Ed:
Quote:
So, if this is bad code should I remove the links? Does it need a health warning?
Not bad code per se, but not necessarily precise. It has been my personal experience, stemming from a lack of a precise understanding of the subject matter at the time, that there's too much glossing over of the distinction between hardware modeling and hardware implementation. In other words, the HDL hardware designer is left with the task of determining how the HDL synthesizer interprets his source code and generates the desired HW.
It's rather unfortunate that these languages are named Hardware Design Languages. The primary purpose of languages like Verilog and VHDL is as a modeling language for HW. There are many situations in HW development/engineering where a model is more important to the understanding and testing of a design than it is to have the hardware itself. One example of this is when the model developed, without regard for the actual details of the implementation itself, is used to specify the desired behavior that the implementation is to have. Subsequently, this same model can be used as a reference to which the implementation, the RTL implementation, can be compared for the purposes of testing and verification.
We've discussed on this thread Verilog papers from Sunburst Designs and papers by Stuart Sutherland. Mr. Sutherland has been heavily involved in the development of Verilog and SystemVerilog, and provides consulting services for industry on the subject of design and simulation using Verilog. Mr. Sutherland prepared a
presentation which is fairly appropos to this discussion. It provides the essential rules for using blocking (
=) and non-blocking (
<=) assignments for both combinational and sequential logic. Although it is 16 years old, it directly addresses the issue that seems to be driving most designers crazy with regard when to use these assignment operators in the their designs. If you'll peruse the presentation, you'll find justification for the simple rules I provided
here at your request.
One thing to keep in mind when reviewing the material provided in that presentation, Mr. Sutherland is presenting the topic from a simulation first perspective. That is, most of his examples represent models of the desired behavior and the discussion of when to use the block (=) and non-blocking (<=) assignment operators is focused on describing desired behavior. On page 26 of the presentation is the coup de gras. On that slide, he poses the question "How many Verilog statements does it take to model an 8 stage pipeline?", and he provides the solution.
Quote:
What simply-stated rules has he broken?
In the first example you linked to, he presents the test bench for a simple 2:1 multiplexer. He then proceeds to develop a testbench to test the multiplexer module. In the explanatory text following the testbench, he stated that the three inputs, S, A, and B, were FFs. They are no such things in the simulation testbench. There is much confusion of the two primary Verilog signal types:
reg and
wire.
reg does not refer to FFs.
The Verilog reg signal type is simply a signal that can hold a value.
A signal assigned a value in the simulation must be declared as having type
reg since the other Verilog signal types can not hold a value.
A signal assigned with an always block must be a reg even if the desired behavior is as a combinatorial signal. In the referenced post, I said to use the non-blocking assignment operator within
always blocks regardless of whether the signal is a combinational or sequential logic signal.
Arlet correctly pointed out that a blocking assignment operator may also be used. In simulation, blocking assignments, with delays, can be used to model the behavior of HW FFs. That statement alone should be enough to drive home the point:
reg is a signal that can hold a value and is not a FF. This may seem to be a fine point, but it is important when more complex circuits are desired. It also explains why Verilog is allowed to insert latches when combinational signals are not fully defined. Only simple combinational circuits that can generally be described with the
?: conditional construct that can be used in
assign statements. More complicated combinational circuits must be described in
always blocks, which require the output variable to be declared as a
reg. As a consequence, when the signal is incompletely specified, Verilog can insert a latch to hold its value since the output signal has type
reg. The
?: conditional requires that both components be specified (or a syntax error is generated), so it can't generate an inferred latch.
Quote:
Because verilog is more subtle than it appears, I feel the need for simple rules. Many attempts at introduction go on about the parallelism, which may indeed be a source of confusion to someone with a coding background, but what are the rules to avoid misinterpretation of the intended design?
This in an incomplete analogy, but the best I can come up with is that all statements (contained within an
always or
assign statements) must be considered independent threads of execution. The combinational circuits require no synchronization mechanism. All of the sequential logic statements synchronize once per clock period, and it is for this reason that the number of clocks in a design should be minimized. Otherwise, the problem of thread synchronization that occurs in multi-threaded SW occurs in multi-clock HW (and there is no operating system to fall back on).
Quote:
As an example, one doesn't even need to know about the danger of implying a latch, if one has rules which make that impossible. Break the rules, you're in unknown territory. Don't do that until you have a deeper understanding.
Latches are a useful design component, and most FPGAs have an explicit way of specifying latches when they truly needed. Like the SW GOTO, latches can in most cases be designed out. But just like in SW when there are exceptional conditions when a GOTO is required, there are times when explicit latches may be required.
Completely specify all combinational logic to prevent the synthesizer from inferring latches.
I think that I can say with absolute certainty that inferred latches are never allowed is an absolute, no come backs, stone tablets from the mountain type of rule. There won't be any seeking of a deeper understanding. Inferred latches change the behavior of the HW design, and generally cause the specification (simulated behavioral RTL) and the synthesized RTL to not yield the same result.
Quote:
I'm not saying there's no need for a full explanation, I'm saying I think beginners would have an easier time of getting started and getting a working design quickly if they had concise guidance.
In general I agree, the rules that I provided are the type of simple concise guidance that is required. However, like SW, designing HW in an HDL still requires some basic knowledge of the subject. The Xilinx ISE lightbulb tool (I'm sure that there exists a similar syntax and code example tool in virtually all FPGA development toolsets) provides extensive code examples in both Verilog and VHDL that I use all the time, and which I recommend to all.
If a background in HW design is lacking, then there is simply going to be some tough times for a period of time. Some concepts can be learned from books and classroom time, but it's been my experience that these methods simply provide a stepping stone or path, and do not provide the experience necessary to be a HW or SW developer.
However, I firmly believe where there's a will to learn, there's a new HW designer. Just like jumping in and using code examples from a working SW application to learn a new SW programming language, I think it is important to jump in and start developing HDL-based HW designs. Forums like this one exist for HDL designs, and there is a lot of help available from forums operated/facilitated by each of the FPGA vendors.