MCDF项目

1.设计

多通道数据整形器 (MCDF,multi-channel data formatter),它可以将上行(uplink)多个通道数据经过内部的 FIFO,最终以数据包(data packet)的形式送出。

版本迭代

1.1SV/UVM版

028-硬件设计功能描述1

1.1.1slave

valid是由外部driver拉高发送给slave的信号,表示输入data准备完成
ready是由内部slave发送给外部driver的信号,表示可以写入data

1.1.2formater

req是formater发送给外部接收端的发送请求
grant是由外部接收端拉高发送给formater的信号,表示外部允许接收数据了
其他信号是由formater发送给外部的信号

1.1.3register

寄存器决定了是读(从formater端)还是写(从slave端)
决定了三个slave中的哪一个


1.2APB版

43【UVM项目实战1】MCDF更新_AMBA接口_验证环境更新
MCDF设计更新

1.2.1slave

1.2.2formater

1.2.3register

3.验证

3.1SV-MCDT

MCDF实验_lab0(0)
MCDF实验——Lab0


由tb模块设置发送的channel的id和data给mcdt dut
mcdtdut在tb中连接了mcdt_data_o
在dut内部连接了arbiter的arb_data_o 在arbiter内部连接了arb_data_r
由一个case决定arb_data_r是哪个channel的data


个人存在的疑问? 为什么ch的fifo余量总是在20和19之间,在未读出数据且写入两个数据的情况下余量仍是19,不会跳转到18? 为什么mcdt的out data总是两拍有效,在channel fifo中读出2个数

MCDF实验_lab1(1)
MCDF实验——Lab1


每一个channel发送更多的(100个)数据(tb模块)

function void set_name(string s);

task chnl_write(input logic[31:0] data); 
chnl_idle(); 
endtask

task chnl_idle();

  logic [31:0] chnl0_arr[];		//创建32位的动态数组
  logic [31:0] chnl1_arr[];
  logic [31:0]chnl2_arr[]; 
  
  initial begin   
  chnl0_arr = new[100];  	 	//每个数组例化100个
  chnl1_arr = new[100];  
  chnl2_arr = new[100];
  foreach(chnl0_arr[i]) 
  	begin
    chnl0_arr[i] = 'h00C0_00000 + i; 	//为100个数赋值
    chnl1_arr[i] = 'h00C1_00000 + i; 	
    chnl2_arr[i] = 'h00C2_00000 + i;   
    end 
  end 
  
initial begin   
chnl0_init.set_name("chnl0_init");  
chnl1_init.set_name("chnl0_init");  
chnl2_init.set_name("chnl0_init");   
foreach(chnl0_arr[i]) chnl0_init.chnl_write(chnl0_arr[i]);  //每一个数重复一次chnl_write操作
foreach(chnl1_arr[i]) chnl1_init.chnl_write(chnl1_arr[i]);
foreach(chnl2_arr[i])chnl2_init.chnl_write(chnl2_arr[i]); 
end 

三个channel同时发送数据(tb模块)

//用fork join实现
fork
foreach(chnl0_arr[i]) chnl0_init.chnl_write(chnl0_arr[i]); 
foreach(chnl1_arr[i])chnl1_init.chnl_write(chnl1_arr[i]);
foreach(chnl2_arr[i])chnl2_init.chnl_write(chnl2_arr[i]); 
join

波形图

mcdt的out data变成了三个channel各读一个的顺序

MCDF实验_lab2(2)
MCDF实验——Lab2


三个test 分别为chnl_basic_test,chnl_burst_test,chnl_fifo_full_test
测试了多个数据传输,改变idle_cycles,以及fifo余量为0的时候结束test

MCDF实验_lab3(3)
MCDF实验——Lab3


数据类chnl_trans不再只局限于包含一个数据,而是多个数据
之前 class chnl_trans; int data;
现在

class chnl_trans; 
rand bit[31:0] data[];	//动态数组
rand int ch_id; 
rand int pkt_id;	 //第几个数据包,即第几个trans
rand int data_nidles; 	//data之间空闲间隔周期
rand int pkt_nidles; 	//数据包之间空闲间隔周期

命令行指令vsim -novopt -solvefaildebug -sv_seed 0 +TESTNAME=chnl_basic_test work.tb3_ref


不同的test需要对chnl_generator的随机变量做出不同的控制,继而进一步控制其内部随机的chnl_trans对象。也就是说,随机化也是可以分层次的,例如在test层可以随机化generator层,而依靠generator被随机化的成员变量,再来利用它们进一步随机化generator中的chnl_trans对象

chnl_basic_test 对chnl_generator的随机变量做出不同的控制

assert(gen[0].randomize() with {ntrans==100; data_nidles==0; pkt_nidles==1; data_size==8;})
assert(gen[1].randomize() with {ntrans==50; data_nidles inside {[1:2]}; pkt_nidles inside {[3:5]}; data_size==16;})
assert(gen[2].randomize() with {ntrans==80; data_nidles inside {[0:1]}; pkt_nidles inside {[1:2]}; data_size==32;})

gen 随机化结果

在gen调用send_trans,进一步控制其内部随机的chnl_trans对象

task run();
repeat(ntrans) send_trans();
endtask

chnl_trans随机化结果

ntrans=100+50+80=230
req+rsp=230*2=460=obj_id

3.2SV-MCDF

MCDF实验_lab4(4)
MCDF实验——Lab4


命令行指令vsim -novopt -classdebug -solvefaildebug -sv_seed 0 +TESTNAME=mcdf_data_consistence_basic_test -l mcdf_data_consistence_basic_test.log work.tb


