将wavedrom图转换为excel
原理上是先转换为json,然后写入到excel中。
import csv
import json
import pandas as pd
content = []
with open("source.txt") as f:
c = f.read()
c = c.replace("reg", "\"reg\"").replace("bits", "\"bits\"").replace("name", "\"name\"").replace(
"'", "\"").replace("config", "\"config\"").replace("lanes", "\"lanes\"").replace(
"hspace", "\"hspace\"").replace("fontsize", "\"fontsize\"").replace("attr","\"attr\"")
data = json.loads(c)["reg"]
# 创建DataFrame
df = pd.DataFrame(data)
new_df = pd.DataFrame()
for index, row in df.iterrows():
if row['bits'] > 1:
# 根据bits的值复制行
for _ in range(row['bits'] - 1):
new_df = pd.concat([new_df, pd.DataFrame([pd.Series()])], ignore_index=True)
new_df = pd.concat([new_df, pd.DataFrame([row])], ignore_index=True)
else:
new_df = pd.concat([new_df, pd.DataFrame([row])], ignore_index=True)
# 重置索引
new_df.reset_index(drop=True, inplace=True)
df = new_df.iloc[::-1, :]
df = df.T
df.iloc[[0, 1]] = df.iloc[[1, 0]]
# 使用pandas的ExcelWriter和openpyxl引擎
with pd.ExcelWriter("output.xlsx", engine='openpyxl') as writer:
df.to_excel(writer, index=False)
# 获取workbook和worksheet对象
workbook = writer.book
worksheet = writer.sheets['Sheet1']
# 根据bits的值设置跨列
row_num = 2 # 从Excel的第二行开始(第一行是标题)
bits_all = 0
for item in data[::-1]:
bits = item['bits']
# 如果bits大于1,则合并单元格
bits_offset = bits_all % 64
if bits > 1:
worksheet.merge_cells(
start_row=row_num, start_column=1 + bits_offset,
end_row=row_num, end_column=bits + bits_offset)
bits_all += bits
if bits_all > 64:
row_num += 1
UVM使用双顶层环境
前述
uvm组件是动态变化的,
在build phase之前(initial 部分,且存在于run_test之前的initial)调用的uvm_top.print_topology()函数,则显示的内容为空。
在build phase之前(initial 部分,且存在于run_test之后的initial)调用的uvm_top.print_topology()函数,则显示的内容只有uvm_test_top。
在elaboration phase,uvm_top.print_topology()函数,则显示的内容是完整的topo。
原理
双顶层或者是说多顶层,本质是将uvm_top(uvm_root的唯一实例指针)下挂载额外的一个组件。第一个组件是通过+UVM_TESTNAME或者run_test的时候指定参数进行的挂载,而额外的一个组件是通过create_component_by_name手动挂载。
因此可以实现多个用例同时运行,由uvm_top统一调度。
实现
uvm_coreservice_t coreservice = uvm_coreservice_t::get();
uvm_factory fact = coreservice.get_factory();
fact.create_component_by_name(testname,"","other_test_top",uvm_top);
参考
实现机制:
http://www.lujun.org.cn/?p=4271
https://blog.csdn.net/weiqi7777/article/details/88219191
通过uvm_top.find获取某个组件:
https://www.cnblogs.com/csjt/p/15560173.html
https://zhuanlan.zhihu.com/p/659753287
慎用casex和casez使用case inside
ase、casex、casez都是可综合的,不过在case中综合电路无法解析x/z/?,会将其认为不关心
https://www.wenhui.space/docs/08-ic-design/rtl-coding/about-verilog-case/
casez treats ‘z’ as dont care
casex treats ‘z’ & ‘x’ as dont care
以case x为例,不只是 case_item 的“z”和 “x”, case_expression 中的“z”和“x”也会被看作“don't care”。因此容易出现混淆。
https://zhuanlan.zhihu.com/p/460286149
假设仿真时输入的 irq 为 3'b00x,casex 将最低位的 x 看作通配符,所以会匹配 case_item 3'b??1,所以 int0=1。
always @(irq) begin
{int2, int1, int0} = 3'b000;
casex (irq)
3'b1?? : int2 = 1'b1;
3'b?1? : int1 = 1'b1;
3'b??1 : int0 = 1'b1;
default: {int2, int1, int0} = 3'b000;
endcase
end
case...inside 不会把 case_expression 中的“z”和“x”看作“don't care”,因而进一步使得仿真结果和综合后的结果可以匹配上。在此例中,假如 irq 为 3'b00x,那么 case...inside 便会匹配 default 选项。
always @(irq) begin
{int2, int1, int0} = 3'b000;
case (irq) inside
3'b1?? : int2 = 1'b1;
3'b?1? : int1 = 1'b1;
3'b??1 : int0 = 1'b1;
default: {int2, int1, int0} = 3'b000;
endcase
end
shell命令行自动补全
https://blog.csdn.net/iEearth/article/details/52703598
inux.51yip.com/search/compgen
compgen
最常用的选项是-W,通过-W参数指定空格分隔的单词列表。
compgen -W 'hi hello how world' h
hi
hello
how
function _test()
> {
> echo "aabc"
> }
$ complete -F _test test
再输入以下命令按补全:
test x<Tab>
得到
test xaabc
function autotab() {
echo "function autotab called $@"
}
autotab_list=("aa" "bb" "cc" "dd" "123")
function _autotab() {
local cur
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=( $(compgen -W "${autotab_list[*]}" -- ${cur}) )
return 0
}
complete -F _autotab autotab
执行命令autotab时,如果命令未输完,按下Tab键就会补全这个命令,而且还会显示或补全一些参数
操作系统的分段机制
linux内存的管理有:段式存储、页式存储、段页式存储。
ASID的功能
ASID的核心作用是索引于TLB,是TLB存在以后出现的概念。ASID在使用层面上是和PPN相匹配,不同进程的某个进程上,ASID相同,PPN多个。ASID用于在TLB层面区分不同的进程,以在相同的VA进行缓存查找翻译的时候使用。
当两个进程带有ASID不同但是基地址PPN相同,使用相同VA进行访问,最终两个进程通过该PPN获取到的是相同的PA。
当两个进程带有ASID相同但是基地址PPN不同,使用相同VA进行访问,最终两个进程通过不同的PPN获取到的是不同的PA。
当两个进程带有ASID不同且基地址PPN不同,使用相同VA进行访问,最终两个进程通过不同的PPN获取到的是不同的PA。这个情况需要ASID生效才可以。如果ASID是无效,那么TLB在存储VA和PA的映射关系上,只能存储一组,将导致第一个进程拿到PPN后,建立的VA和PA的映射关系被第二个进程使用,从而导致错误。
当进程P1执行VA1映射得到PA1,进程P2执行VA2映射得到PA2,再次回到进程P1,cache命中情况下VA1仍然映射得到PA1。
ASID本质用于TLB的误命中,而PPN直接作为Tag索引则位宽过大,引入ASID和PPN对应。
查看CPU信息
/proc/cpuinfo里显示的cpu_cores是每个插槽的实际物理cpu个数。
或者使用lscpu命令查看
https://www.cnblogs.com/badboy200800/p/10606405.html
Architecture: x86_64 #架构,这里指64位处理器
CPU op-mode(s): 32-bit, 64-bit #运行方式
Byte Order: Little Endian #字节顺序,这里指小端法
CPU(s): 48 #服务器上CPU的逻辑核总数
On-line CPU(s) list: 0-47 #服务器上在线的CPU逻辑核总数(有时因为CPU过热可能会暂停某些CPU)
Thread(s) per core: 2 #每个物理核超线程数(大于1则为超线程)
Core(s) per socket: 6 #每个插槽的物理核数(每颗CPU物理核数)
Socket(s): 4 #服务器上CPU插槽数 (一般为CPU总数)
NUMA node(s): 8 #非统一内存访问节点
Vendor ID: AuthenticAMD #cpu厂商ID
CPU family: 21 #CPU系列
Model: 1 #CPU型号编号
Model name: AMD Opteron 6234 @ 2.40GHz #CPU型号名称
Stepping: 2 #步进
CPU MHz: 2400.66 #cpu主频
BogoMIPS: 4799.42
Hypervisor vendor: AMD-V #虚拟化架构
Virtualization type: full #cpu支持的虚拟化技术
L1d cache: 16K #一级缓存,dcahce用于缓存数据
L1i cache: 64K #一级缓存,icahce用于缓存指令
L2 cache: 2408K #二级缓存
L3 cache: 6144K #三级缓存,缓存速度上 L1 > L2 > L3 > DDR(内存,理论速度几十g每秒)
NUMA node0 CPU(s): 0,4,8,12,16,20 #逻辑CPU和NUMA节点映射
NUMA node1 CPU(s): 24,18,32,36,40,44
NUMA node2 CPU(s): 1,5,9,13,17,21
NUMA node3 CPU(s): 25,29,33,37,41,45
NUMA node4 CPU(s): 2,6,10,14,18,22
NUMA node5 CPU(s): 26,30,34,38,42,46
NUMA node6 CPU(s): 27,31,35,39,43,47
NUMA node7 CPU(s): 3,7,11,15,19,23
标签:case,补全,df,ASID,uvm,bits,CPU
From: https://www.cnblogs.com/bai2022/p/18100710