/// LSU EE 3755 --Fall 2009-- Computer Organization

//

/// Verilog  Notes 12 -- Synthesis

// 

//  More illustrations of synthesized hardware.

 

/// Contents

//

//

//

// Synthesis of Procedural Code (Three Forms)

// Form 1 - Combinational Logic and Level-Triggered Reg

// Form 2 - Edge-Triggered Flip-Flops

// Synthesis of Forms 1 and 2 (Summary of Classes)

// Synthesis: Assignments Class, some FormEnd Class cases.

// Synthesis of Conditional Class (if/else)

// Synthesis of Conditional Class (case, if/else chains)

// Synthesis of Iteration Class (for, while, repeat)

 

/// References

//

// :P:   Palnitkar, "Verilog HDL"

// :Q:   Qualis, "Verilog HDL Quick Reference Card Revision 1.0"

// :PH:  Patterson & Hennessy, "Computer Organization & Design"

 

 

///////////////////////////////////////////////////////////////////////////

/// Synthesis of Procedural Code (Three Forms)

 

// :P: 14.3.3

 

 /// Synthesizable Definition

//

// A property of an HDL description indicating that a synthesis program

// will correctly synthesize it.  Whether a description is synthesizable

// depends upon the synthesis program used.

//

// Not all procedural code is synthesizable.

//

/// Note

//

// In these notes flip-flop and registers are used interchangeably.

// (A register is a collection of flip-flops meant to store data. A

// one-bit register is equivalent to a flip-flop as used here.)

 

 /// The Three Synthesizable Forms

//

// An always block is synthesizable if it is in one of three forms:

//

// Form 1

//   Synthesizes into combinational logic and level-triggered flip-flops.

//

// Form 2

//   Synthesizes into edge triggered flip flops.

//

// Form 3

//   Synthesizes into a state machine.

 

//

// The form applies to a procedural block starting with "always."

// A module can have any number of such blocks, each block can

// be in any form.

//

// Blocks starting with initial are not synthesizable.

 

 /// Synthesis of Forms 1 and 2

//

//

// See the Synthesis of Forms 1 and 2 section further below.

 

 

////////////////////////////////////////////////////////////////////////////////

/// Form 1 - Combinational Logic and Level-Triggered Reg

 

// Describes combinational logic and level-triggered flip-flops (latches)

 

// :Syntax:  always @( OBJ1 or OBJ2 or ... ) begin ST1; ST2; ... end

//

// OBJ1, OBJ2, etc are the names of nets or  names of variables; these are

// said to be in the /sensitivity list/.

//

// ST1, ST2, etc are statements that conform to the following rules:

//

//  Every net or variable appearing in an expression must be in the

//  sensitivity list unless that value is written by an earlier

//  statement(If this rule is not followed simulation will not

//  match synthesis; synthesizer program will give the wrong realization.).

//

//   ST1, ST2, etc. must not contain delays or event controls (#5,

//   @( a ), wait); sometimes not synthesizable or wrong result.

//       Example : wait

//             always

//                 wait(count_enable) #20 count = count +1; //it is waiting

                                             //for count_enable to become 1

                                             //when it becomes 1 ,

                                             //it will increment count

                                             //after 20 time units.

//

//  The number of iterations performed by looping constructs

//  must be determinable(known in advance) by the synthesis program

//  at analysis time (sort of like compile time);

//  otherwise it is not synthesizable.              

//          for ( i = 0; i <= 4 ; i = i +1)  // synthesizable.

//                c = 2;

//                a = c+1;;

//        for ( i = 0; i <= a ; i = i +1)// Not synthesizable ;

                                      //a is unknown at analysis time.

                                      // knowing "a" value requires

                                      // arithmetic operation, a = c+1;

 

 

//   System tasks ($display, etc.) are not allowed;

//    if included , the module is not synthesizable.

//

// :Example:

//

// An 8-bit adder in Form 1.

 

module sum_using_form_1(sum,a,b);

   input [7:0] a, b;

   output      sum;

   reg [8:0]   sum;

 

   // Code below executes each time a or b changes.

   // always @( OBJ1 or OBJ2 or ... ) -> always @( a or b )

   always @( a or b ) 

     begin

        sum = a + b;  // ST1

     end

endmodule

//See Fig.1

 

// :Example:

//

// Example of something which is almost Form 1.  Unlike the adder

// above, the output of the module will not change when b changes,

// at least according to the simulator. (Some synthesis programs

// incorrectly synthesize this.)

 

module sum_using_not_quite_form_1(sum,a,b);

   input [7:0] a, b;

   output      sum;

   reg [8:0]   sum;

 

   // Code below executes each time a changes.  This is close to

   // Form 1, but not the same. (Simulated and synthesized versions

   // will differ.)

   always @( a )

     begin

        sum = a + b;// b does not appear in the sensitivity list;

                    //so wrong result.

     end

 

   // Remember, code above is NOT Form 1

   // (nor any other synthesizable form).

 

endmodule

 

 

// :Example:

//

// A module for computing a complex product.

 

module complex_prod(xr,xi,ar,ai,br,bi);

   input [31:0] ar, ai, br, bi;

   output       xr, xi;

   reg [31:0]   xr, xi;

 

   // Temporary variables to hold products.

   reg [31:0]   p1, p2;

 

   always @( ar or ai or br or bi )

     begin

        xr = ar * br - ai * bi;

        p1 = ar * bi;

        p2 = ai * br;

        xi = p1 + p2; // p1,p2 are written by  earlier statements;

                      // although p1, p2 are not appearing in the

                      // sensitivity list, it is  Ok.

     end

 

endmodule

 

// See fig.2

 

////////////////////////////////////////////////////////////////////////////////

/// Form 2 - Edge-Triggered Flip-Flops

 

// Describes edge-triggered flip flops.

 

// The description below is a simplified version of Form 2.

 

// :Syntax:  always @( posedge CLK ) begin ST1; ST2; ... end

//

//

// ST1, ST2, etc are statements that conform to the following rules:

//

//   ST1, ST2, etc. must not contain delays or event controls (#5,

//   @( a ), wait);sometimes not synthesizable or wrong result.

 

//

//   Each variable can be assigned in only one always block.

//   The following is not synthesizable or gives wrong result.

//   Example :

 

// reg ab;

//      always(a)

//      begin

//          ab = c;

//      end

//            

//      always(c)

//      begin

//         ab = d;

//      end

//    because  varialbe ab is written in two always blocks.

//

//   The number of iterations performed by looping constructs

//   must be determinable (known in advance)

//   by the synthesis program at analysis time (sort of like compile time).

//   This will be explained further  when looping constructs are covered.

//   System tasks ($display, etc.) not allowed;

//   if included , the module is not synthesizable.

 

 

// :Example:

//

// Module describing an adder with a buffered output(we store the output).  // On the positive edge of clk output sum is set to a+b;

// that sum stays there until the next positive edge.

 

module sum_using_form_2(sum,a,b,clk);

   input [7:0] a, b;

   input       clk;

   output      sum;

   reg [7:0]   sum;

 

   // Code below executed each time clk changes to 1.

 

   always @( posedge clk )

     begin

        sum = a + b;   // ST1

     end

 

endmodule

 

// See Fig.3

 

// :Example:

//

// A module for computing a complex product.  The product

// is updated on the positive edge of the clock.

// buffered output(we store the output). 

 

module complex_prod_2(xr,xi,ar,ai,br,bi,clk);

   input [31:0] ar, ai, br, bi;

   input        clk;

   output       xr, xi;

   reg [31:0]   xr, xi;

 

   // Holds products.

   reg [31:0]   p1, p2;

 

   always @( posedge clk )

     begin

        xr = ar * br - ai * bi;

        p1 = ar * bi;

        p2 = ai * br;

        xi = p1 + p2;

     end

 