chnl_pkg和reg_pkg和lab3一样,由test随机gen,gen随机trans
reg_pkg

class reg_trans;    
	rand bit[7:0] addr;    
	rand bit[1:0] cmd;   
	rand bit[31:0] data;    
	 //cmd_data_in[31:6保留位,5:3数据包长度,2:1优先级,0通道使能信号]
	 //5:3数据包长度 → 0对应4,1对应8,2对应16,3对应32,其他都是32
	 //cmd_data_out[31:8保留位,7:0FIFO的可写余量]
	bit rsp;

constraint cstr {
     soft cmd inside {`WRITE, `READ, `IDLE};
     //决定状态是读/写/idle
     soft addr inside {`SLV0_RW_ADDR, `SLV1_RW_ADDR, `SLV2_RW_ADDR, `SLV0_R_ADDR,`SLV1_R_ADDR, `SLV2_R_ADDR};
     //决定是6个寄存器里哪个地址
     // 0x00,04,08;  0x10,14,18
     addr[7:4]==0 && cmd==`WRITE -> soft data[31:6]==0;
     //如果地址是 0x0? 的同时为写状态,把保留位设置为1
     soft addr[7:5]==0;
     addr[4]==1 -> soft cmd == `READ;    
     //如果地址是0x1?,为只读寄存器,约束cmd的状态只能为读
     };

我的理解是一开始会给3个读写寄存器通过data分别配置
比如channel1经过fmt的数据包长度是8,channel2则是16,channel3是32
波形图
之后chnl_pkg生成数据,和lab3一样
按照reg的配置fmt输出
波形图

MCDF实验——Lab5
MCDF实验_lab4(4)


命令行指令
1.
仿真
vsim -novopt -classdebug -solvefaildebug -sv_seed 0 +TESTNAME=mcdf_data_consistence_basic_test -l mcdf_data_consistence_basic_test.log work.tb
保存波形
log -r /*
运行
run -all
2.
收集覆盖率
vsim -i -classdebug -solvefaildebug -coverage -coverstore H:\mcdf\SV-MCDF\lab5\cover -sv_seed random +TESTNAME=mcdf_data_consistence_basic_test -l mcdf_data_consistence_basic_tast.log work.tb
运行
run -all
直接查看覆盖率

代码覆盖率

功能覆盖率

退出仿真生成.data文件
quit -sim

合并覆盖率
把所有test跑一次后merge,覆盖率提升
vcover merge -out merged_coverage.ucdb H:\mcdf\SV-MCDF\lab5\cover



更新了mcdf_coverage,6个covergroup和测试功能点一一对应

遇到编译问题
Modelsim找不到头文件 Cannot find `include file “xxxxxx” in directories:

3.3UVM-MCDF

UVM入门实验0
UVM入门实验1
一、工厂的注册、创建和覆盖机制
二、域的自动化和uvm_object的常用方法
三、phase机制
四、config机制
五、消息管理

UVM入门实验2


UVM验证环境测试的开始、环境构建的过程、连接以及结束的控制。

UVM入门实验3


TLM通信

UVM仿真控制

UVM入门实验4


之前的test
mcdf_base_test的run_phase运行了do_reg,do_formatter,do_data
do_reg,do_formatter,do_data为空定义

task run_phase(uvm_phase phase);
 		this.do_reg();
		this.do_formatter(); 
		this.do_data(); 
endtask 

还定义了idle_reg,write_reg和read_reg

在子类test 即mcdf_data_consistence_basic_test中在do_reg配置了3个channel输出的格式
调用的是basetest中write_reg、read_reg task

do_formatter、do_data同样配置


现在的test
mcdf_base_test运行了run_top_virtual_sequence
run_top_virtual_sequence为空定义

task run_phase(uvm_phase phase);
      this.run_top_virtual_sequence();
endtask 

在子类test即mcdf_data_consistence_basic_test中重新定义run_top_virtual_sequence
包括了例化vseq(mcdf_data_consistence_basic_virtual_sequence),并且挂载到vsqr

(1)其中vsqr

例化了所有sqr
(2)其中mcdf_base_virtual_sequence

(2.1)例化了所有seq,包括了reg、channel、formater的seq
其中idle_reg_sequence、write_reg_sequence、read_reg_sequence在reg_pkg中定义

(2.2)task body中运行了do_reg,do_formatter,do_data
do_reg,do_formatter,do_data为空定义
在子类vseq即mcdf_data_consistence_basic_virtual_sequence中重新定义do_reg,do_formatter,do_data
在do_reg配置了3个channel输出的格式,调用的是reg_pkg中的idle_reg_sequence、write_reg_sequence、read_reg_sequence

do_formatter、do_data同样配置

UVM入门实验5


寄存器模型mcdf_rgm_pkg

之前是reg_pkg的agent里的seq随机化产生cmd、addr和data发送给dut的reg
现在新加入了寄存器模型,由寄存器模型产生数据(cmd、addr和data)发送给reg_pkg的sequencer,但是需要adapter去转换uvm_reg_bus_op和reg_trans

rgm、adapter和predictor在mcdf_env里例化,显式调用build

adapter在上图看似例化在map中,实际上只是在env中的connect phase中map连接了adapter的句柄,又连接reg agent的sequencer

涉及到前门访问和后门访问,期待值、镜像值和硬件实际值
predictor是显式预测,连接到adapter和map
最后使用的是内建build in sequence

在sequence里的do_reg里配置

在vsqr和vseq里例化rgm
把其他测试也修改为寄存器模型访问

3.4APB-MCDF

UVM验证环境更新策略


register master agent由于总线更新为APB,需要开发完整的APB master agent。

APB协议UVM验证环境的搭建


  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值