02-14-2020 01:17 PM
I am not sure whether this will be right platform to put my query but I need some suggestions.
I write the verilog code for fun and i would to share my code with you, for understand if what i write is correct.
I usually write FSM using both edge of clock, i serched in the lecterature, but i don't find any example about it.
in attach i post 3 example of my code, someone can help me to understand the correct way?
thank you a lot.
02-20-2020 01:53 AM
02-20-2020 02:28 AM
When you said you use both edges of the clock I was getting ready for a disaster, but it's really not that bad. You use one edge of the clock, and one edge of the reset - which is acceptable. With that said, Xilinx recommendation is to use synchronous resets (ie check the value of "reset" in the block, but don't actually trigger the block on the reset signal).
Another "style" point is that (at least in the SPI FSM that I'm looking at) you use capital letters everywhere. Normally I'd use these for constants (IDLE, TIME, S1, READ) and leave everything else lower/mixed-case.
A third (minor) style point is that you always define the bits being set (eg. "C_STATE[1:0] <= STATE[1:0];"). This is unnecessary; they're both 2-bit values and the synthesis tool is quite smart enough to recognise that "C_STATE <= STATE;" means that you want to use both bits.
A more fundamental issue is that your FSM seems to be a mix of the 1-block and 2-block techniques.
In a 1-block FSM, you have a single clock-triggered always block, and you update the state in there directly. Because the state update only occurs after the block finishes, it's got the new state for the next clock cycle. This is an absolutely valid way of writing FSMs.
In a 2-block FSM, you have a single clock-triggered always block which essentially sets state <= next_state (or your equivalent). It may also handle the reset. All the interesting logic happens in a separate combinational block ("always @(*)"), which depends on state and defines next_state.
In your code, you've gone for the 2-block style - but both blocks are clock-triggered! What this means is that on one cycle the "processing" block sets STATE, then on the next cycle it runs again with the original C_STATE value. On that cycle C_STATE gets updated to be STATE in your state update block, so on the third cycle C_STATE is updated and your FSM actually moves on. This feels like it'll be very confusing; much better to just dump your state update block (the top one) and remove C_STATE entirely.
02-22-2020 10:10 AM
thank you for your time.
I don't understand one thing, when I use an alway with posedge for update the state and another always on negedge for check the output
is an different way to build a FSM or is uncorrect way?
thank you again
02-24-2020 05:18 AM
Transitioning on both edges of a clock is generally a very bad practice when working with FPGAs. It's usually better to increase the speed of the clock by 2x if you need to do something like that.
02-24-2020 06:34 AM