Rev 206 | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*** Copyright 2006, Ira W. Snyder (devel@irasnyder.com)* License: GNU General Public License v2 (or, at your option, any later* version)*//*** Name: Ira Snyder* Class: CS365 - Computer Architecture* Project #1 - Part 2* Due: 2006-02-06*//*** File: MUL4.v* Purpose: Implementation of a 4-bit multiplier.** A 4-bit multiplier, following the algorithm from* Pg. 179, Figure 3.7 of the book Computer Organization and Design by* Patterson and Hennessey.*/// This controls the multiplication unit.module MUL4_CONTROL (prod_in, alu_op, write_op, shift_op, clk, ctr);input prod_in, clk;input[0:3] ctr;output[0:1] alu_op;output write_op, shift_op;// Only trigger at the negative edge of the clock. We should stay constant// in all other cases.always @(negedge clk) begin// If we have a "low enough" counter, set the correct// operations based on the input of the last bit in the product// register.//// If the counter is out of range, then don't do anything, since we// want to give the hardware some time to accept new values, for the// next multiplication operation.if (ctr <= 4) beginforce write_op = prod_in;force shift_op = 'b1;force alu_op = 'b10;end else beginrelease write_op;release shift_op;release alu_op;endendendmodule// This stores the "right" mutiplying number until it changes.module MUL4_MULTIPLICAND (in, out, clk);input[0:3] in;output[0:3] out;input clk;reg[0:3] value;// Only change the value stored in this// register when the input changes.always @(in) beginvalue = in;endassign out = value;endmodule// This stores the 8-bit product of the multiplication unit. It gets reset// when it's right 4 bits change.//// It will write the value coming in on it's left4 input every negative edge// of the clock, only if it is getting the write signal from the control unit.// It will then shift the value if it is getting the shift operation from the// control unit. Since we NEVER write without a shift, this implementation is// safe.module MUL4_PRODUCT (left4, right4, shift_op, write_op, out, clk);input[0:3] left4, right4;input shift_op, write_op, clk;output[0:7] out;// Storage registerreg[0:7] value;// Reset the storage register whenever the leftmost multiplying number// changes.always @(right4) beginvalue[0:3] = 'b0000;value[4:7] = right4;end// Every time we get to the negative edge of the clock, we should check// and see if we need to WRITE + SHIFT, or just SHIFT, based on the// signals sent from the control unit.always @(negedge clk) beginif (shift_op == 1) beginif (write_op == 1) begin// Write the ALU's value into the left half of the register.value[0:3] = left4[0:3];end// Shift the register, since we got a shift signal. This is here// to make sure that we write FIRST, then shift SECOND.value = value >> 1;endend// Set the output to the new value in the storage register.assign out = value;endmodule// The actual multiplier unit. It takes 10 "$time" units from when you give// the inputs until the output is set correctly.module MUL4 (a, b, out);input[0:3] a, b;output[0:7] out;reg[0:3] counter;reg clk;// Set initial variable valuesinitial beginclk = 'b0;counter ='b0000;cin = 'b0;end// Clock generatoralways begin#1 clk = ~clk;end// Increment the counter at the negative edge of the clockalways @(negedge clk) begincounter = counter + 'b1;end/* //DEBUGGING INFORMATIONinitial begin$monitor ("time=%0d counter=%b clk=%b w_mout=%b w_prod=%b w_aop=%b w_sop=%b w_wop=%b out=%b",$time, counter, clk, w_mout, w_prod, w_aop, w_sop, w_wop, out);end*/wire[0:7] w_prod;wire[0:3] w_mout, w_alu_out;wire[0:1] w_aop;wire w_sop, w_wop, w_cout;reg cin;MUL4_PRODUCT mp (w_alu_out, a, w_sop, w_wop, w_prod, clk);MUL4_MULTIPLICAND mm (b, w_mout, clk);MUL4_CONTROL mc (w_prod[7], w_aop, w_wop, w_sop, clk, counter);ALU4 ma (w_prod[0:3], w_mout, cin, w_aop, w_cout, w_alu_out);// Set the output, since we have a valid result right now.// Also reset the counter every time it reaches 4, it is used// to keep the MUL4_CONTROL in sync.always @(counter) beginif (counter == 4) beginforce out = w_prod; // set the outputcounter = 'b1111; // reset counterend else beginrelease out;endendendmodule