中端知识和工具+字符设备和块设备+LMA和VMA+gdb查看系统调用+vim查看指定文件链接的autocmd+linux编辑二进制文件+特殊覆盖率定义

中端知识和工具

https://www.cnblogs.com/yjw951012/p/12865036.html

抖动(Jitter)和偏移(skew)

信号周期的长度总会有一定变化,从而导致下一个沿的到来时间不确定。这种不确定就是抖动(jitter)。
因时钟线长度不同或负载不同,导致时钟到达相邻单元的时间不同,这个时间上的偏差就叫时钟偏移SKEW。

setup和hold的计算

建立时间(Setup time):触发器时钟上升沿到来前数据保持稳定的时间。
保持时间(Hold time):触发器时钟上升沿到来后数保持据稳定的时间。
image
△T=Tskew
T1=REG1检测到时钟后内部延时+组合逻辑延时最后到达REG2的时间
Tcycle=CLK的周期
Ts=数据在CLK2上升沿到达前维持的时间
Ts = Tcycle + Tskew-T1
Th=数据在CLK上升沿到达后维持的时间
Th = T1 – Tskew
如果Ts>setup time(触发器),Th>hold time(触发器)则数据能正常写入,由这个条件可以看出,Tskew与T1起着关键作用,而正之前所说如果使用全局时钟则Tskew会很小,可以忽略不计。
(引用链接的其它地方,存在矛盾,不能确定正确性,不再计算)

时间裕量Slack

关键路径(critical path):从输入到输出中延时最大的那条路径。
到达时间(arrival time):信号从参考的时间起到达某特点位置的时间。
需求时间(required time):信号到达的最晚的时间。

用需求时间减去到达时间得到的结果就是时间裕量(slack =required time- arrival time)。
如果是正数则说明路径延时满足需求,如果是负数则说明延时不满足。其中比较重要的时Hold Time Slack。

create_generated_clock

https://blog.csdn.net/weixin_37584728/article/details/116641215
在数字 IC 设计中,芯片中各个模块的工作频率可能都不太一样。因此有了时钟产生电路(clock generation)。这个电路含有时钟切换电路,时钟分频,倍频电路以及 clock reset 电路。通常我们通过 create_generated_clock 来定义时钟分频和倍频电路后的时钟。

create_generated_clock 是用来说明 generated clock 与 source clock 的相位(边沿)关系。同时根据 source clock 找到 master clock 以及 source clock 和 master clock 的关系, 最终会确定 generated clock 和 master clock 的相位(边沿)关系。

create_clock -period 10 CLK

create_generated_clock -name CLKdiv2 \
-divide_by 2 \
-source CLK \
[get_pins Udiv/Q]

set_clock_groups

Set Clock Groups (set_clock_groups)约束使您能够指定设计中的哪些时钟是不相关的。

字符设备和块设备

字符设备指那些必须以串行顺序依次进行访问的设备,如触摸屏、磁带驱动器、鼠标等。块设备可以按任意顺序进行访问,以块为单位进行操作,如硬盘、eMMC等。
Flash的编程原理都是只能将1写为0,而不能将0写为1。因此在Flash编程之前,必须将对应的块擦
除,而擦除的过程就是把所有位都写为1的过程,块内的所有字节变为0xFF。

LMA和VMA

https://blog.csdn.net/shenjin_s/article/details/88893762
LMA: 加载地址,如加载到RAM中等,在嵌入式中,有可能是在ROM中(这时LMA!=VMA)
VMA: 虚拟地址,就是程序运行时的地址,一般就是内存地址,如要把ROM中的数据加载到RAM中运行。
链接脚本默认是VMA地址,LMA地址通过LOAD ADDR指令中写死指定。

个人认为如果是操作系统已经启动的情况,LMA和VMA应该是操作系统管理copy过程,所反汇编出的elf文件具有lma和vma字段。如果是嵌入式那种,应该是裸核固件自己定死LMA和VMA的地址(只是写在link.ld文件,还要和汇编开头的固件配合),自己做copy。
https://blog.csdn.net/suz_cheney/article/details/24586745

典型的bootloader(加载器)搬运代码如链接所示:
https://www.cnblogs.com/ironx/p/4963018.html

