The error is caused by having two different always @
blocks assigning the same variable, Q. If you combine your logic into one always @
that error will go away. This is the normal way to solve the problem.
You have a number of other problems with your code, like your first always @
. We'll fix this, but I want to think about the problem a little differently.
Say you don't want the combinatorial part of the logic in the main always @
block. You may want this to modularize the logic for example, or you may need to use some hardware macro. Whatever your reason, yes, that's possible. In fact there's at least 3 ways to do that.
First way: use a function
:
module LAB (clk, clear, Enable, Q);
input clk, clear, Enable;
output reg [3:0] Q;
always @ (posedge clk) begin
if (~clear)
Q <= 0;
else
Q <= incrementer_4 (Q, Enable);
end
function incrementer_4;
input [3:0] a;
input increment;
incrementer_4 = a + increment;
endfunction
endmodule
Second way: use an assign
with an intermediate variable D:
module LAB (clk, clear, Enable, Q);
input clk, clear, Enable;
output reg [3:0] Q;
wire [3:0] D;
assign D = Q + {3'b0,Enable};
always @ (posedge clk) begin
if (~clear)
Q <= 0;
else
Q <= D;
end
endmodule
Third way: create an async block using always @
with a wildcard sensitivity list, again with an intermediate variable:
module LAB (clk, clear, Enable, Q);
input clk, clear, Enable;
output reg [3:0] Q;
reg [3:0] D;
always @ * begin
D <= Q + {3'b0,Enable};
end
always @ (posedge clk) begin
if (~clear)
Q <= 0;
else
Q <= D;
end
endmodule
So, yes, you can use two always @
statements, but not to the same variable.
All three of these examples will compile to the exact same result. The new concept I showed here is how to use the always @ *
block to make async logic. It's not used often, but it comes in handy if for example a complex async logic element like case
statement is needed.
I also introduced a couple of new syntax concepts:
- vector fields
{3'b0,Enable}
- safer way of handling logicals
(~clear)
Finally, I'm assuming your intent for the register is a synchronous reset. To make it async, you can add negedge clear
to the register sensitivity list to make it behave that way.
More about always
and the sensitivity list here: https://www.hdlworks.com/hdl_corner/verilog_ref/items/SensitivityList.htm
There's a fourth way, using a separate module
and instancing that in your code. You would need to do this if, for example, you were using a library element and wanted to instance it explicitly.
And here it is:
module LAB (clk, clear, Enable, Q);
input clk, clear, Enable;
output reg [3:0] Q;
wire [3:0] D;
increment_4 u_increment (Q, Enable, D);
always @ (posedge clk) begin
if (~clear)
Q <= 0;
else
Q <= D;
end
endmodule
module increment_4 (a, inc, sum);
input [3:0] a;
input inc;
output wire [3:0] sum;
assign sum = a + inc;
endmodule
Q
in two different always blocks. You have to figure out how to write one always block that handles both cases (Enable set or clear). \$\endgroup\$