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

时间:2017-07-04 14:13:01

标签: verilog modelsim

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

顶级模块的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块来选择参数,并将所需参数传递给wire_freq线时,我的模拟工作正常 - 我可以看到预期的使能脉冲。

但是,如果我使用always块,则reg cycles_countdown会获得正确的值,但由于某种原因,启用信号只是一条红线。当我选择我的clock_divider_enable模块并将其'q'信号添加到我的波形上时,它也是红色并且没有显示数据,并且对象q“未记录”。因此,我无法调试并弄清楚我的代码究竟是什么问题。

如果有人可以帮助解决模拟问题,而不是仅仅指出我的Verilog代码的问题,那就太棒了,因为我想学习如何有效地使用ModelSim,以便将来调试更容易我

使用的设备:

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

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

1 个答案:

答案 0 :(得分:0)

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

我猜你在使用参数方法时正在参数化cycles_countdown。某些模拟器在时间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