点击查看代码
.extern    _fbss
  .extern    _ebss
  .extern     main
  .section ".boot","ax"
  .set noreorder
  .set noat
  .globl  _start
  .ent    _start

#define DRAM_BASE    0xa0000000
#define DRAM_SIZE    0x00001800

#boot start
_start:
    li    s0, 0xffff
    li    s1, 0xffff
    li    v0, 0xffff
    li    v1, 0xffff
    li    a0, 0xffff
        li      a1, 0xffff
    li    a2, 0xffff
    li    a3, 0xffff
        nop
#copy .data to dram
_copy_data:
    li    s0, _fdata
    li    s1, _edata
    li    v0, DRAM_BASE
1:    lw      v1, 0(s0)
    sw    v1, 0(v0)
    addiu    s0, 4
    addiu    v0, 4
    blt    s0, s1, 1b
#clear bss
clear_bss:
    li    s0, _fbss
    li    s1, _ebss
    li    v0, 0
1:    sw    v0, 0(s0)
    addiu   s0, 4
    blt    s0, s1, 1b
    nop
clr_num:
           li      v0, 0xa0001800
           move     sp, v0
    jal    main
    nop
loop:
    la    v0, loop
    j       v0
    nop
         .set    reorder
          .end    _start

gdb查看系统调用

https://www.kancloud.cn/wizardforcel/gdb-tips-100/146744
装载完毕后,马上使用catch syscall,重新跑一遍,随后在使用bt之前查看。
具体执行步骤如下:

  1. 编写c程序
  2. 编译c程序,带着-g选项。
  3. gdb装载程序
  4. 执行catch syscall
  5. 执行r
  6. 执行where
  7. 多次执行s
  8. 查看调用栈。

vim查看指定文件链接的autocmd

https://yyq123.github.io/learn-vim/learn-vi-49-01-autocmd.html

:autocmd filetypedetect * *.htm

linux编辑二进制文件

https://zhuanlan.zhihu.com/p/510387133

  1. xxd bin bin.dump 将file转换为可编辑格式,并输出到文件file.dump中。
  2. 使用编辑器编辑文件。
  3. xxd -r bin.dump > bin 修改即成功。

特殊覆盖率定义

大部分定义可以通过新建变量、函数的处理方式,实现覆盖率的各种自定义

onehot coverage

想要覆盖data域段里所有的onehot字段。
方法1:建立数组,然后创建bins。encoding本身的数字作为bins的值。

logic[WIDTH-1:0] encoding[WIDTH] ;
logic[WIDTH-1:0] data;
covergroup onehot_cg(int width);
	onehot_cp: covergroup data{
    //这里onehot的每个子bins中都是有效的场景<6'b1><6'b10><6'b100> ... <6'b10_0000>
		bins onehot[width] = encoding;  
	} 
endgroup
//encoding构造onehot数组 //需要在covergroup new之前定义好数组场景
onhot_cg = new(WIDTH);
foreach(encoding[i]) encoding[i] = 1<<i; 

power-of-two coverage

一个位宽为WIDTH的数,所有power-of-two状态,例如:4‘bit的数: 只关心:4’b0000, 4’b001?, 4’b01??, 4’b1???,其中?表示0/1/x/z任意值。
使用iff的方法,限定覆盖率和覆盖点:

bit[WIDTH-1:0] data;
covergroup power_of_two_cg(int width) with function sample(
  int idx , bit[WIDTH-1:0] value);
	//关键是mask如何计算
	coverpoint idx iff(
    value[idx]==1 &&
    ((value & ({WIDTH{1'b1}} << idx+1 )) == {WIDTH{1'b0}})
  ){ 
		bins all[] = {[0:WIDTH-1]};
	}
endgroup

duty cycle coverage

以1的个数作为覆盖率点位

bit[WIDTH-1:0] data;
covergroup duty_cycle_cg(int width) with function sample(int num);
	coverpoint num{
		bins all[] = {[0:width]};
	}
endgroup
duty_cycle_cg = new(WIDTH);
duty_ctcle_cg.sample($countones(data));

covergroup在class中不能定义成数组。

posted @ 2024-02-17 16:08  大浪淘沙、  阅读(14)  评论(0编辑  收藏  举报