modelsim中用非阻塞赋值仿真遇到的问题
来源:互联网 发布:淘宝商品链接怎么复制 编辑:程序博客网 时间:2024/04/30 00:58
这是对rom初始化并读取的源码
module rom_nxm(rom_data,rom_addr,clk,rd,load); parameter M=8,N=4; input clk,rd; input load; input [N-1:0] rom_addr; output reg [M-1:0] rom_data; reg[M-1:0]memory[0:2**N-1]; always@(posedge load) begin:init integer i; for(i=0;i<(2**N);i=i+1) memory[i]=i+1;endalways@(posedge clk)endalways@(posedge clk)begin:readif(rd)rom_data=memory[rom_addr];endendmoduletestbench为
`timescale 1ns/100ps module rom_nxm_tb ; parameter M = 8 ;parameter N = 4 ; reg load ;
reg [N-1:0] rom_addr ; reg rd ; reg clk ; wire [M-1:0] rom_data ; rom_nxm #( M , N ) DUT ( .load (load ) , .rom_addr (rom_addr ) , .rd (rd ) , .clk (clk ) , .rom_data (rom_data ) ); initial begin clk=0; load=0; rd=0; end initial begin #10 load=1; #10 rd=1; rom_addr=0; end always #10 clk=~clk; always@(posedge clk) begin $display("addr:%d,data:%d",rom_addr,rom_data); if(rom_addr==15) rom_addr=0;//rom_addr<=0 else rom_addr= rom_addr+1;//rom_addr<= rom_addr+1 end initial #35 $strobe($time,"addr:%d,data:%d",rom_addr,rom_data); endmodule
阻塞赋值的仿真结果:
addr: x,data: x
# addr: 0,data: x
# 35addr: 1,data: 2
# addr: 1,data: 2
# addr: 2,data: 3
# addr: 3,data: 4
非阻塞赋值的结果:
addr: x,data: x
# addr: 0,data: x
# 35addr: 1,data: 1
# addr: 1,data: 1
# addr: 2,data: 2
# addr: 3,data: 3
modelsim的testbench中对always@(posedge)模块的阻塞赋值是在posedge clk之前delta时间进行赋值,而非阻塞赋值是在posedge clk之后delta时间进行赋值,且一般寄存器的采样在时钟前delta时间,而赋值在时钟后delta时间。
若为阻塞赋值,在第二个上升沿的时侯,addr在posedge clk前的delta时间进行赋值变为0001,然后memory采样的是posedge clk之前delta时间的值即0001(虽然显示为0000,),则addr显示为0001的时候,memory显示的是memory【0001】。这时addr与memory对应。
但若用非阻塞赋值的话,在第二个上升沿的时侯,addr的显示与阻塞赋值是一样的,但差别是非阻塞赋值是在posedge clk之后delta时间进行赋值,则memory采样仍是在clk之前,就变成memory【0000】。这时,从图上看,仿佛addr与memory不对应。
但是在testbench中将阻塞赋值用非阻塞赋值替代是有好处的,尤其是你的verilig源文件中有非阻塞赋值(存在寄存器或触发器)的情况,这样才能在时序图中体现非阻塞赋值的功能(因非阻塞的本质是读取触发前的状态,而testbench中的非阻塞赋值起到了延时的作用,不要死板的认为是在下一个时钟触发时才赋值),但你要将testbench中的非阻塞赋值当做阻塞赋值对待,深刻理解modelsim是仿真,可参考:
http://xilinx.eetop.cn/viewthread-282059
有高手说:
写tb时注意信号的生成不要在pos clk的同时用阻塞赋值(当你的模块是pos clk时)。这就是多事件同时发生:如果都是非阻塞赋值就不存在问题。但阻塞赋值时,不同仿真器的处理顺序不一样,会导致结果差异。可用3种方式:1:neg clk 和阻塞赋值;2:pos clk和非阻塞赋值;3:pos clk +单位延时 + 阻塞赋值。
若用testbench中用阻塞赋值,
加载测试向量时,避免在时钟的上下沿变化
为了模拟真实器件的行为,加载测试向量时,避免在时钟的上下沿变化,而是在时钟的上升沿延时一个时间单位后,加载的测试向量发生变化。如:
assign #5 c="a"^b
……
@(posedge clk) #(0.1*`cycle) A=1;
- modelsim中用非阻塞赋值仿真遇到的问题
- Verilog 非阻塞赋值的仿真/综合问题
- Verilog 非阻塞赋值的仿真/综合问题
- Verilog非阻塞赋值的仿真/综合问题
- modelsim 仿真中遇到的问题
- 阻塞赋值和非阻塞赋值深度解析——仿真事件的调度
- 关于modelsim仿真出现红线的问题
- ISE与modelsim联合仿真的问题
- modelsim仿真问题
- 有关verilog中阻塞赋值和非阻塞赋值的问题
- verilog中阻塞赋值和非阻塞赋值的区别
- 关于阻塞赋值和非阻塞赋值的…
- 阻塞赋值与非阻塞赋值的再分析
- 关于四位计数器的设计,阻塞式与非阻塞式赋值引发的问题
- python使用select监听非阻塞socket遇到的问题
- modelsim 仿真中的问题集
- Modelsim仿真包含quartus ROM的工程文件的问题
- Modelsim与Quartus ii联合仿真的一些问题
- Android学习之AndroidManifest.xml文件解析
- Java字节流与字符流的区别
- Android Vibrator的使用
- JAVA读取外部资源的方法
- lines
- modelsim中用非阻塞赋值仿真遇到的问题
- 用AutoCompleteTextView实现历史记录提示 .
- What is the Difference Between Proxy Types?
- android bug list
- “创意不是想出来的”
- C++第1周项目3——结构体数组处理学生成绩
- vc 调试技巧
- 怎样用文件或命令行 添加\删除注册表项
- 算法方面的经典书籍