I am trying to implement counter using Verilog HDL
output reg testLED;
reg [30:0] counter;
reg [30:0] sec = 0;
always @ (posedge clock50MHz)
begin
if(sec>10) testLED = 1;
counter<= counter+1;
if (counter == 30'd50_000_000) begin
counter<=0;
sec = sec +1;
end
end
However, this code is not working properly. testLED lights up immediately after startup. Moreover, when I tried to do it using assign, the counter worked properly.
output testLED;
reg [30:0] counter;
reg [30:0] sec = 0;
always @ (posedge clock50MHz)
begin
counter <= counter+1;
if (counter == 30'd50_000_000) begin
counter<=0;
sec = sec +1;
end
end
assign testLED = (sec>10) ? 1 :0;
What is the reason of this behaviour and how make the counter work without "assign"?
1 Answer 1
You have not initialized 'counter', but that's not the only issue.
The two statements don't do the same thing. If you replace
if(sec>10) testLED = 1;
With
testLED <= (sec>10) ? 1:0;
(and deal with initializing 'counter') then it should work. Note the use of a non-blocking assignment <= in the sequential block, also note that a value is assigned on every single clock edge. If you don't assign a value on every edge, a flip-flop is needed to retain the previous value (in this case, an uninitialized value).
You could alternatively add a combinational block using a a blocking assignment:
always @ (*)
begin
if(sec>10) testLED = 1;
else testLED = 0;
end
or even
always @ (*)
begin
testLED = 0;
if(sec>10) testLED = 1;
end
They are equivalent give or take one 50MHz clock edge.
counter
? \$\endgroup\$