```
`define SYN_SEQ

// Sample Questions for LSU EE 4702 Spring 2000 Final Exam

// Includes questions not covered in the 5 May class.

////////////////////////////////////////////////////////////////////////////////
// Problem 1:
// -----------------------------------------------------------------------------
// (a.1) Convert the behavior multiplier description to a synthesizable
// description that synthesizes into combinational logic.

`ifdef BEHAVIORAL_NON_SYN
module multiplier(product,a,b);
input a,b;
output product;

wire [15:0] a, b;
reg [31:0]  product, a_left;
reg [15:0]  b_right;

always @( a or b ) begin:MULT

a_left = {16'd0,a};
b_right = b;
product = 0;

forever begin
if( !b_right ) disable MULT;

if( b_right ) product = product + a_left;

a_left = a_left << 1;
b_right = b_right >> 1;

end

end

endmodule // multiplier
`endif // ifdef BEHAVIORAL_NON_SYN

//
// Solution to 1(a.1)
//

`ifdef SYN_COMB
module multiplier(product,a,b);
input a,b;
output product;

wire [15:0] a, b;
reg [31:0]  product, a_left;
reg [15:0]  b_right;
integer     i;

always @( a or b ) begin:MULT

a_left = {16'd0,a};
b_right = b;
product = 0;

for(i=0; i<16; i=i+1) begin

if( b_right ) product = product + a_left;

a_left = a_left << 1;
b_right = b_right >> 1;

end

end

endmodule // multiplier
`endif

// -----------------------------------------------------------------------------
// (a.2) Draw a schematic that will look something like the
// synthesized design.  Use basic components such as gates and
// multiplexors, you don't have to use the exact components chosen by
// the synthesis program.

//
// Solution to 1(a.2)
//

// Note. An actual solution would consist of a schematic.  A lengthy
// verbal description like the one below is not necessary, it is
// there to help study for the exam.

// Since the code is combinational separate "iteration" hardware
// things will be synthesized for each iteration of the loop.  The
// index (i) will not be synthesized since its value is constant
// within the hardware that represents an iteration.

// The inputs to an "iteration" hardware thing are "product", "a_left",
// and "b_right".  The outputs are new versions of  "product", "a_left",
// and "b_right";  the outputs go to the inputs of the next iteration
// hardware thing.  The inputs to the first iteration hardware thing
// are "a" and "b" (the module ports), and the constant "0" (for product).
// Output "product" of the last iteration hardware thing goes to the
// product output port of the module.  Outputs "a_left" and "b_right"
// are ignored.

// Each iteration consists of the following:

//   The line below

//     if( b_right ) product = product + a_left;

//   synthesizes into a multiplexor feeding an adder. One input to the mux
//   is "product + a_left" the other input is "product".  The control
//   input is b_right.

//   The lines below

//         a_left = a_left << 1;
//         b_right = b_right >> 1;

//   don't generate any logic. The most significant bit of a_left is
//   discarded and the constant zero is put in the least significant
//   position.  b_right is handled similarly.

// -----------------------------------------------------------------------------

// (b.1) Convert the behavioral multiplier description to a synthesizable
// description that uses a clock and that synthesizable into sequential
// logic. The area (number of gates) should be lower than part (a).

//
// Solution
//

`ifdef SYN_SEQ
module multiplier(product,a,b,clk);
input a,b, clk;
output product;

wire [15:0] a, b;
reg [31:0]  product, a_left, product_temp;
reg [15:0]  b_right;
integer     i;

// Note form 3, an implicit state machine is used.

always @( posedge clk ) begin

a_left = {16'd0,a};
b_right = b;
// Use a temp variable because it will take several cycles
// to update the output and we don't want intermediate results
// at the outputs.
product_temp = 0;

// Insert a posedge clk. Necessary for form 3.
begin:MULT_LOOP forever @( posedge clk ) begin

// Disable is allowable in form 3. (Though the output is
// updated sooner by using the disable, this isn't useful
// because there is no ready signal.  External circuitry
// must wait about 34 clock cycles. (With a start signal, would
// wait only 17 cycles.)

if( !b_right ) disable MULT_LOOP;

if( b_right ) product_temp = product_temp + a_left;

a_left = a_left << 1;
b_right = b_right >> 1;

end end

product = product_temp;

end // block: MULT

endmodule // multiplier
`endif

