仿真时寄存器究竟在时钟沿的什么时刻赋值?
1 现象:
仿真在140ns位置处,时钟clk上升沿一来,data_in和data_in_reg同步变化? 但是,data_in_reg为寄存器,它与数据源data_in同时变化,这与寄存器赋值会有一拍延时相矛盾。例如:cnt与data_out两个信号,data_out比cnt延时一拍。
2 原因
由于data_in不是由寄存器驱动的,而是在testbench中直接赋值,modelsim在分析时,认为此时data_in的值已经更新为1,故将data_in直接赋值给data_in_reg,在理想仿真情况下,寄存器的输入与输出没有延时,data_in_reg更新为1。
3 解决:
(1)在testbench中错开时钟沿赋值;
(2)在RTL中加入#1延迟;
4 相关程序
(1)设计程序
1 module register_test( 2 input wire clk, 3 input wire rst_n, 4 input wire [7:0] data_in, 5 output reg [7:0] data_in_reg, 6 output reg [7:0] data_out 7 ); 8 9 reg [7:0] cnt; 10 11 always@(posedge clk or negedge rst_n)begin 12 if(!rst_n) 13 data_in_reg <= 8'd0; 14 else 15 data_in_reg <= data_in; 16 end 17 18 always@(posedge clk or negedge rst_n)begin 19 if(!rst_n) 20 cnt <= 8'd0; 21 else 22 cnt <= cnt + 1'b1; 23 end 24 25 always@(posedge clk or negedge rst_n)begin 26 if(!rst_n) 27 data_out <= 8'd0; 28 else 29 data_out <= cnt; 30 end 31 32 endmodule
(2)仿真程序
1 `timescale 1ns/1ns 2 3 module register_test_tb(); 4 5 reg clk; 6 reg rst_n; 7 reg [7:0] data_in; 8 wire [7:0] data_in_reg; 9 wire [7:0] data_out; 10 11 integer i; 12 13 register_test register_test_inst( 14 .clk (clk), 15 .rst_n (rst_n), 16 .data_in (data_in ), 17 .data_in_reg (data_in_reg), 18 .data_out (data_out) 19 ); 20 21 initial clk = 1; 22 always #10 clk = ~clk; 23 24 initial begin 25 rst_n = 0; data_in = 0; 26 #100; rst_n = 1; 27 #20; 28 for(i=0;i<15;i=i+1)begin 29 data_in = i; 30 #20; 31 end 32 #20; 33 $stop; 34 end 35 36 endmodule
参考资料: