Subversion Repositories programming

Rev

Rev 206 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 206 Rev 207
Line -... Line 1...
-
 
1
/**
-
 
2
 * Copyright 2006, Ira W. Snyder (devel@irasnyder.com)
-
 
3
 * License: GNU General Public License v2 (or, at your option, any later
-
 
4
 * version)
-
 
5
 */
-
 
6
 
-
 
7
/**
-
 
8
 * Name: Ira Snyder
-
 
9
 * Class: CS365 - Computer Architecture
-
 
10
 * Project #1 - Part 2
-
 
11
 * Due: 2006-02-06
-
 
12
 */
-
 
13
 
-
 
14
/**
-
 
15
 * File: MUL4.v
-
 
16
 * Purpose: Implementation of a 4-bit multiplier.
-
 
17
 *
1
/* A 4-bit multiplier, following the algorithm from
18
 * A 4-bit multiplier, following the algorithm from
-
 
19
 * Pg. 179, Figure 3.7 of the book Computer Organization and Design by
2
 * Pg. 179, Figure 3.7. */
20
 * Patterson and Hennessey.
-
 
21
 */
3
 
22
 
-
 
23
// This controls the multiplication unit.
4
module MUL4_CONTROL (prod_in, alu_op, write_op, shift_op, clk, ctr);
24
module MUL4_CONTROL (prod_in, alu_op, write_op, shift_op, clk, ctr);
5
 
25
 
6
    input prod_in, clk;
26
    input prod_in, clk;
7
    input[0:3] ctr;
27
    input[0:3] ctr;
8
    output[0:1] alu_op;
28
    output[0:1] alu_op;
9
    output write_op, shift_op;
29
    output write_op, shift_op;
10
 
30
 
-
 
31
    // Only trigger at the negative edge of the clock. We should stay constant
-
 
32
    // in all other cases.
11
    always @(negedge clk) begin
33
    always @(negedge clk) begin
-
 
34
        // If we have a "low enough" counter, set the correct
-
 
35
        // operations based on the input of the last bit in the product
-
 
36
        // register.
-
 
37
        //
-
 
38
        // If the counter is out of range, then don't do anything, since we
-
 
39
        // want to give the hardware some time to accept new values, for the
-
 
40
        // next multiplication operation.
12
        if (ctr <= 4) begin
41
        if (ctr <= 4) begin
13
            force write_op = prod_in;
42
            force write_op = prod_in;
14
            force shift_op = 'b1;
43
            force shift_op = 'b1;
15
            force alu_op = 'b10;
44
            force alu_op = 'b10;
16
        end else begin
45
        end else begin
Line 20... Line 49...
20
        end
49
        end
21
    end
50
    end
22
 
51
 
23
endmodule
52
endmodule
24
 
53
 
-
 
54
// This stores the "right" mutiplying number until it changes.
25
module MUL4_MULTIPLICAND (in, out, clk);
55
module MUL4_MULTIPLICAND (in, out, clk);
26
 
56
 
27
    input[0:3] in;
57
    input[0:3] in;
28
    output[0:3] out;
58
    output[0:3] out;
29
    input clk;
59
    input clk;
30
 
60
 
31
    reg[0:3] value;
61
    reg[0:3] value;
32
 
62
 
-
 
63
    // Only change the value stored in this
-
 
64
    // register when the input changes.
33
    always @(in) begin
65
    always @(in) begin
34
        value = in;
66
        value = in;
35
    end
67
    end
36
 
68
 
37
    assign out = value;
69
    assign out = value;
38
 
70
 
39
endmodule
71
endmodule
40
 
72
 
-
 
73
// This stores the 8-bit product of the multiplication unit. It gets reset
-
 
74
// when it's right 4 bits change.
-
 
75
//
-
 
76
// It will write the value coming in on it's left4 input every negative edge
-
 
77
// of the clock, only if it is getting the write signal from the control unit.
-
 
78
// It will then shift the value if it is getting the shift operation from the
-
 
79
// control unit. Since we NEVER write without a shift, this implementation is
-
 
80
// safe.
41
module MUL4_PRODUCT (left4, right4, shift_op, write_op, out, clk);
81
module MUL4_PRODUCT (left4, right4, shift_op, write_op, out, clk);
42
 
82
 
43
    input[0:3] left4, right4;
83
    input[0:3] left4, right4;
44
    input shift_op, write_op, clk;
84
    input shift_op, write_op, clk;
45
    output[0:7] out;
85
    output[0:7] out;
46
 
86
 
-
 
87
    // Storage register
47
    reg[0:7] value;
88
    reg[0:7] value;
48
 
89
 
-
 
90
    // Reset the storage register whenever the leftmost multiplying number
-
 
91
    // changes.
49
    always @(right4) begin
92
    always @(right4) begin
50
        value[0:3] = 'b0000;
93
        value[0:3] = 'b0000;
51
        value[4:7] = right4;
94
        value[4:7] = right4;
52
    end
95
    end
53
 
96
 
-
 
97
    // Every time we get to the negative edge of the clock, we should check