// -----------------------------------------------------------------------------

// (b.2) Draw a schematic that will look something like the
// synthesized design.  Use basic components such as gates,
// multiplexors, and flip-flops, you don't have to use the exact
// components chosen by the synthesis program.

//
// Solution
//

// Use one copy of the iteration hardware thing described in 1.a.2.
// Add registers for product_temp, product, a_left, and a_right.  Also
// add a register for the implicit state variable inferred by the
// synthesizer.

// The outputs of the iteration thing connect to the data inputs of
// the register a_left, a_right, and product_temp.
// Multiplexor are connected to the inputs of registers a_left, a_right;
// one input is from the output of the iteration hardware, the
// other is from the module ports.  The inputs of product_temp
// are connected to the iteration hardware output.

// The inputs of register product are connected to the outputs
// of product_temp.

//
// Another Study Question
//

// Create an explicit state machine representation of the multiplier.

// -----------------------------------------------------------------------------

// (c) First, suppose the synthesis program was not smart enough to
// figure out that the synthesizable descriptions were multipliers.
// Suppose that the implicit structural description is synthesizable
// (it is, by Leonardo) and that a combinational version will be
// synthesized.  How would the result compare to the synthesizable
// version from the previous part?

`ifdef IMPLICIT_STR
module multiplier(product,a,b);
input a,b;
output product;

wire [15:0] a, b;
wire [31:0] product = a * b;

endmodule // multiplier
`endif

//
// Solution
//

// The synthesis program would infer a multiplier. (A no-brainer
// in this case, since the multiply operator is used.) That
// would be mapped to a target-technology-optimized multiplier,
// that would probably be better than the hand coded versions.

// Note: the synthesis program can create sequential multipliers too.

////////////////////////////////////////////////////////////////////////////////
// Problem 2

// Why would many synthesis programs not synthesize this:

module t1(a,clk);
input clk;
output a;
reg    a;

always @( posedge clk ) begin
a = 1;
#1;
a = 0;
end

endmodule

// ... but would have no problem with

module t2(a,clk);
input clk;
output a;
reg    a;

always @( posedge clk ) begin
a = 1;
@( posedge clk );
a = 0;
end

endmodule // t

// Solution

// The first module requires the synthesis of hardware that can
// generate a 1 unit (default 1 nanosecond) delay.  Though this could
// be done in principle it would require alot of hardware so such a
// feature would rarely be used.  The delay in the second module
// is implemented by using an implicit state variable, just one bit.

////////////////////////////////////////////////////////////////////////////////
// Problem 3

// -----------------------------------------------------------------------------
// (a) Show examples of two case statements, one where the parallel_case
// directive is needed, and one where it's not.

// Solution

`ifdef DONTDEFINEME

// Needed:

// Possible values for op: 100, 010, 001

wire [2:0] op;

// Needed because the synthesizer doesn't know that if the middle bit
// is 1 the leftmost bit must be zero.  (It can't according to the
// comment, which IS PART OF THE SOLUTION.)

// exemplar parallel_case
casez(op)
3'b1??: a = 1;
3'b?1?: b = 1;
3'b??1: c = 1;
endcase // casez(op)

// Not Needed:

// Possible values for op: 00 01 10 11

wire [1:0] op;

case(op)
3'b00: foo;
3'b01: bar;
3'b10: foobar;
3'b11: snafu;
endcase // case(op)

`endif

// -----------------------------------------------------------------------------
// (b) How will the synthesized hardware be affected if parallel case
// is omitted where it should be used.

// Solution

// Using the solution as an example, if parallel case *is* used,
// the enable signal to register b (if thats what it is) is just
// based on op.  If parallel case is omitted, the enable
// signal must be (!op && op).

// exemplar translate_off
module test_mult();

wire [31:0] p;
reg [15:0]  a, b;
reg         clk;

multiplier m1(p,a,b,clk);

integer     i;

initial begin

clk = 0;

for(i=0; i<1000; i=i+1) begin

a = \$random; b = \$random;
a = a >> ( \$random & 15 );
b = b >> ( \$random & 15 );

#70;

if( a*b != p ) begin
\$display("Error: %d %d = %d",a,b,p);
\$stop;
end

end // for (i=0; i<1000; i=i+1)

\$stop;

end // initial begin

always #1 clk = ~clk;

endmodule // test_mult
// exemplar translate_on
```