endmodule

 

// Same as Fig.2 except that we store xi and xr into Flip-Flops.

////////////////////////////////////////////////////////////////////////////////

/// Synthesis of Forms 1 and 2

 

// Synthesis

//

//   Synthesizable code will be decomposed into four classes,

//   each with its own simple synthesis rules.

//

//   The Classes:

//

//      Assignment:  

//      Conditional:  if/else and case.

//      Iterative:    for, while, repeat.

//      FormEnd:      Indicates the end of a procedural block.

//

//   Notation:

//

//       SStatement -> Assignment | Conditional | Iterative

//      (SStatement can refer to either Assignment, Conditional,

//         or Iterative.)

 

// Structure of Form 1 always Block:

//

//   :Syntax: always @( SLIST ) SStatement FormEnd

//   :Syntax: always @( SLIST ) begin SStatement SStatement ... end FormEnd

//

// See first example below.

 

// Structure of Form 2 always Block:

//

//   :Syntax: always @( posedge CLK ) SStatement FormEnd

//   :Syntax: always @( posedge CLK )

//               begin SStatement SStatement ... end FormEnd

 

 

// :Example:

//

// Module with comments indicating how the code is classified.

 

module syn_example_f1(x,y,a,b,c);

   input [7:0] a, b, c;

   output      x, y;

   reg [8:0]   x, y;

 

   // SLIST -> a or b or c

   always @( a or b or c )  // Form 1.

     begin

        x = a + b;          // SStatement -> Assignment -> x = a + b;

        y = x & c | b;      // SStatement -> Assignment -> y = x & c | b;

        x = b + 7;          // SStatement -> Assignment -> x = b + 7;

     end

   // FormEnd   There is no code here.

 

endmodule

// See Fig.4

 

 

 /// Classes

//

// For Each Class:

//

//  Hardware is synthesized.

//  The hardware emits(produces) updated values of variables.

//

// So, for each class we need to:

//

//  Determine what hardware is synthesized(adder,multiplexor,etc).

//  Determine which variables get updated values.

//

 

/// Summary of Classes

//

// Assignment

//

//  :Sample:  x = a + b;

//

//   Hardware:

//      Combinational logic for right-hand side (RHS) of assignment.

//      An adder for the sample above.

//   Updated Variable:

//      The assigned variable. Variable x in the sample above.

//

// Conditional

//

//  :Sample: if( a ) begin x = y; c = 5; end else begin c = z; end

//   Note: also includes case.

//  

//   Hardware:

//      One multiplexor for each updated variable, each input

//      from a different path (if, else).      

//   Updated Variables:

//      All variables modified in "if" or "else" parts.

//   See Fig.5.

//  

// Iterative

//

//  :Sample: for(i=0;i<5;i=i+1) begin s = s + a[i]; end

//   Note: also includes while, repeat.

//

//   Hardware:

//      Synthesize n copies of hardware corresponding to the loop body,

//      where n is the number of iterations.

//   Updated Variables:

//      All variables updated in last iteration.

//   See Fig.6.

// FormEnd

//

//   This one is important and is described in several places below.

//

//   Each variable may synthesize into a register, which means

//   a variable may NOT synthesize into a register.  This has

//   nothing to do with the declared type, since that should be

//   reg.

//   if a variable is updated always,

//   it is synthesized as wire,otherwise it is synthesized  as a reg.

//

//   Hardware: 

//      Form 1: Level-triggered registers (latches)

//              for some modified variables.

//      Form 2: Edge-triggered registers for some modified variables.

//   Updated Variables:

//      Those for which registers synthesized(outputs of registers).

 

 

////////////////////////////////////////////////////////////////////////////////

/// Synthesis: Assignments Class, some FormEnd Class cases.

 

 /// Assignment Class

//

// :Sample: sum = a + b;

//

// Hardware:

//

//   Combinational logic corresponding to

//   RHS(the RHS requires an adder the output of

//   which will be assigned to the variable at the LHS).

//

// Updated Variable

//

//   Variable on LHS(which is sum).

 

 

/// FormEnd Class -- Form 1, No Conditional Code

//

// Hardware:

//

//   None.

//

// Updated Variables.

//

//   None, since there is no hardware.

 

 /// FormEnd Class -- Form 2, No Conditional Code

//

// Hardware:

//

//   For each variable assigned(sum) in the always block an edge-triggered

//   flip-flop is synthesized. The latest value connects to the data

//   (d) input (a+b) and CLK connects to the clock input.

//   The q output is the variable sum.

//   The q output(sum) is the value used by all non-procedural code

//   and the first statement of all procedural code.

//

// Updated Variables:

//

//   One for each flip-flop output(sum).

//   See Fig.3 again and module sum_using_form_2(sum,a,b,clk);

 

// :Example:

//

// Module showing how its code is classified by structure above.

 

module syn_example2_f1(z,x,y,a,b,c);

   input [7:0] a, b, c;

   output      x, y, z;

   reg [8:0]   x, y;

   wire [8:0]  z;

 

   assign      z = x + 5;

 

   always @( a or b or c )

     begin

        x = a + b;       // HW: adder.       Updated Variable: x

        y = x & c | b;   // HW: AND and OR.  Updated Variable: y.

        x = b + 7;       // HW: adder.       Updated Variable: x

     end

   // FormEnd:   Nothing synthesized(No hardware).

 

endmodule

//similar to Fig.4.

 

// :Example:

//

// Module showing how its code is classified by structure above.

 

module syn_example2_f2(z,x,y,a,b,c,clk);

   input [7:0] a, b, c;

   input       clk;

   output      x, y, z;

   reg [8:0]   x, y;

   wire [8:0]  z;

 

   assign      z = x + 5;

 

   always @( posedge clk )

     begin

        x = a + b;       // HW: adder.       Updated Variable: x

        y = x & c | b;   // HW: AND and OR.  Updated Variable: y.

        x = b + 7;       // HW: adder.       Updated Variable: x

     end

   // FormEnd:   Edge-triggered FF for y and x.

 

endmodule

//similar to Fig.4.except we store x and y into Flip-Flops.

//We also need an adder for x+5;

 

////////////////////////////////////////////////////////////////////////////////

/// Syntax of if else(covered before)

 

// :Syntax: if( EXPR ) STATEMENT;

// :Syntax: if( EXPR ) STATEMENT1; else STATEMENT2

 

// :Example:

//

// Example of if/else. 

// This module is not synthesizable because it contains initial statement.

//

//

module if_not_syn_examples();

   integer a, b, c,x;

 

   initial

     begin

 

       if( a < b ) c = 1;

             

       if( a < b )

          begin

             c = 3;

             x = 5;

          end

       else

          begin

             c = 7;

             x = 2;

          end

   

     end

endmodule

 

 

////////////////////////////////////////////////////////////////////////////////

/// Synthesis of Conditional Class (if/else)

 

 /// Conditional - if / else

//

//:Syntax: if( COND ) IFPART

//:Syntax: if( COND ) IFPART else ELSEPART;

//

// Hardware:

//

//   Synthesize hardware for IFPART and ELSEPART.

//

//   Synthesize hardware to evaluate COND, call the output cond.

//

//   Determine the union of variables modified in IFPART and

//     ELSEPART(taking all variables from if and else part).

//   For each variable in the union:

//

//   Synthesize a two-input multiplexor.

//

//  

//      Connect one input to the latest value in IFPART, or if the

//      variable isn't updated in IFPART, the latest value before the

//      "if". 

//

//      Connect the other input to the latest value in ELSEPART, or if

//      the variable isn't updated in ELSEPART, the latest value

//      before the "if".

//

//      Connect cond to the control input.

//

//      The multiplexor output is the updated value.

//

//      A multiplexor might be eliminated in an optimization step,

//      see FormEnd below.

//

// Updated Values

//

//   All variables modified in "if" or "else" parts.

 

 /// FormEnd Class Form 1, Conditional

//   (The synthesis program will decide whether to put a latch

//     or not here.)

//   (FormEnd is not an explicit code; it is only for synthesis program.)

// Updated Variables

//

//    Those which may be unchanged due to an if

//    or case condition(appearing only in either if part or else part).

//    (Such as y in the example below; module cond_form_1_example2.)

//

// Hardware

//

//    For each possibly unchanged variable:

//

//       A level-triggered flip-flop (latch).

//

//       Condition(cond) is the clock(or enable)  to the flip-flop input

//

//       The latest value connects to the data (d) input.

//

// Optimization

//

//    In many cases multiplexors can be eliminated. (See y in

//    the example below.)

 

 

 /// FormEnd Class Form 2, Conditional

//

// Updated Variables

//

//    All assigned(updated) variables.

//

// Hardware

//

//    For each variable:

//

//       An edge-triggered flip-flop.

//

//       CLK (see Form 2 syntax) connects to the clock input.

//

//       Logic that determines whether the variable will change(update),

//       that logic connects to the flip-flop enable input

//        (enable is conditon or cond). 

//       The latest value connects to the data (d) input. 

 

 

// :Example:

//

// Very simple module to illustrate synthesis of if statement

// in Form 1 code.

 

module cond_form_1_example1(x,a,b,c);

   input a, b,c;

   output x;

   reg    x;

 

   always @( a or b or c )

     begin

      // x = 5;  latch does not work;  Mux always works.

        if( a ) x = b | c;  // SStatement1

     end

   // FormEnd

// See Fig.7.

//

endmodule

// Here is how the module above should

// be parsed(explained in detailed steps):

// SStatement1 -> Conditional -> if( COND ) IFPART

//   COND -> a

//   IFPART -> x = b | c;

//

 

 

// :Example:

//

// Simple module to illustrate synthesis of if/else statements in

// Form 1 code.

// Level-Triggered Registers: y, enabled by a.

 

module cond_form_1_example2(x,y,a,b,c);

   input a,b,c;

   output x,y;

   wire [7:0] b, c;

   reg [8:0]  x, y;

 

   always @( a or b or c ) begin

      if( a ) begin

         x = b + c;

         y = b - c;

      end else begin

         x = b - c;

      end

   end

endmodule

//See fig.8.

 

 

 

// :Example:

//

// Simple module to illustrate synthesis of if/else statements in

// Form 2 code.

// Edge-Triggered Registers: x and y.

// The hardware for module below will consist of two multiplexors

// one for x and  one for y(before optimization; after optimization,

// the multiplexor will be replaced with a flip-flop with

// enable signal(a)).

// and two edge triggered flip flops(registers);

// the register for y has enable signal(a) and d input(b-c);

// the register for x does not have enable input and d input which is

// output of a multiplexor.

 

module cond_form_2_example2(x,y,a,b,c,clk);

   input a,b,c;

   input clk;

   output x,y;

   wire [7:0] b, c;

   reg [8:0]  x, y;

 

   always @( posedge clk )

     begin

        if( a ) begin

           x = b + c;

           y = b - c;

        end

        else begin

           x = b - c;

          end

     end

endmodule

 

// See Fig.9.

// :Example:

//

// Example of an if/else if/else chain.

// Registers: None. (x assigned on all paths.)

//

 

module anotherif(x,a);

   input [7:0] a;

   output      x;

   reg [7:0]   x;

 

   always @( a )

     begin

 

        if( a < 10 )

          x = 1;   // IFPART1

        else

          // ELSEPART1

          if ( a < 50 )

            x = 2;  // IFPART2

          else

            // ELSEPART2

            if ( a < 200 ) x = 3;

            else x = 4;

       

     end

 

endmodule

 

// See Fig.10.

// :Example:

//

// Example of an if/else if/else chain.

// Level-Triggered Registers: x.

//

//

module yetanotherif(x,a);

   input [7:0] a;

   output      x;

   reg [7:0]   x;

 

   always @( a )

     begin

 

        if( a & 2 ) x = 6;

 

        if( a < 10 ) x = 1;

        else if ( a < 50 ) x = 2;

       

     end

 

endmodule

// in the  above example if a = 65, a&2 is false, a< 10 is false,

// a < 50 false so x is never updated. We need a latch.

// See Fig.11.

 

 

// :Example:

//

// An example with lots of if's.

// Registers: None. (x is always updated.)

 

module andyetanotherif(x,a);

   input [7:0] a;

   output      x;

   reg [7:0]   x;

 

   always @( a )

     begin

       

        x = a;

 

        if( a[0] )

          begin

             x = x + 2;

             if( a[1] & a[2] ) x = x + 1;

          end

        else

          begin

             if( a[3] ^ a[4] ) x = x + ( a >> 1 ); else x = x + ( a << 1 );

             x = 3 * x;

          end

 

        if( x[7] ) x = x - 1;

 

     end

 

endmodule

 

//See Fig.12.

 

// :Example:

//

// Another ALU.

// Registers: None

 

module form1_alu(result,a,b,op);

   input [31:0] a, b;

   input        op;

   output       result;

   reg [31:0]   result;

 

   always @( a or b or op )

     begin

        if(op) result = a + b; else result = a - b;

     end

 

endmodule

 

 

// :Example:

//

// An ALU with an overflow output.

// Registers: None.

 

module form1_alu_with_overflow(result,overflow,a,b,op);

   input [31:0] a, b;

   input        op;

   output       result;

   output        overflow;

   reg           overflow;

   reg [31:0]    result;

 

   always @( a or b or op )

     begin

        if( op ) result = a + b; else result = a - b;

        overflow = a[31] == b[31] && a[31] != result[31];

     end

 

endmodule

 

//See Fig.13.

////////////////////////////////////////////////////////////////////////////////

 

////////////////////////////////////////////////////////////////////////////////

/// Synthesis of Conditional Class (case, if/else chains)

 

 /// Conditional - if/else chains and case.

//

// General Conditions: (See also Sequential Conditions)

//

// :Syntax: if( C1 ) ST1;

//          else if ( C2 ) ST2;

//          else if ( C3 ) ST3;

//          ...

//          else STD;        // Optional

//

// :Syntax: case ( EXPR )

//             CEXP1:ST1;  

//             CEXP2:ST2;  

//             CEXP3:ST3;  

//             ...

//             default:STD;  // Optional

//          endcase

//

// Hardware:

//

//   Synthesize hardware for ST1, ST2, ..., STD

//

//   Synthesize hardware to evaluate either:

//       C1, C2, ...;  call respective outputs c1,

//       c2,...(We called them "cond" before)

//       EXPR == CEXP1, EXPR == CEXP2, ...

//        call respective outputs c1, c2,...

//      

//   Determine the union of variables(taking all variables)

//        modified in ST1, ST2, ..., STD

//   For each variable in the union:

//

//      Synthesize a selector with one input per STx.

//

//      For each STx:

//         Connect the latest value of the variable in STx to a

//         selector input, or if the variable isn't updated in STx,

//         the latest value before the "case" or "if".

//

//         Connect cx to the corresponding control input.

//

//      The selector output is the updated value.

//

//

// Sequential Conditions:

//

// :Syntax: if( EXPR == 0 ) ST0;

//          else if ( EXPR == 1 ) ST1;

//          else if ( EXPR == 2 ) ST2;

//          ...

//

// :Syntax: case ( EXPR )

//             0:ST0;

//             1:ST1;  

//             2:ST2;  

//             ...

//          endcase

//

// Hardware:

//

//   Synthesize hardware for ST0, ST1, ...

//

//   Synthesize hardware to evaluate EXPR, call the output expr.

