If I have more reg
declared, every reg
needs to have his own always
block, for example:
output reg[3:0] A;
output reg[3:0] B;
output reg[3:0] C;
always @(posedge clock) begin
if(reset) begin
A <= 4'b0;
end
.
.
.
end
always @(posedge clock) begin
if(reset) begin
B <= 4'b0;
end
.
.
.
end
always @(posedge clock) begin
if(reset) begin
C <= 4'b0;
end
.
.
.
end
What if I have a loop, lets say something like this:
repeat n times
if(C<0) begin
shift C two positions
C <= C + 1;
else
shift A one position
A <= C + 1;
end
As you see here, inside of if(C<0)
block, I can't have
C <= C << 2;
C <= C + 1;
so I will need separate register to store C
shifted, let's say it will be output reg[8:0] shiftC
, so by the way I need separate always
block. And of course, separate always
block for A
too.
My question is, how can I make this loop work, if I use multiple always
blocks?
PS: here, number of bits is just informative, and does not matter.
1 Answer 1
I learned [...] every
reg
needs to have his ownalways
block...
I think you've got this backwards. Each register should only be assigned to by one always
block. However, this doesn't mean you need a separate always
block for each register! It's perfectly safe (and, in fact, quite normal) to have a single always
block for all the synchronous logic in a module, e.g.
always @(posedge clk) begin
if (reset) begin
A <= 4'b0;
B <= 4'b0;
...etc...
end else begin
...etc...
end
end
What if I have a loop, lets say something like this:
You can't do that in a loop.
Verilog loops are for generating multiple copies of repeated logic. They are not a substitute for clocked logic -- if you need to perform multiple actions, you will probably need to make them happen on separate clocks, and implement them in a state machine.
Depending on what you need to happen, there might be some way to "unroll" the loop and make several iterations happen in a single clock. However, you will need to be very careful about how you implement this. Making multiple levels of branching logic run in a single clock cycle is generally inadvisable; data dependencies will severely limit the clock rate of such a design.
-
\$\begingroup\$ Thank you for your answer. I understood part about loops, but at part about
every reg needs to have his own always block
I don't know who to trust. When I wrote many registers in samealways
block, my teachers told me to never ever do that again, because is software like. In every single example given by them, there were all the time separatealways
blocks for every register. \$\endgroup\$Linksx– Linksx2017年05月15日 21:39:17 +00:00Commented May 15, 2017 at 21:39 -
1\$\begingroup\$ @ClaudiuM Your teacher, and those examples, are wrong. Breaking up
always
blocks that way will inevitably end up forcing you to replicate logic (like theif (reset)
in my example); having multiple copies of that logic makes it easy to accidentally change one but not the other, leading to unexpected behavior. \$\endgroup\$user39382– user393822017年05月15日 21:42:02 +00:00Commented May 15, 2017 at 21:42 -
\$\begingroup\$ Writing FSMs would be a nightmare if each
reg
needed its own always block. It is definitely not a Verilog requirement, nor a requirement from any other HDL I'm aware off. Perhaps the "every reg needs to have its own always block" is an assignment requirement; a challenge to make you think. \$\endgroup\$Greg– Greg2017年05月15日 23:17:45 +00:00Commented May 15, 2017 at 23:17 -
\$\begingroup\$ @Greg I also asked other people who are advanced in Verilog and actually graduated school. They all told me that I need an
always
block for every register. I would like to trust you, rather than trust them. Their examples of circuits and add/sub/mult/div algorithms are also wrong described, and I'm not the only one here who have this problem. \$\endgroup\$Linksx– Linksx2017年05月16日 05:35:52 +00:00Commented May 16, 2017 at 5:35
C <= {C,2'b01};
. For more complex procedural logic I sugest adding a combinationalalways @*
block to assignC_next
(or other name of your choice) with blocking statements (=
), then in the synchronousalways @(posedge clock)
block assign asC <= C_next
\$\endgroup\$