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

Modelsim-对象未记录&;模拟verilog时钟分频器代码时无信号数据,verilog,modelsim,Verilog,Modelsim,我想做什么:我希望计算0到十六进制F的数字,并在我的FPGA板上以不同的频率显示这些数字-我的板的时钟(时钟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 parame

我想做什么:我希望计算0到十六进制F的数字,并在我的FPGA板上以不同的频率显示这些数字-我的板的时钟(时钟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
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
我面临的问题:

//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
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 selected_freq时,我的模拟工作正常——我可以看到预期的启用脉冲

然而,如果我使用always块,reg cycles_倒计时确实得到了正确的赋值,但由于某些原因,启用信号只是一条红线。当我选择时钟除法器启用模块并将其“q”信号添加到波形中时,它也是红色,不显示任何数据,并且对象q“未记录”。因此,我无法调试并弄清楚我的代码到底有什么问题

如果有人能帮助解决模拟问题,而不是仅仅指出我的Verilog代码的问题,那就太好了,因为我想学习如何有效地使用ModelSim,这样在将来的调试中对我来说就更容易了

使用的设备:

//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
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
FPGA:Altera De-1-SoC、Cyclone V芯片


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

SW
未给出初始值,因此其为高Z(如果连接到reg,则为X)

我猜当您使用参数化方法时,您正在参数化
cycles\u countdown
。某些模拟器不会在时间-0触发
@*
。因此,如果senctivity列表没有变化,那么块可能不会执行;将
循环\u倒计时
作为其初始值(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
模块速率\u设备\u tb;
注册时钟50;
reg[1:0]SW;
reg[1:0]键;
金属丝[6:0]HEX0;
速率分配器dut(.CLOCK_50(CLOCK_50),.SW(SW),.KEY(KEY),.HEX0(HEX0));
总是开始
时钟_50=1'b1;
#10;
时钟_50=1'b0;
#10;
结束
初始开始
//初始输入信号

软件你需要在释放重置之前分配软件,两者之间有一个时间差。谢谢,工作得很好!你能解释一下我为什么要这么做吗?当我直接使用参数时,为什么没有问题?我猜在这种情况下,SWs没有驱动任何逻辑?