//      

//   Determine the union of variables modified in ST0, ST1, ...

//   For each variable in the union:

//

//      Synthesize a multiplexor with one input per STx.

//

//      Connect expr to the control input.

//

//      For each STx:

//         Connect the latest value of the variable in STx to a

//         multiplexor input, or if the variable isn't updated in STx,

//         the latest value before the "case" or "if".

//

//      The multiplexor output is the updated value.

//

 /// More Information

//

// The synthesis program may be smart enough to use a multiplexor

// instead of a selector.

// Multiplexor is simpler than selector.

 

// :Example:

//

// An up/down counter.

// This fall under "General Conditions" above.

// Edge-triggered registers: count.

//

module up_down_counter(count,up,reset,clk);

   input up, reset, clk;

   output count;

   reg [7:0] count;

 

   always @( posedge clk )

     begin

 

        if( reset ) count = 0;

        else if( up ) count = count + 1;

        else count = count - 1;

       

     end

 

endmodule

 

//See Fig.14.

 

// :Example:

//

// A mux, the hard way, but look at how the if/else chain works.

// Because the if conditions check for consecutive constants (0,1,2)

// instead of using three two-input mux, the synthesis

// program uses one four-input multiplexor.

// This falls under "Sequential Conditions" above.

// Registers: None.

 

module mux(x,select,i0,i1,i2,i3);

   input [1:0] select;

   input [7:0] i0, i1, i2, i3;

   output      x;

   reg [7:0]   x;

 

   always @( select or i0 or i1 or i2 or i3 )

     begin

 

        if( select == 0 ) x = i0;

        else if( select == 1 ) x = i1;

        else if( select == 2 ) x = i2;

        else x = i3;

 

     end

 

endmodule

 

//See Fig.15.

//

// :Example:

//

// It looks like a selector but it's not.  The synthesized hardware

// will make use of a selector, but the entire module is not a

// selector.  How is it not a selector?

 

module not_exactly_a_selector(x,c0,c1,c2,c3,i0,i1,i2,i3);

   input c0, c1, c2, c3;

   input [7:0] i0, i1, i2, i3;

   output      x;

   reg  [7:0]  x;

 

   always @( c0 or c1 or c2 or c3 or i0 or i1 or i2 or i3 )

     begin

 

        case( 1 )

          c0: x = i0;

          c1: x = i1;

          c2: x = i2;

          c3: x = i3;

        endcase

       

     end

  

endmodule

 

// Variable x is not always assigned, so the selector output

// goes to a level-triggered flip-flop.  When none of the

// control inputs are set the module output(x)

// remains at old value.

//

// Level-Triggered Register: x

// See Fig.16.

 

 

////////////////////////////////////////////////////////////////////////////////

/// Synthesis of Iteration Class (for, while, repeat)

 

 /// Iteration - for, while, repeat

//

//  :Syntax: for( INIT_ASSIGN; CONDITION; STEP_ASSIGN ) BODY

//  :Syntax: while( CONDITION ) BODY

//  :Syntax: repeat( COUNT ) BODY

//

// Remember

//

//   The number of iterations must be determinable(known in advance)

//   by the synthesis program  at analysis time(sort of synthesis

//   or compile; when the synthesis program reads the verilog code,

//   it should know the number of iterations without performing

//   any computation).

//

// Hardware:

//

//    Let n denote number of iterations.

//

//    Synthesize and cascade (connect in series) n copies of BODY.

//

//    For a "for" loop, determine value of iteration variable (e.g., i)

//    at each iteration, and use that as an input into the hardware

//    for the corresponding iteration.

//

// Updated Variables:

//

//    Variables updated in the last iteration.

 

 

// :Example:

//

// Simple repeat example.

 

module times_five(five_a,a);

   input [7:0] a;

   output [10:0] five_a;

 

   reg [10:0]    five_a;

 

   always @( a ) begin

 

      five_a = 0;

 

      repeat( 5 ) five_a = five_a + a;

 

   end

 

