/// 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