PS I taught Digital Systems for many years and the first version always annoyed me!
Since you teach the language, you're focused on the language. In contrast, I am focused on the design, and I want to use the language to describe my design with as little effort as possible.
The easiest way to infer flip-flops is to create a clocking process. So, I have a 4-line template which I paste. It happened to be "rising_edge" variety, so I use "rising_edge" everywhere. It could have been "clock'event" variety just as well, in which case I would use "clock'event" everywhere. Makes no difference, except one - with "rising_edge" I need to change the clock name twice. With "clock'event" I would have to do it three times. So, I would say "rising_edge" is somewhat better.
You're missing the point, which is that rising_edge(clk) is the proper modern idiom to use when inferring edge-sensitive flip-flops.
Also, your editor doesn't have a find-and-replace feature?
That's a bit silly. I don't invoke a search and replace to change two things. It's more work than it's worth.
My assumption was that NorthGuy wanted to change the name of the clock in more than one process/block. Basically a refactor. Hence, search and replace. In emacs, that's
M-x replace-string.
But it would be even better if there was a construct where I need to change the clock name only once. Sorry, not in VHDL
We know you're a Verilog partisan, so explain why the sensitivity lists for always blocks that are used to infer flip-flops with an asynchronous reset are sensitive to the edge of that reset?
To wit:
always @(posedge clk, negedge rst_l) begin
if (!rst_l) begin
q <= 1'b0;
end
else begin
q <= d;
end
end
Flip-flop async resets are not edge triggered!
That's not exactly correct. All logic in HDLs take action on the transition. Then that state is assumed to hold until something else takes action on the signal. If you model a pull-up resistor with an 'H' or 'L' even that takes action when the signal that had been driving it makes the change to release the drive (an edge if you will).
Actually, they take action when there is an event on a signal. An assignment to a signal creates an event on that signal, even if the new value assigned is the same as the previous.
Yes, I know this is not considered to be edge sensitive logic, but that's the way models in HDL work, both HDLs.
Well, yes, but the point is that the always block should not be sensitive to the edge of the reset if the reset is actually a level.
The only difference between saying rising_edge(signal_name) and adding signal_name to the sensitivity list is the sensitivity list acts on both edges.
No --
the sensitivity list triggers the process on any event on its signals.This is why we are discussing the use of VHDL's
rising_edge(clk) vs
clk'event and clk = '1'! The process is sensitive to any event on the signals in the list. We have shown, the transition from 'H' to '1' creates an event which the latter idiom will say "yes! You have a rising edge!" whereas the former (the
rising_edge() function)
will not.
You can describe a FF thus.
A <= B when rising_edge(clk);
Works pretty much like any other concurrent assignment.
Yes, it does.
The implied sensitivity list is (B, clk), so sensitive to edges of both signals, yet A only changes when there is a rising edge on clk.
Yes, and the B on the list is superfluous -- and that's why the model for the synchronous process includes only the clock and async resets. You don't trigger the process on changes in the D input. Remember the model here: a D flip-flop ignores its D input except on the active edge of the clock input.
Also the above always block doesn't explicitly say that the q <= d assignment happens on the rising edge. It's implied because we know there are only two events which trigger the block. We explicitly test only for the state of rst_l first, and if that test is false, then we assume that the rising edge of clk was the trigger event.
But even the test for rst_l being low is sorta weird. The only event on rst_l that triggers the block results in that signal being low, so testing for it being low is redundant.
Not redundant if the process was triggered on the clock while rst_l was low. rst_l being low does not stop the triggers on clk.
What I'm saying is that the block is triggered by the falling edge of rst_l, and Verilog doesn't have a way of describing the innards of the block in a non-redundant way.
Yes, the clock can toggle while
rst_l is asserted low. Yes, the correct operation is for the clock to be ignored as
rst_l low has precedence.
But the block is sensitive only to the falling edge of
rst_l so the test for
rst_l = '0' is redundant but necessary because Verilog gives you no way to discern that the block was triggered by
rst_l and not the clock. VHDL says, "there was some event on a signal on your sensitivity list, please check for the conditions of interest on all of them."