endmodule

 

// See Fig.17.

//

// :Example:

//

// Simple for example.

 

module add_mult(sum,a);

   input [7:0] a;

   output sum;

   reg [15:0] sum;

   integer       i;

 

   always @( a ) begin

      sum = a;

 

      for(i = 0;  i < 5;  i = i + 1 ) sum = a + sum * i;

 

   end

 

endmodule

//See Fig.18.

 

// :Example:

//

// Simple for example.

 

module times_five_f(five_a,a);

   input [7:0] a;

   output [10:0] five_a;

 

   reg [10:0]    five_a;

   integer       i;

 

   always @( a ) begin

      five_a = 0;

 

      for(i = 0;  i < 5;  i = i + 1 ) five_a = five_a + a;

 

   end

 

endmodule

//

// Note: synthesized hardware identical to version with repeat loop.

// Same as Fig.17.

 

// :Example:

//

// population count module.

module pop_combinational_syn(p,a);

   input [4:0] a;

   output      p;

  

   reg [2:0]   p;

  

   integer     i; 

 

   // Form 1

   always @( a )

    begin

     // ST1 -> Assignment -> p = 0;

     p = 0;

     // ST2 -> Iteration -> for( INIT_ASSIGN; CONDITION; STEP_ASSIGN ) BODY

     // INIT_ASSIGN -> i=0

     // CONDITION -> i<5

     // STEP_ASSIGN -> i=i+1

     // BODY -> p=p+a[i];

     for(i=0; i<5; i=i+1) p = p + a[i];

    end

   // FormEnd

   //   A register is not needed for p because it's always assigned.

   //   We need a wire for p.

   //   A register is not needed for i because

   //   it is not referenced elsewhere(kind like an

   //   internal variable; used inside for loop).

 

  

endmodule

 

// Note:

//

//   Make five copies of body, p = p + a[i];  (an adder).

//   In first copy set i -> 0, in second set i -> 1, etc.

//   See Fig.19.

 

 

// :Example:

//

// A comparison module.  Output lt is asserted if a < b

// and gt is asserted if a > b.

 

module compare(gt, lt, a, b);

   input a, b;

   output gt, lt;

   wire [2:0] a, b;

   reg        gt, lt;

   integer    i;

 

   always @( a or b ) begin

      gt = 0; lt = 0;

      for(i=2; i>=0; i=i-1)

        if( !gt && !lt ) begin

           if( a[i] < b[i] ) lt = 1;

           if( a[i] > b[i] ) gt = 1;

        end

   end

 

endmodule // compare

// See Fig.20.

 

// :Example:

//

// Non-synthesizable loop.  The loop cannot be synthesized because the

// number of iterations in not a constant (not known in advance;

//  it depends on the module input, a). 

// For this particular case one could set the sum to

// a(a+1)/2(if your intention is just adding numbers starting from 0 to a;

// 0 + 1+ 2 +  ...+ a = a(a+1)/2; don't use loop,

// just use simple equation; save time).

 

module not_synthesizable_sum(sum,a);

   input [7:0] a;

   output [10:0] sum;

 

   reg [10:0]    sum;

 

   integer       i;

  

   always @( a ) begin

 

      sum = 0;

 

      for(i=0; i<=a; i=i+1) sum = sum + i;

 

   end

  

endmodule

//

 

// :Example:

//

// The code below is synthesizable but requires 256 copies of the loop

// body and so is probably impractical.  Computing a(a+1)/2 is much

// easier; 0 + 1+ 2 +  ...+ a = a(a+1)/2;

 

module synthesizable_sum_but_impractical(sum,a);

   input [7:0] a;

   output [10:0] sum;

 

   reg [10:0]    sum;

 

   integer       i;

 

   always @( a ) begin

 

      sum = 0;

 

      for(i=0; i<256; i=i+1) if( i <= a ) sum = sum + i;

 

   end

  

endmodule

//