You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:30:49