简体   繁体   中英

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

What I'm trying to do: I wish to count numbers from 0 to hexadecimal F and display these on my FPGA board at different frequencies - my board's clock (CLOCK_50) is at 50 MHz and I wish to alter the frequency/speed of the counting based on two input switches on my board (SW[1:0]).

Verilog Code for top-module & clock divider module:

//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 Code:

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

Problems I am facing:

Here's the thing - when I don't use the always block to select a parameter, and pass a desired parameter to the wire selected_freq, my simulation works fine - I can see the expected enable pulse.

HOWEVER, if I use the always block, the reg cycles_countdown does get the correct value assigned, BUT for some reason the enable signal is just a red line. When I select my clock_divider_enable module and add it's 'q' signal onto my waveform, it is red too and shows no data, and the object q is "not logged". As such, I'm unable to debug and figure out what exactly the problem with my code is.

It'd be great if someone could help with how to fix the simulation issue rather than just point out the issue with my Verilog code since I want to learn how to use ModelSim efficiently so that in the future debugging will be easier for me.

Equipment Used:

FPGA: Altera De-1-SoC, Cyclone V chip

CAD/Simulation Tools: Altera Quartus II Lite 17.0 + ModelSim Starter Edition

SW wasn't given an initial value, therefore it is high-Z (X if connected to a reg).

I'm guessing when you used the parameter approach you were parameterizing cycles_countdown . Some simulators do not trigger @* at time-0. So if there isn't a change on the senctivity list, then the block may not execute; leaving cycles_countdown as its initial value (4'hX).


Instead of driving your test with TCL commands, you can use create a testbench in with verilog. This testbench should only be used in simulation, not synthesis.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM