Actually, the structure of your verilog looks just fine. It's the details that are wrong, in a lot of places. Here are some:
reg [3:1] y2, y1, Y2, Y1
Yes, the missing semicolon throws the compiler off. More to the point, [3:1]
tells it that each of these regs is three bits wide, but they're only one bit wide in the planning. Traditionally we use 0 for the least significant bit (such that the binary interpretation has weight 2^n at bit n). The parameter line would thus be [1:0]
, as it is you extend it to three bits wide.
always @(w,y2,y1)
always @(negedge Resetn, posedge Clock)
The sensitivity list is separated by or
, not comma.
case (y2)
A: if (w) Y2 = 0;
Y1 = 1;
else Y2 = 0;
Y1 = 0;
y2
in this case statement only matches one bit in your planning (three in the code, but that made less sense). You can concatenate bits using {y2,y1}
; in fact, extending the case to case ({y2,y1,w})
will let you use case matches like {A,1'b0}:
and remove the if
statements entirely.
Secondly, you are trying to manage groups of statements (both assignments to Y2 and Y1) with if
; doing so requires enclosing them with begin
and end
. Alternatively, you could make a wider assignment such as {Y2,Y1} <= B;
, which ends up more readable as it can use your named states.
Thirdly, assignment using =
can cause some confusion (it acts more like sequential languages, while <=
doesn't modify the meaning of a reg within your always). In this case, it is fine as the block is fully combinatorial and does not depend on its own outputs.
Finally (for the case
section), you can simply add more matches. You don't even need a default
match, but it's probably convenient to use default
to go to state A in this case.
always @(negedge Resetn, posedge Clock)
if (Resetn == 0) //something :/
else //something else :/
Something and something else would be register updates, such as {y2,y1} <= {Y2,Y1};
. It is the clock edge sensitivity that turns the regs into flipflops.
Finally, since you should now understand what defines a reg width, why don't you make two bit wide regs named state
and next_state
to replace {y2,y1}
and {Y2,Y1}
respectively?
if you really need to understand it, you need to learn the theory behind it. Start with theory on formal languages. There you can find,that formal language can be specified by something called regular grammar, regular expressions or finite automaton (another name for finite state machine) etc. etc. Which are all basically the same thing with equal "computational power".
So one answer to your question could be, that one method of encoding FSM is transformation of the FSM to a regular expression (which is basically textual string).
Best Answer
If you have a state machine with N states, there are a number of different ways to encode those states as binary logic.
One-hot encoding assigns one FF to each state, so it requires N FFs. Only one FF has the value 1 (is "hot") at a time. If at any time, more than one FF is 1, that's an error.
Binary encoding assigns sequential integers to the states, and they get encoded on \$\lceil\log_2 N\rceil\$ FFs as unsigned binary numbers.
Hamming encoding is similar to binary encoding, except that enough additional FFs are added so that the state assignments are Hamming codes that are capable of correcting single-bit errors and detecting double-bit errors. An error detector monitoring the state values can determine that an error has occurred and correct it. If the binary encoding requires \$M = \lceil\log_2 N\rceil\$ FFs, then the Hamming encoding requires an additional \$\lceil\log_2 M\rceil + 1\$ FFs.