-
 
98
    // and see if we need to WRITE + SHIFT, or just SHIFT, based on the
-
 
99
    // signals sent from the control unit.
54
    always @(negedge clk) begin
100
    always @(negedge clk) begin
55
        if (shift_op == 1) begin
101
        if (shift_op == 1) begin
56
            if (write_op == 1) begin
102
            if (write_op == 1) begin
-
 
103
 
-
 
104
                // Write the ALU's value into the left half of the register.
57
                value[0:3] = left4[0:3];
105
                value[0:3] = left4[0:3];
58
            end
106
            end
-
 
107
 
-
 
108
            // Shift the register, since we got a shift signal. This is here
59
            
109
            // to make sure that we write FIRST, then shift SECOND.
60
            value = value >> 1;
110
            value = value >> 1;
61
        end
111
        end
62
    end
112
    end
63
 
113
 
-
 
114
    // Set the output to the new value in the storage register.
64
    assign out = value;
115
    assign out = value;
65
 
116
 
66
endmodule
117
endmodule
67
 
118
 
68
module testme;
-
 
69
 
-
 
70
    reg[0:3] a, b;
-
 
71
    wire[0:7] w_out;
-
 
72
 
-
 
73
    MUL4 mult (a, b, w_out);
-
 
74
 
-
 
75
    initial begin
-
 
76
        $monitor ("time=%0d a=%b b=%b prod=%b", $time, a, b, w_out);
119
// The actual multiplier unit. It takes 10 "$time" units from when you give
77
    end
-
 
78
    
-
 
79
    initial begin
-
 
80
            a = 'b0011; b = 'b0011;
-
 
81
        #10 a = 'b0001; b = 'b1100;
-
 
82
        #10 a = 'b1100; b = 'b0011;
120
// the inputs until the output is set correctly.
83
        #10 a = 'b0101; b = 'b1010;
-
 
84
        #8
-
 
85
        #2 $finish;
-
 
86
    end
-
 
87
 
-
 
88
endmodule
-
 
89
 
-
 
90
module MUL4 (a, b, out);
121
module MUL4 (a, b, out);
91
 
122
 
92
    input[0:3] a, b;
123
    input[0:3] a, b;
93
    output[0:7] out;
124
    output[0:7] out;
94
 
125
 
95
    reg[0:3] counter;
126
    reg[0:3] counter;
96
    reg clk;
127
    reg clk;
97
 
128
 
-
 
129
    // Set initial variable values
98
    initial begin
130
    initial begin
99
        clk = 'b0;
131
        clk = 'b0;
100
        counter ='b0000;
132
        counter ='b0000;
101
        cin = 'b0;
133
        cin = 'b0;
102
    end
134
    end
103
 
135
 
-
 
136
    // Clock generator
104
    always begin
137
    always begin
105
        #1 clk = ~clk;
138
        #1 clk = ~clk;
106
    end
139
    end
107
 
140
 
-
 
141
    // Increment the counter at the negative edge of the clock
108
    always @(negedge clk) begin
142
    always @(negedge clk) begin
109
        counter = counter + 'b1;
143
        counter = counter + 'b1;
110
    end
144
    end
111
    
145
 
112
    /* //DEBUGGING INFORMATION
146
    /* //DEBUGGING INFORMATION
113
    initial begin
147
    initial begin
114
        $monitor ("time=%0d counter=%b clk=%b w_mout=%b w_prod=%b w_aop=%b w_sop=%b w_wop=%b out=%b",
148
        $monitor ("time=%0d counter=%b clk=%b w_mout=%b w_prod=%b w_aop=%b w_sop=%b w_wop=%b out=%b",
115
               $time, counter, clk, w_mout, w_prod, w_aop, w_sop, w_wop, out);
149
               $time, counter, clk, w_mout, w_prod, w_aop, w_sop, w_wop, out);
116
    end
150
    end
117
    */
151
    */
118
    
152
 
119
    wire[0:7] w_prod;
153
    wire[0:7] w_prod;
120
    wire[0:3] w_mout, w_alu_out;
154
    wire[0:3] w_mout, w_alu_out;
121
    wire[0:1] w_aop;
155
    wire[0:1] w_aop;
122
    wire w_sop, w_wop, w_cout;
156
    wire w_sop, w_wop, w_cout;
123
    reg cin;
157
    reg cin;
Line 131... Line 165...
131
    // Also reset the counter every time it reaches 4, it is used
165
    // Also reset the counter every time it reaches 4, it is used
132
    // to keep the MUL4_CONTROL in sync.
166
    // to keep the MUL4_CONTROL in sync.
133
    always @(counter) begin
167
    always @(counter) begin
134
        if (counter == 4) begin
168
        if (counter == 4) begin
135
            force out = w_prod; // set the output
169
            force out = w_prod; // set the output
136
            counter = 'b1111; // reset counter
170
            counter = 'b1111;   // reset counter
137
        end else begin
171
        end else begin
138
            release out;
172
            release out;
139
        end
173
        end
140
    end
174
    end
141
 
175