Search code examples
verilogmodelsim

Expecting a vector value and getting an array instead for a reg


I am trying to create Verilog code which allows for an LED to blink at a certain frequency. I have a reg that I am using as a counter that I think should be a vector but is instead saying it's a packed array in ModelSim.

VERILOG CODE

module main(
    input wire clk,         //100MHz//
    input wire reset_,
    output LED1     //LED On/Off Two-States//
    );
    reg [27:0] LEDStateCount;   //LED Counter - 27 Bit Stored//
    reg OFF;            //State of LED//    
    localparam [27:0] Freq=50000000;    
    assign LED1 = OFF;         
    always @(posedge clk or negedge reset_)begin
        if (!reset_)begin
            LEDStateCount <= 28'b0;    //On startup, clear value//
            OFF <= 1'b1;
        end
        else if (LEDStateCount<Freq)begin
            LEDStateCount <= LEDStateCount + 1'b1;    //Accumulate to ~50,000,000//
        end 
    else if (LEDStateCount == Freq); begin
        OFF <= 1'b0;             //LED Off Until Value Reached//
        end
    end
endmodule

TEST BENCH

`timescale 1 ps/ 1 ps
module testbenchsaveme();
reg clk;
reg reset_;                                             
wire LED1;                              
main i1 (   
    .LED1(LED1),
    .clk(clk),
    .reset_(reset_)
);
initial 
begin 
#100000000 $stop;
end 
always
begin
    clk = 1'b0;
    clk = #5000 1'b1;
    #5000;
end  
initial
begin
    reset_ = 1'b1;
    reset_ = #100 1'b0;
end 
endmodule

ModelSim Waveform

A few things I am confused about.

  1. Shouldn't my OFF Signal be set to 1 in this scenario after the !reset_? Originally I had this my OFF set to 1'b0 in that reset_ loop, but that gave me a value of 1 after the negedge of reset_.
  2. I believe LEDStateCount should be vector that is 28 bits long in binary; however ModelSim seems to be treating them as 28x1 array. Regardless of how it's being stored, I thought it should still increment in situations where the LEDStateCount is not equal to the stored Freq value.
  3. If I don't set it to increment by a bit value and instead use 1, my OFF signal never initializes and I'm not sure why that is.

I'm not sure if these issues are because of a lack of experience in ModelSim, an issue with the code, or a bit of both. The clk is operating as expected and, when forced as a value, I can get LED1 to produce the signal I am looking for, that being high or low.


Solution

  • The first problem was a tricky one. You have a semicolon where you don't want it to be. Change:

    else if (LEDStateCount == Freq); begin
    

    to:

    else if (LEDStateCount == Freq) begin
    

    Now I see OFF become 1.


    The second problem regarding your counter not counting is due to the reset signal. Since your reset signal is active-low, you want to drive it differently in your testbench:

    initial
    begin
        reset_ = 1'b0;
        reset_ = #100 1'b1;
    end 
    

    Normally, you want the reset to be asserted at time 0, then released after a delay. In your code, you assert it at time 100, then keep it asserted for the duration of the sim. This prevents the counter from incrementing.