如何将SystemVerilog中的$realtime函数转换为Verilog实现?
将SystemVerilog的realtime/$realtime转换为可综合Verilog(FPGA实现)
核心问题说明
$realtime是仿真专用函数,无法被FPGA综合工具识别。要实现原代码的脉冲宽度测量功能,必须用系统时钟驱动的自由运行计数器替代仿真时间戳,通过计数时钟周期来实现时间测量,同时将异步电平敏感逻辑改为同步边沿检测(FPGA设计推荐同步电路)。
改写后的可综合Verilog代码
// 适配FPGA的脉冲宽度测量模块,需根据实际硬件调整时钟、复位信号 module pulse_width_measurer( input clk, input rst_n, // 低电平有效复位 input PAD, input filt_in_h, // 对应原代码的第二个输入信号 output reg [31:0] pad_pulse_width, output reg [31:0] filt_in_h_pulse_width ); // 自由运行计数器:替代$realtime的时间戳,单位为时钟周期 reg [31:0] time_counter; // 信号打拍:用于同步边沿检测 reg pad_prev; reg filt_in_h_prev; // 时间戳寄存器:替换原realtime类型变量 reg [31:0] t_pad_current; reg [31:0] t_pad_prev; reg [31:0] t_filt_current; reg [31:0] t_filt_prev; // 1. 全局时间计数器:每个时钟周期自增 always @(posedge clk or negedge rst_n) begin if(!rst_n) begin time_counter <= 32'd0; end else begin time_counter <= time_counter + 32'd1; end end // 2. PAD信号的脉冲宽度测量逻辑 always @(posedge clk or negedge rst_n) begin if(!rst_n) begin pad_prev <= 1'b0; t_pad_prev <= 32'd0; t_pad_current <= 32'd0; pad_pulse_width <= 32'd0; end else begin pad_prev <= PAD; // 检测PAD的跳变(上升/下降沿),同时排除X态(综合环境中可省略X态判断) if(PAD !== pad_prev && ^PAD !== 1'bx) begin t_pad_prev <= t_pad_current; t_pad_current <= time_counter; pad_pulse_width <= time_counter - t_pad_prev; end // 原代码else分支的清零逻辑,仅在复位时执行即可,正常运行时保持寄存器值 end end // 3. filt_in_h信号的脉冲宽度测量逻辑(同PAD逻辑) always @(posedge clk or negedge rst_n) begin if(!rst_n) begin filt_in_h_prev <= 1'b0; t_filt_prev <= 32'd0; t_filt_current <= 32'd0; filt_in_h_pulse_width <= 32'd0; end else begin filt_in_h_prev <= filt_in_h; if(filt_in_h !== filt_in_h_prev && ^filt_in_h !== 1'bx) begin t_filt_prev <= t_filt_current; t_filt_current <= time_counter; filt_in_h_pulse_width <= time_counter - t_filt_prev; end end end endmodule
关键细节解释
- 计数器替代时间戳:
time_counter由FPGA全局时钟驱动,每周期自增,其值对应从复位开始的时钟周期数,等价于原代码的$realtime(若需实际时间,后续可乘以时钟周期换算,比如100MHz时钟对应10ns/周期)。 - 同步边沿检测:通过对输入信号打拍(
pad_prev)捕捉跳变,替代原代码的异步电平敏感always @(PAD),避免FPGA出现亚稳态问题。 - 类型替换:将
realtime改为reg [31:0],位宽可根据最大测量需求调整(32位在100MHz时钟下可测量约429秒的脉冲宽度)。 - X态处理:综合环境中不会出现X态,
^PAD !== 1'bx的判断仅用于仿真兼容,实际硬件可省略。
内容的提问来源于stack exchange,提问作者Eliza
相关产品推荐
相关产品推荐

