HDLBits-Verilog Practice

张开发
2026/4/13 13:14:21 15 分钟阅读

分享文章

HDLBits-Verilog Practice
HDLBits使用步骤为了在时序图中显示信号我们定义了三个Verilog宏probesignal向定时图添加信号。probe_start 在初始块内使用此法开始新的计时图probe_stop在初始方块内使用这个来停止当前的计时图你需要probe_start来开始做计时图。限制每个信号只能添加一次。信号数量最多只能有512个。每个信号最多只能是512位的总线顶级模块必须叫做top_module运行仿真时你通常会有一个可合成的模块被测设备DUT来测试还有一个测试平台负责实例化你的模块并在适当时间驱动其输入。一个基础测试平台使用一些 regs 和初始块来赋值。初始块类似于始终块但它只在模拟开始时执行一次。Verilog 过程块允许在语句中添加延迟。例如x 0;#10;x 1;将x设为0然后等待10个时间单位再将x 1。基础调试可以通过打印信号的数值使用$display、$strobe或$monitor来完成。$display的原理类似于 C语言中的 printf。使用系统任务$finish结束模拟。Simulation下的“Run a Simulation(Icarus Verilog)”module top_module (); reg clk0; always #5 clk ~clk; // Create clock with period10 initial probe_start; // Start the timing diagram probe(clk); // Probe signal clk // A testbench reg in0; initial begin #10 in 1; #10 in 0; #20 in 1; #20 in 0; $display (Hello world! The current time is (%0d ps), $time); #50 $finish; // Quit the simulation end invert inst1 ( .in(in) ); // Sub-modules work too. endmodule module invert(input in, output out); assign out ~in; probe(in); // Sub-modules can also have probe() probe(out); endmoduleprobe是什么这不是 Verilog 标准语法而是仿真工具比如 HDL Designer、Vivado 内部集成工具的自定义宏。作用probe_start开始记录波形probe(信号)把信号加入波形图你可以把它理解为让信号能在波形窗口里看到。点击“Submit(New window)”在新界面中进行仿真将编写好的Testbench代码和RTL代码放到一个文件中Testbench在上面RTL代码在下面这个平台可以将两种文件放在一起示例5分频50%占空比module top_module (); reg clk0; always #5 clk ~clk; // 时钟周期10和你示例完全一样 initial probe_start; // 启动波形探测 probe(clk); // 探测输入时钟 // 5分频需要复位信号 reg rst_n; initial begin rst_n 0; // 初始复位 #20 rst_n 1; // 20个时间单位后释放复位 end // 例化 5分频模块 wire clk_out; div5 u_div5 ( .clk_in(clk), .rst_n(rst_n), .clk_out(clk_out) ); // 仿真结束控制 initial begin #200 $finish; end endmodule // 5分频模块 module div5( input clk_in, input rst_n, output clk_out ); reg [2:0] cnt; reg clk_p; reg clk_n; // 计数器 0~4 循环 always (posedge clk_in or negedge rst_n) begin if(!rst_n) cnt 0; else if(cnt 4) cnt 0; else cnt cnt 1; end // 上升沿生成中间时钟 always (posedge clk_in or negedge rst_n) begin if(!rst_n) clk_p 0; else if(cnt 2 || cnt 4) clk_p ~clk_p; end // 下降沿生成中间时钟 always (negedge clk_in or negedge rst_n) begin if(!rst_n) clk_n 0; else if(cnt 2 || cnt 4) clk_n ~clk_n; end // 输出 50% 占空比 5分频 assign clk_out clk_p | clk_n; // 波形探测 probe(clk_in); probe(rst_n); probe(cnt); probe(clk_p); probe(clk_n); probe(clk_out); endmodule复位阶段0~20ns时间节点0ns ~ 20ns关键信号状态rst_n低电平0异步复位生效cnt保持 0计数器复位clk_p/clk_n/clk_out全部保持低电平0设计逻辑异步复位确保电路上电后从初始状态开始工作避免亚稳态。复位释放与计数启动20ns时间节点20ns关键信号状态rst_n跳变为高电平1复位释放cnt在 clk 上升沿20ns开始递增从 0→1设计逻辑复位释放后计数器在每个输入时钟上升沿正常计数进入 0-4 循环。第一个分频周期20ns ~ 70ns时间节点关键事件信号状态30nscnt2上升沿clk_p翻转0→135nscnt2下降沿clk_n翻转0→140nsclk_out由 clk_pclk_n 生成跳变为高电平0→1clk_out150nscnt4上升沿clk_p翻转1→055nscnt4下降沿clk_n翻转1→060nsclk_out跳变为低电平1→0clk_out070ns第一个 5 分频周期结束clk_out周期 50ns5×10ns 输入周期占空比验证核心指标clk_out高电平时间40ns ~ 65ns持续 25nsclk_out低电平时间65ns ~ 90ns持续 25ns结论完美 50% 占空比符合奇数分频双边沿合成的设计目标后续周期70ns 之后计数器持续0→1→2→3→4→0循环clk_p/clk_n按相同逻辑翻转clk_out以 50ns 为周期稳定输出无毛刺、无相位偏移分频比稳定为 5:1双边沿合成技术通过上升沿触发的clk_p和下降沿触发的clk_n相位相差半个输入时钟周期经或运算后生成 50% 占空比的奇数分频时钟。异步复位低电平复位确保电路上电后状态可控复位释放后立即进入正常工作状态。计数器逻辑3 位计数器 0-4 循环在cnt2和cnt4时翻转中间时钟是实现 5 分频的核心计数逻辑。

更多文章