I tried making a BCD counter on EDA Playground using icarus verilog for simulation. In my first try, I coded the always
block without using the begin
and end
keywords:
module bcdcounter(out, clock, reset);
output [3:0] out;
input clock, reset;
reg [3:0] outstate= 4'd0;
reg [1:0] state= 2'd0;
always@(posedge reset)
case(state)
2'd0: state <=2'd1;
2'd1: state <=2'd2;
2'd2: state <=2'd0;
endcase
always@(posedge clock or state)
if(!state)
outstate <= 4'd0;
if(state == 2'd1)
if(outstate != 4'd9)
outstate <= outstate +4'd1;
else
outstate <= 4'd0;
if(state == 2'd2)
outstate <= outstate;
assign out = outstate;
endmodule
and the following output was generated while I checked:
design.sv:21: syntax error
design.sv:21: error: Invalid module instantiation
design.sv:23: syntax error
design.sv:23: error: Invalid module instantiation
design.sv:25: syntax error
design.sv:25: error: Invalid module instantiation
Exit code expected: 0, received: 1
But, once I added a few begin
and end
keywords, it did work without errors:
module bcdcounter(out, clock, reset);
output [3:0] out;
input clock, reset;
reg [3:0] outstate= 4'd0;
reg [1:0] state= 2'd0;
always@(posedge reset)
case(state)
2'd0: state <=2'd1;
2'd1: state <=2'd2;
2'd2: state <=2'd0;
endcase
always@(posedge clock or state)
begin
if(!state)
outstate <=4'd0;
if(state==2'd1)
begin
if(outstate!=4'd9)
outstate<= outstate+4'd1;
else outstate<= 4'd0;
end
if(state==2'd2)
outstate<=outstate;
end
assign out = outstate;
endmodule
When do we need to use the begin
and end
keywords in the design modules? Any help would be appreciated.
begin/end
keywords are mandatory when you have multiple statements within an always
block.
In your 1st always
block, you don't need begin/end
since the case
statement is considered a single statement.
However, in your 2nd always
block, you have 3 top-level if
statements, which means you need to group them together inside begin/end
. Here is the code with different whitespace to clearly show the separate statements:
always@(posedge clock or state) begin
// Statement 1
if(!state) outstate <= 4'd0;
// Statement 2
if(state == 2'd1)
if(outstate != 4'd9)
outstate <= outstate +4'd1;
else
outstate <= 4'd0;
// Statement 3
if(state == 2'd2) outstate <= outstate;
end
Since this code compiles without syntax errors, it demonstrates a couple things:
begin/end
keywords shown are mandatorybegin/end
keywords are neededHowever, other begin/end
keywords are optional. You may decide to use them in every if
statement. Here is another way to write the code:
always@(posedge clock or state) begin
if (!state) begin
outstate <= 4'd0;
end
if (state == 2'd1) begin
if (outstate != 4'd9) begin
outstate <= outstate +4'd1;
end else begin
outstate <= 4'd0;
end
end
if (state == 2'd2) begin
outstate <= outstate;
end
end
The same rules apply for initial
and final
procedural blocks, just like they do for always
blocks.