1 COMP541 State Machines - II Montek Singh Feb 13, 2012
Today’s Topics Lab preview: “Debouncing” a switch “Debouncing” a switch Verilog styles for FSM Don’t forget to check synthesis output and console msgs. Don’t forget to check synthesis output and console msgs. State machine styles Moore vs. Mealy Moore vs. Mealy 2
Lab Preview: Buttons and Debouncing Mechanical switches “bounce” vibrations cause them to go to 1 and 0 a number of times vibrations cause them to go to 1 and 0 a number of times called “chatter” hundreds of times! hundreds of times! We want to do 2 things: “Debounce”: Any ideas? “Debounce”: Any ideas? Synchronize with clock Synchronize with clock i.e., only need to look at it at the next +ve edge of clock Think about (for Wed class): What does it mean to “press the button”? Think carefully!! What does it mean to “press the button”? Think carefully!! What if button is held down for a long time? What if button is held down for a long time? 3
Beware the unintended latch! Very easy to unintentionally specify a latch/register in Verilog! one of the most common mistakes! one of the most common mistakes! one of the biggest sources of headache! one of the biggest sources of headache! you will do it a gazillion times you will do it a gazillion times this is yet another result of the the hangover of software programming this is yet another result of the the hangover of software programming forgetting everything in hardware runs in parallel, and time is continuous Solution good programming practice good programming practice 4
Beware the unintended latch! Example: multiplexer out is output of combinational block out is output of combinational block no latch/register is intended in this circuit no latch/register is intended in this circuit recommended Verilog: recommended Verilog: assign out = select? A : B; But, an if statement (inside an always block) will incorrectly introduce a reg: if (select) out <= A; if (!select) out <= B; reg added to save old value if condition is false reg added to save old value if condition is false to avoid extra reg, cover all possibilities: to avoid extra reg, cover all possibilities: if (select) out <= A; else out <= B; 5 select A B out
Verilog coding styles for FSMs 6
Verilog coding styles First: More on Verilog procedural/behavioral statements if-then-else if-then-else case statement case statement Then: How to specify an FSM Using two always blocks Using two always blocks Using a single always block?? Using three always blocks Using three always blocks 7
Verilog procedural statements All variables/signals assigned in an always statement must be declared as reg Unfortunately, the language designers made things unnecessarily complicated Unfortunately, the language designers made things unnecessarily complicated not every signal declared as reg is actually registered it is possible to declare reg X, even when X is the output of a combinational function, and does not need a register! whattt???!! They thought it would be awesome to let the Verilog compiler figure out if a function is combinational or sequential! They thought it would be awesome to let the Verilog compiler figure out if a function is combinational or sequential! a real pain sometimes you will suffer through it later in the semester if not careful!
Verilog procedural statements These statements are often convenient: if / else if / else case, casez case, casez more convenient than “? : ” conditional expressions more convenient than “? : ” conditional expressions especially when deeply nested But: these must be used only inside always blocks again, some genius decided that again, some genius decided that Result: designers often do this: designers often do this: declare a combinational output as reg X so they can use if/else/case statements to assign to X HOPE the Verilog compiler will optimize away the unintended latch/reg HOPE the Verilog compiler will optimize away the unintended latch/reg
Example: Comb. Logic using case module DecTo7Seg(input [3:0] data, output reg [7:0] segments); case (data) // abcdefgp 0: segments = 8'b ; 1: segments = 8'b ; 2: segments = 8'b ; 3: segments = 8'b ; 4: segments = 8'b ; 5: segments = 8'b ; 6: segments = 8'b ; 7: segments = 8'b ; 8: segments = 8'b ; 9: segments = 8'b ; default: segments = 8'b ; // required endcase endmodule Note the *: it means that when any inputs used in the body of the always block change. This include “data”
Synthesizing an Unwanted Latch? Could happen! Check the synthesizer output In order for a case statement to imply combinational logic, all possible input combinations must be described by the HDL Remember to use a default statement when necessary May be good practice anyway May be good practice anyway And all if statements w/ matching else And all if statements w/ matching else
Combinational Logic using casez casez allows case patterns to use don’t cares module priority_casez(input [3:0] a, output reg [3:0] y); casez(a) 4'b1???: y = 4'b1000; // ? = don’t care 4'b01??: y = 4'b0100; 4'b001?: y = 4'b0010; 4'b0001: y = 4'b0001; default: y = 4'b0000; endcase endmodule
Blocking vs. Nonblocking Assignments (review) <= is a “nonblocking assignment” Occurs simultaneously with others Occurs simultaneously with others = is a “blocking assignment” Occurs in the order it appears in the file Occurs in the order it appears in the file // nonblocking assignments module syncgood(input clk, input d, output reg q); reg n1; clk) begin n1 <= d; // nonblocking q <= n1; // nonblocking end endmodule // blocking assignments module syncbad(input clk, input d, output reg q); reg n1; clk) begin n1 = d; // blocking q = n1; // blocking end endmodule
Cheat Sheet for comb. vs seq. logic Sequential logic: Use clk) Use clk) Use nonblocking assignments (<=) Use nonblocking assignments (<=) Do not make assignments to the same signal in more than one always block! Do not make assignments to the same signal in more than one always block! e.g.: e.g.: (posedge clk) q <= d; // nonblocking q <= d; // nonblocking
Cheat Sheet for comb. vs seq. logic Combinational logic: Use continuous assignments (assign …) whenever readable Use continuous assignments (assign …) whenever readable assign y = a & b; OR Use (*) Use (*) All variables must be assigned in every situation! All variables must be assigned in every situation! must have a default case in case statement must have a closing else in an if statement do not make assignments to the same signal in more than one always or assign statement do not make assignments to the same signal in more than one always or assign statement
16 Revisit the sequence recognizer (from last lecture)
17 Let’s encode states using parameter module seq_rec (CLK, RESET, X, Z); input CLK, RESET, X; output Z; reg [1:0] state, next_state; parameter A = 2'b00, B = 2'b01, C = 2 'b10, D = 2'b11; Notice that we’ve assigned codes to the states
18 Next State logic begin case (state) A: if (X == 1) A: if (X == 1) next_state <= B; next_state <= B; else else next_state <= A; next_state <= A; B: if(X) next_state <= C;else next_state <= A; B: if(X) next_state <= C;else next_state <= A; C: if(X) next_state <= C;else next_state <= D; C: if(X) next_state <= C;else next_state <= D; D: if(X) next_state <= B;else next_state <= A; D: if(X) next_state <= B;else next_state <= A;endcase end end The last 3 cases do same thing. Just sparse syntax.
Register for storing state Register with reset asynchronous reset asynchronous reset reset occurs whenever RESET goes high reset occurs whenever RESET goes high CLK or posedge RESET) if (RESET == 1) state <= A; else state <= next_state; synchronous reset synchronous reset reset occurs only at clock transition reset occurs only at clock transition CLK) if (RESET == 1) state <= A; else state <= next_state; 19 Notice that state only gets updated on posedge of clock (or on reset)
20Output case(state) A: Z <= 0; B: Z <= 0; C: Z <= 0; D: Z <= X ? 1 : 0; default: Z <= 0; default: Z <= 0;endcase
21 Comment on Code Could shorten Don’t need next_state, for example Can just set state on clock Can just set state on clock Don’t need three always clauses Although it’s clearer to have combinational code be separate Although it’s clearer to have combinational code be separate Template helps synthesizer Check to see whether your state machines were recognized Check to see whether your state machines were recognized
Verilog: specifying FSM using 2 blocks Let us divide FSM into two modules one stores and update state one stores and update state another produces outputs another produces outputs 22
Verilog: specifying FSM using 2 blocks reg [1:0] state; reg outp; … clk) case (state) case (state) s1: if (x1 == 1'b1) state <= s2; s1: if (x1 == 1'b1) state <= s2; else state <= s3; else state <= s3; s2: state <= s4; s2: state <= s4; s3: state <= s4; s3: state <= s4; s4: state <= s1; s4: state <= s1; endcase endcase case (state) s1: outp <= 1'b1; s1: outp <= 1'b1; s2: outp <= 1'b1; s2: outp <= 1'b1; s3: outp <= 1'b0; s3: outp <= 1'b0; s4: outp <= 1'b0; s4: outp <= 1'b0; default: outp <= 1'b0; default: outp <= 1'b0; endcase endcase 23
Synthesis (see console output) Synthesizing Unit. Related source file is "v_fsm_2.v". Related source file is "v_fsm_2.v". Found finite state machine for signal. Found finite state machine for signal | States | 4 | | States | 4 | | Transitions | 5 | | Transitions | 5 | | Inputs | 1 | | Inputs | 1 | | Outputs | 1 | | Outputs | 1 | | Clock | clk (rising_edge) | | Clock | clk (rising_edge) | | Reset | reset (positive) | | Reset | reset (positive) | | Reset type | asynchronous | | Reset type | asynchronous | | Reset State | 00 | | Reset State | 00 | | Power Up State | 00 | | Power Up State | 00 | | Encoding | automatic | | Encoding | automatic | | Implementation | LUT | | Implementation | LUT | Summary: Summary: inferred 1 Finite State Machine(s). Unit synthesized. 24
Incorrect: Putting all in one always Using one always block generally incorrect! (But may work for Moore FSMs) generally incorrect! (But may work for Moore FSMs) ends up with unintended registers for outputs! ends up with unintended registers for outputs! clk) case (state) s1: if (x1 == 1'b1) begin state <= s2; outp <= 1'b1; end else begin state <= s3; outp <= 1'b0; end else begin state <= s3; outp <= 1'b0; end s2: begin state <= s4; outp <= 1'b1; end end s3: begin state <= s4; outp <= 1'b0; end end s4: begin state <= s1; outp <= 1'b0; end endendcase 25
Synthesis Output Synthesizing Unit. Related source file is "v_fsm_1.v". Related source file is "v_fsm_1.v". Found finite state machine for signal. Found finite state machine for signal | States | 4 | | States | 4 | | Transitions | 5 | | Transitions | 5 | | Inputs | 1 | | Inputs | 1 | | Outputs | 4 | | Outputs | 4 | | Clock | clk (rising_edge) | | Clock | clk (rising_edge) | | Reset | reset (positive) | | Reset | reset (positive) | | Reset type | asynchronous | | Reset type | asynchronous | | Reset State | 00 | | Reset State | 00 | | Power Up State | 00 | | Power Up State | 00 | | Encoding | automatic | | Encoding | automatic | | Implementation | LUT | | Implementation | LUT | Found 1-bit register for signal. Found 1-bit register for signal. Summary: Summary: inferred 1 Finite State Machine(s). inferred 1 D-type flip-flop(s). 26
Textbook Uses 3 always Blocks 27
Three always Blocks reg [1:0] state; reg [1:0] state; reg [1:0] next_state; reg [1:0] next_state; … … … clk) clk) if (RESET == 1) state <= s1; else state <= next_state; case (state) case (state) s1: if (x1==1'b1) s1: if (x1==1'b1) next_state <= s2; next_state <= s2; else else next_state <= s3; next_state <= s3; s2: next_state <= s4; s2: next_state <= s4; s3: next_state <= s4; s3: next_state <= s4; s4: next_state <= s1; s4: next_state <= s1; default: next_state <= s1; default: next_state <= s1; endcase endcase reg outp; ……… case (state) case (state) s1: outp <= 1'b1; s1: outp <= 1'b1; s2: outp <= 1'b1; s2: outp <= 1'b1; s3: outp <= 1'b0; s3: outp <= 1'b0; s4: outp <= 1'b0; s4: outp <= 1'b0; default: outp <= 1'b0; default: outp <= 1'b0; endcase endcase 28
Synthesis (again, no unintended latch) Synthesizing Unit. Related source file is "v_fsm_3.v". Related source file is "v_fsm_3.v". Found finite state machine for signal. Found finite state machine for signal | States | 4 | | States | 4 | | Transitions | 5 | | Transitions | 5 | | Inputs | 1 | | Inputs | 1 | | Outputs | 1 | | Outputs | 1 | | Clock | clk (rising_edge) | | Clock | clk (rising_edge) | | Reset | reset (positive) | | Reset | reset (positive) | | Reset type | asynchronous | | Reset type | asynchronous | | Reset State | 00 | | Reset State | 00 | | Power Up State | 00 | | Power Up State | 00 | | Encoding | automatic | | Encoding | automatic | | Implementation | LUT | | Implementation | LUT | Summary: Summary: inferred 1 Finite State Machine(s). Unit synthesized. 29
My Preference The one with 2 always blocks Less prone to error than 1 always Less prone to error than 1 always Easy to visualize the state transitions Easy to visualize the state transitions 3 always blocks is okay too 3 always blocks is okay too 30
Moore vs. Mealy FSMs? So, is there a practical difference? 31
Moore vs. Mealy Recognizer Mealy FSM: arcs indicate input/output
Moore and Mealy Timing Diagram
Moore vs. Mealy FSM Schematic Moore Mealy
Next class Solution to switch bounce problem Registers and counters (in depth) 35