The statements inside a process
are indeed executed sequentially, but they are all executed each time the process is activated (as defined by its sensitivity list).
Typically, the entire process will be executed once per clock edge, which means that any outputs (signals or variables) that get assigned within the process can all be updated on any given clock edge.
In this case, "sequential" refers to the relationships among the statements inside the process, but it has no bearing on its interaction with the rest of the design.
I'm guessing that like me, you probably come from a software development background and are now learning HDL.
The when others
case is empty; that's where you are implicity making all the latches. You clear this warning by explicitly setting the output's next value to its previous value, like x <= x;
. Remember this is a Hardware Description Language, not a procedural computer programming language. So you have to think in terms of what actual hardware you expect each module to implement.
As a general rule, when you have a case statement, each clause (i.e. each "execution path" though that's the wrong terminology) -- should define the value of each of the statement's output ports, even if there is no change intended. There are certain code patterns that HDL synthesis tools recognize, and for best results you should try to stick with those forms whenever possible.
Response to the comment:
There's two kinds of warning mesasges here.
Warning # 10492 seems to indicate that an input signal is missing from the sensitivity list
.
Warning (10492): VHDL Process Statement warning at IDEXWBBranchUnit.vhd(105): signal "newpc" is read inside the Process Statement but isn't in the Process Statement's sensitivity list
In the delcaration
comb_part : process (in1, in2, N, Z, C, V)
the sensitivity list only declares in1, in2, N, Z, C, V
as the available input signals. In terms of hardware, this is like declaring that comb_part is implemented with some hardware block that has these six inputs -- and then oh by the way, surprise, here's this other signal called offset
, which looks like it was meant to be another input.
offset <= std_logic_vector(resize(signed(in1(26 downto 0)), 32));
So because this is a non-blocking assignment
statement, offset must be some kind of signal, but is it an internal register or an output? The HDL compiler can't tell of that's what was intended, thus the error message.
Recommended fix is that you need to review your design and determine whether you need to add those inputs to the sensitivity list.
Warning # 10631 seems to indicate that an output signal has an inferred latch
.
Warning (10631): VHDL Process Statement warning at IDEXWBBranchUnit.vhd(66): inferring latch(es) for signal or variable "flushfifo_t", which holds its previous value in one or more paths through the process
In software it's assumed that variables hold their value until explicitly changed, but in HDL synthesis that requires a latch or a flip-flop. When you have an HDL module that describes code in terms of "behavioral" statements like if/else, or swtich/case, and there is at least one non-blocking assignment
to a signal, then every "execution path" should explicity make a non-blocking assignment to that signal.
case opc is
when OPC_BEQ =>
if (Z = '1') then
flushfifo_t <= '1';
pcOUT_t <= newPC;
pcWrEn_t <= '1';
end if;
-- etc...
when OPC_BLAL =>
flushfifo_t <= '1';
pcOUT_t <= newPC;
pcWrEn_t <= '1';
regOut_t <= "00000";
dataVal_t <= newpc;
wr_reg_t <= '1';
when OTHERS =>
-- [MarkU] here's the problem, missing non-blocking assignments should go here
flushfifo_t <= flushfifo_t;
pcOUT_t <= pcOUT;
pcWrEn_t <=pcWrEn_t;
-- [MarkU] and so on for all the non-blocking assignments that are unchanged in this case
end case;
Best Answer
The
if-elsif-else
construct infers a priority routing network:simulate this circuit – Schematic created using CircuitLab
This corresponds to
The
case
construct, on the other hand, infers a big ol' mux:This corresponds to
Obviously these are very simplified designs with only one value expression, resulting in one output.
Per the above, you can see how they would nest/mix.
Since
if-else
infers priority, it should be used when more than one input condition could occur. Usingcase
, one the other hand, is appropriate when the inputs are mutually exclusive.