I was also of the opinion that it wasn't a very good coding style but after a couple of years of basic VHDL teaching I think it is actually better to say that a sequential process looks like this:
process begin -- process wait until rising_edge(clk); -- Some code... end process;
The "standard" alternative is this:
process (clk) begin -- process if clk'event and clk = '1' then -- rising clock edge -- Some code... end if; end process;
The problem with the second one is that first time students are likely to produce something like:
process (clk) begin -- process if rst = '1' then foo '0'); end if;
if clk'event and clk = '1' then -- rising clock edge -- Some code... else somethingelse
YOU CAN NOT USE "wait" statement for FPGA design. YOU CAN NOT USE "wait" statement for FPGA design. YOU CAN NOT USE "wait" statement for FPGA design. YOU CAN NOT USE "wait" statement for FPGA design. YOU CAN NOT USE "wait" statement for FPGA design.
- First time students will disobey the template and create unholy processes which works in modelsim (most of the time) but has no hope of ever working in a CPLD or FPGA :/ If the wait until rising_edge(clock) is used instead, the tool will not accept anything which isn't synchronous no matter how much you try.
Sure, we could (and of course _do_) say "Don't do that!", but even so I don't think it is an exaggaration to say that at least one group disobeys the template on every lab, leading to much frustration (for them :)). In their defense, they usually come from a programming background and they also have faith that a design that works in ModelSim will work in hardware. If they were experts in digital design they wouldn't have to take this course after all :)
Anyway, this is a relatively minor point, what would be much better in a teaching situation is if XST could be configured to be more strict in what it accepts.
For example, I would like to be able to say that latches should not be allowed to be inferred at all in a design (unless they are instantiated manually). Please, implement always_ff/_latch/_comb from SystemVerilog ASAP :) (IIRC there is equivalent functionality in VHDL 2006 but I don't remember the details right now.)
Something which also would be nice is the ability to flag suspicious combinations of asynchronous/synchronous processes as errors. While it might be ok with an asynchronous reset it is probably not ok if that asynchronous reset is generated combinatorially in the same process as in:
if bar="1001" then foo '0'); else if rising_edge(clk) then foo
Indeed, you can't. But I consider this to be a deficiency of the tools. The above example is easy to synthesize. There have been academic proofs of concept decades ago. Essentially you only need to add a state per wait statement.
You cannot wait for TIME in synthesizable code. You can wait until rising_edge(clk)! Not usually the best coding style, but it can be done and is accepted by most synthesis tools.
NA,
You can wait for time in a testbench (simulation code written to test the synthesizable FPGA design code).
An additional problem is that the wait statement is a sequential statement (inside a process), but it is being used in a concurrent context (outside a process). That won't work for simulation or synthesis.
Concurrent assignment statements are each their own little implied process, running in parallel with other concurrent assignment statements and processes. The order in which they appear in the code is not necessarily the order in which they execute, and they may execute repeatedly/continuously.
You can use wait statements in FPGA design but not as the OP thinks like "wait clk'event and clk='1'" But using wait is not something I recommend.
The biggest problem here is that the OP needs to understand the difference of parallel statements and sequential statements. Outside processes, statements are parallel and inside processes statements are sequential Your statements outside the process are parallel but your attempt looks like you think them as sequential.
maybe some day later you understand that I did give good advice. something need to learned.
FPGA (or any hardware) DOES NOT WAIT... so its better not to get used to "wait",
when any signal changes then it propagates with interconnect+logic delay time, all FPGA vendors try to make those delays as small as possible.
so try to understand that FPGA is not actually waiting for something to happen, but contrary and event (change of signal values) is immediatly processed at maximum speed Any amount of events happening at same time all are handler in parallel.
so for your delay, you need to use some flag that gets set if some number of clock cycles is elapsed
eg you are not wait until that happens, but you should describe what should be done if the condition (time elapsed) exists.
if my first answer did not please you, well maybe it helps to understand the basic better at the end. its really the basic thing that you have not understand yet.
you should never forget that any electronic circuit can be built from single primitive NAND2 - in FPGA there are more primitives so you do not need need to build flip-flops from NAND2 gates, but same rules apply. if you write a clocked process this (if it is synthesiseable) CAN always be mapped to sea of gates of NAND2 (and logic gate does not know how to wait, if it is ideal it has 0 delay, if not then it has small delay).
The reason for the parse error is that WAIT is not allowed at the position you have used it, see the BNF of VHDL:
formatting link
wait_statement is a sequential_statement, which is allowed in subprograms, processes or as part of sequence_of_statements, which is allowed in loops and conditions.
But that's only the formal reason. Most synthesizes tools won't allow you to use it in processes, too, because VHDL is intended as a hardware description language. Sequential logic has to be implemented with state machines, see for example my DS2432 ROM id reader, which uses the same
1-wire protocol as the DS18B20:
formatting link
--
Frank Buss, fb@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
You do not want the chip to sit and wait at the point you have implemented the 'wait'. For this reason, wait is only used during a testing activity and is not allowed during synthesis.
What you want to do is to initialise a timer with a value that is proportional to the required delay and to decrement this timer on each clock transition until the value becomes zero (as you have basically done in the above code).
The problem is that you have placed the 'wait' statement there which is not allowed when synthesising.
Depending upon the complexity of your FPGA application - I would use a 'state machine' approach to coding the VHDL.
Those are by no means the only options. For example:
process (clock) begin if rising_edge(clock) then
-- Put your RTL code in here
if reset = '1' then
-- Put the code that resets any signals that need resetting in here
end if;
end if; end process;
Pros/cons: + No wait statement + Completely general + No asynchronous behaviour to worry about + No sensitivity list to worry about + Efficient (sync) resets for signals that need them but with no penalty for signals that don't - ???
As far as I've heard/seen in large companies with regulated coding styles, the wait statement version of a DFF is considered to be sloppy for readability maintainability purposes. tick-event is considered a much cleaner way of coding a DFF.
As for the original question: Buy a book on synthesizable VHDL and lookup "counter" in the index But it will go something along the lines of
Rising_edge / Falling edge only matter if you're using non '0' / '1' values in your simulation... U -> '1' is not a rising edge with "rising_edge" but is a rising edge if you use 'EVENT. But U, H, X, L, etc... only exist in simulation, no such thing inside your FPGA, so assuming you setup your simulation to reflect reality there's no difference.
Use of rising_edge() and falling_edge() is more self-documenting, safer in simulation, and last but certainly not least, easier to type!
The 'event style is discouraged in our coding style guides.
Another template that I use when needing some flops asynchronously reset, but not others in the same process is:
process (clk, reset) is begin if rising_edge(clk) then do_synchronous_stuff_here; end if; if reset = '1' then reset_some_but_not_all_flops_here; end if; end process;
The advantage is it works without creating feedback muxes for those flops not being reset. The disadvantage is you don't get a warning if you unintentionally leave something out of the reset clause.
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.