/// Notes and Demos for LSU EE 4702-1 Spring 2001 // Form 3: Implicit State Machine // Sources: Ci: Ciletti, Modeling, synthesis, and rapid prototyping // with the Verilog HDL // Leo: Exemplar Logic (Mentor Graphics), // LeonardoSpectrum HDL Synthesis Manual, October 2000 /// Contents (Incomplete) // Form 3: Implicit State Machine // Form 3: Simple Example // State Encoding /// Form 3: Implicit State Machine /// Describes a state machine synchronized to clock. // "Implicit" refers to the lack of a declared state variable, // the synthesis program will add one for you. // The states are portions of code bounded by event controls, // usually @( posedge clk ). /// Basic Form // // always <clk-or-non-timing-statements>; // <clk-or-non-timing-statements> can include one kind of timing // statement: @( posedge clk ). (negedge can be used, clk can // be any signal.). // The timing statement must appear at least once on every cycle through // a non-constant or infinite loop. (See examples.) `ifdef NEVER module e1(); // Okay, timing control appears once: always @( posedge clk ) a = a + 1; always begin @( posedge clk ); a = a + 1; end always begin if( a1 ) @( posedge clk ) a = a + 1; else @( posedge clk ); // Okay, timing control appears twice: always @( posedge clk ) begin @( posedge clk ) a = a + 1; end always begin @( posedge clk ); @( posedge clk ) a = a + 1; end // NOT okay, timing control may appear zero times (if a1 false). always begin if( a1 ) @( posedge clk ) a = a + 1; end // Inference of Registers (Synthesis of assignment statements.) // // Registers synthesized for all assignments, edge triggered on clk. // // State register inferred, state corresponds to position in procedural // code. endmodule `endif /// Form 3: Simple Example `define SIMPLE `ifdef SIMPLE module sum(rdy,sum_a_to_b,a,b,start,clk); input [7:0] a, b; input start, clk; output sum_a_to_b; output rdy; reg [8:0] sum_a_to_b; reg busy; wire rdy = !busy; reg [7:0] i; // exemplar translate_off initial busy = 0; // exemplar translate_on always begin while( start !== 1 ) @( posedge clk ); sum_a_to_b = 0; busy = 1; for(i = a; i <= b; i = i + 1) @( posedge clk ) sum_a_to_b = sum_a_to_b + i; @( posedge clk ); busy = 0; end endmodule `endif // exemplar translate_off module testsum(); reg [7:0] a, b; reg start, clk; wire rdy; wire [8:0] sum_a_to_b; sum s(rdy,sum_a_to_b,a,b,start,clk); initial clk = 0; always #5 clk = !clk; initial begin start = 0; a = 0; b = 10; repeat( 5 ) @( clk ); wait( rdy ); start = 1; wait( !rdy ); start = 0; wait( rdy ); $display("Sum %d to %d is: %d", a, b, sum_a_to_b); a = 7; b = 23; wait( rdy ); start = 1; wait( !rdy ); start = 0; wait( rdy ); $display("Sum %d to %d is: %d", a, b, sum_a_to_b); $stop; end endmodule // exemplar translate_on /// State Encoding // // Specifying How Form 3-States are Coded // Synthesis program adds a state variable in Form 3. // Will automatically choose coding, or use one specified // by a synthesis directive: // exemplar encoding ENCODING // ENCODING: onehot, twohot, gray, binary, random, auto // Form 2 State machine. module state(); // In Form 2, designer can choose the coding, two alternatives // shown below. (Module does not do anything useful.) // Code should include only one of the parameter sets below. // States encoded in binary. parameter st_one = 3'd0, st_two = 3'd1, st_three = 3'd2; // States encoded one hot. parameter st_one = 5'b00001, st_two = 5'b00010, st_three = 5'b00100; reg [4:0] state; integer a, b; always @( posedge clk ) case( state ) st_one: begin a = a + 1; state <= st_two; end st_two: begin b = b + 1; state <= a ? st_one : st_two; end st_three: begin b = b + 2; state <= st_one; end // ... endcase endmodule // In Form 3 synthesis program adds state, so it chooses coding. // It can automatically select an appropriate coding, or use // one specified. // The synthesis program uses the line below to choose the coding // used for the states, in this case a one-hot scheme. // exemplar encoding onehot module state(); always @( posedge clk ) begin a = a + 1; @(posedge clk ); b = b + 1; @(posedge clk ); end endmodule