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
A few things I am confused about.
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_
.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.
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.