仿真时寄存器究竟在时钟沿的什么时刻赋值?
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
参考资料:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律