Modelsim - 模拟 verilog 时钟分频器代码时未记录对象且无信号数据

Modelsim - Object not logged & no signal data while simulating verilog clock divider code

我正在尝试做的事情:我希望计算从 0 到十六进制 F 的数字,并以不同的频率在我的 FPGA 板上显示这些数字 - 我的板的时钟(CLOCK_50) 的频率为 50 MHz,我希望根据板上的两个输入开关 (SW[1:0]) 更改计数的 frequency/speed。

顶层模块和时钟分频器模块的 Verilog 代码:

//top level module 

module rate_divider (input CLOCK_50, input [1:0] SW, input [1:0] KEY,output [6:0] HEX0);

//Declare parameters that define the # of clock cycles needed to generate an enable pulse
according to the desired frequency.

    parameter FREQ_5MHz = 4'd9; //To divide to 5 MHz we need (10-1) cycles, 
                                //since the pulse needs to start at the 9th cycle.
    parameter FULL50_MHz = (4'd1);  //The CLOCK_50's Frequency.

//Select the desired parameter based on the input switches

    reg [3:0] cycles_countdown;  
    wire enable_display_count;
    wire [3:0] selected_freq;

    always @(*)
            case (SW)           
                2'b00: cycles_countdown = FULL50_MHz;
                2'b01: cycles_countdown = FREQ_5MHz; 
                default : cycles_countdown = FULL50_MHz;
            endcase

    assign selected_freq = cycles_countdown;        

//wire that is the output of the display_counter and input to the 7 segment

    wire [3:0] hex_value;

// instantiate my other modules

    clock_divider_enable freq_divider (.d(selected_freq), .clk(CLOCK_50), .reset(KEY[0]), 
                                                    .enable(enable_display_count));

    display_counter count_hex (.enable(enable_display_count), .clk(CLOCK_50), .hex_out(hex_value), .reset(KEY[1]));

    hex_decoder HX0 (.hex_digit(hex_value), .segments(HEX0[6:0]));

endmodule

//the clock_divider sub-circuit.

module clock_divider_enable (input [3:0] d, input clk, reset, 
                                        output enable);

    reg [3:0] q;

    always @(posedge clk)
        begin
            if (!reset || !q)
                q <= d;
            else
                q <= q - 4'd1;
        end

    assign enable = (q == 4'h0) ? 1'b1 : 1'b0;  

endmodule

ModelSim 代码:​​

vlib work
vlog rate_divider.v
vsim rate_divider
log {/*}
add wave {/*}

#initial reset - using KEY[1:0]. Note: active low synchronous reset.

force {CLOCK_50} 1
force {KEY[0]} 0
force {KEY[1]} 0
run 10ns

#choose 5 MHz as the desired frequency - turn SW[0] high. 

force {CLOCK_50} 0 0ns, 1 {10ns} -r 20ns
force {KEY[0]} 1
force {KEY[1]} 1
force {SW[0]} 1
force {SW[1]} 0
run 600ns

我面临的问题:

事情是这样的 - 当我不使用 always 块来 select 一个参数,并将所需的参数传递给线路 selected_freq 时,我的模拟工作正常 - 我可以看到预期使能脉冲。

但是,如果我使用 always 块,reg cycles_countdown 确实得到了正确的分配值,但由于某种原因,启用信号只是一条红线。当我 select 我的 clock_divider_enable 模块并将它的 'q' 信号添加到我的波形时,它也是红色的并且没有显示任何数据,对象 q 是 "not logged"。因此,我无法调试并弄清楚我的代码到底出了什么问题。

如果有人能帮助解决仿真问题,而不是仅仅指出我的 Verilog 代码的问题,那就太好了,因为我想学习如何有效地使用 ModelSim,以便将来进行调试对我来说更容易。

使用的设备:

FPGA:Altera De-1-SoC,Cyclone V 芯片

CAD/Simulation 工具:Altera Quartus II Lite 17.0 + ModelSim 入门版

SW 没有给出初始值,因此它是高 Z(如果连接到 reg,则为 X)。

我猜你在使用参数化方法时 cycles_countdown。一些模拟器不会在 time-0 触发 @*。因此,如果敏感列表没有变化,则该块可能不会执行;将 cycles_countdown 作为其初始值 (4'hX)。


您可以使用 verilog 创建测试台,而不是使用 TCL 命令驱动测试。此测试台应仅用于仿真,不可用于综合。

module rate_devider_tb;
  reg CLOCK_50;
  reg [1:0] SW;
  reg [1:0] KEY;
  wire [6:0] HEX0;

  rate_divider dut( .CLOCK_50(CLOCK_50), .SW(SW), .KEY(KEY), .HEX0(HEX0));

  always begin
    CLOCK_50 = 1'b1;
    #10;
    CLOCK_50 = 1'b0;
    #10;
  end
  initial begin
    // init input signals
    SW <= 2'b01;
    KEY <= 2'b00;

    // Log file reporting
    $monitor("SW:%b KEY:%b HEX0:%h  @ %t", SW, KEY, HEX0, $time);
    // waveform dumping
    $dumpfile("test.vcd");
    $dumpvars(0, rate_devider_tb);

    wait(CLOCK_50 === 1'b0); // initialization x->1 will trigger an posedge
    @(posedge CLOCK_50);
    KEY <= 2'b01; // remove reset after SW was sampled
    #600; // 600ns assuming timescale is in 1ns steps
    $finish();
  end