Subversion Repositories programming

Rev

Rev 198 | Rev 204 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/* A 4-bit multiplier, following the algorithm from
 * Pg. 179, Figure 3.7. */

module MUL4 (mul1, mul2, result, clk);
    input[0:3] mul1, mul2;
    output[0:7] result;
    input clk;

    wire[0:3] w_alu_out;
    wire[0:3] w_multiplicand;
    wire[0:7] w_product;

    wire[0:1] w_alu_op;
    wire w_write_op, w_shift_op;

    reg[0:3] count;

    MUL4_MULTIPLICAND m_mcand (mul1, w_multiplicand, clk);
    MUL4_PRODUCT m_prod (w_alu_out, mul2, w_shift_op, w_write_op, w_product, clk);
    MUL4_CONTROL m_ctrl (w_product[7], w_alu_op, w_write_op, w_shift_op, clk);
    ALU4 m_alu (w_product[0:3], w_multiplicand, cin, w_alu_op, cout, w_alu_out);

    always @(mul1 or mul2) begin
        count = 'b0000;
    end

    always @(clk) begin
        if (count == 4) begin
            $display ("set the result");
            force result = w_product;
        end
        count = count + 1;
    end

endmodule

module MUL4_2 (mul1, mul2, out);
    input[0:3] mul1, mul2;
    output[0:7] out;

    initial begin
        clk = 'b0;
    end

    always begin
        clk = ~clk;
    end

endmodule

module MUL4_CONTROL (prod_in, alu_op, write_op, shift_op, clk);

    input prod_in, clk;
    output[0:1] alu_op;
    output write_op, shift_op;

    reg[0:1] a_op;
    reg w_op, s_op;

    initial begin
        a_op = 'b00;
        w_op = 'b0;
        s_op = 'b0;
    end

    always @(clk) begin
        if (prod_in == 'b1)
            begin
                a_op = 'b10; // ADD
                w_op = 'b1;  // STORE
                s_op = 'b1;  // SHIFT
            end
        else
            begin
                a_op = 'b00; // AND, unnecessary
                w_op = 'b0;  // DO NOT WRITE
                s_op = 'b1;  // SHIFT
            end

    end //always

    assign alu_op = a_op;
    assign write_op = w_op;
    assign shift_op = s_op;

endmodule

module MUL4_MULTIPLICAND (in, out, clk);

    input[0:3] in;
    output[0:3] out;
    input clk;

    reg[0:3] value;

    always @(in) begin
        $display ("multiplicand changed");
        value = in;
    end

    assign out = value;

endmodule

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;

    reg[0:7] value;

    always @(right4) begin
        value[0:3] = 'b0000;
        value[4:7] = right4;
        $display ("right4 changed");
    end

    always @(clk) begin
        $display ("value=%b", value);
        if (shift_op == 1) begin
            $display ("shift 1");
            if (write_op == 1) begin
                $display ("write 1");
                value[0:3] = left4[0:3];
            end

            value = value >> 1;
        end
    end

    assign out = value;

endmodule

module testme;

    reg[0:3] a, b;
    wire[0:7] prod;

    initial begin
        $monitor ("time=%0d a=%b b=%b prod=%b", $time, a, b, prod);
    end

    initial begin
           clk = 'b0;
           a = 'b0000; b = 'b0000;
        #4 a = 'b0011; b = 'b1111;
        #4
        $finish;
    end

    reg clk;

    // Clock Generator
    always begin
        #1 clk = ~clk;
    end

    MUL4 m4 (a, b, prod, clk);

endmodule