OpenCores
URL https://opencores.org/ocsvn/hive/hive/trunk

Subversion Repositories hive

[/] [hive/] [trunk/] [v04.05/] [alu_mult_shift.v] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 ericw
/*
2
--------------------------------------------------------------------------------
3
 
4
Module : alu_mult_shift
5
 
6
--------------------------------------------------------------------------------
7
 
8
Function:
9
- Multiply & shift unit for a processor ALU.
10
 
11
Instantiates:
12
- functions.h (clog2)
13
- (1x) alu_multiply.v
14
  - (1x) pipe.v (debug mode only)
15
- (4x) pipe.v
16
 
17
Notes:
18
- I/O optionally registered.
19
- 5 stage pipeline w/ 4 mid registers (not counting I/O registering).
20
- (pow=0 & shl=0) gives unsigned (sgn=0) and signed (sgn=1) A*B.
21
- (pow=0 & shl=1) gives A unsigned (sgn=0) and A signed (sgn=1) A<<B.
22
- (pow=1 & shl=0) gives 1<<B (sign=x).
23
- (pow=1 & shl=1) and (B>=0) gives 1<<B, (B<0) gives A<<B (A signed & unsigned).
24
- Debug mode for comparison to native signed multiplication, only use for
25
  simulation as it consumes resources and negatively impacts top speed.
26
 
27
--------------------------------------------------------------------------------
28
*/
29
 
30
module alu_mult_shift
31
        #(
32
        parameter       integer                                                 REGS_IN                 = 1,            // in register option
33
        parameter       integer                                                 REGS_OUT                        = 1,            // out register option
34
        parameter       integer                                                 DATA_W                  = 32,           // data width
35
        parameter       integer                                                 DEBUG_MODE              = 0              // 1=debug mode; 0=normal mode
36
        )
37
        (
38
        // clocks & resets
39
        input                   wire                                                            clk_i,                                          // clock
40
        input                   wire                                                            rst_i,                                          // async. reset, active high
41
        // control I/O
42
        input                   wire                                                            sgn_i,                                          // 1=signed
43
        input                   wire                                                            ext_i,                                          // 1=extended result
44
        input                   wire                                                            shl_i,                                          // 1=shift left
45
        input                   wire                                                            pow_i,                                          // 1=power of 2
46
        // data I/O
47
        input                   wire    [DATA_W-1:0]                     a_i,                                                    // operand
48
        input                   wire    [DATA_W-1:0]                     b_i,                                                    // operand
49
        output          wire    [DATA_W-1:0]                     result_o,                                       // result
50
        // debug
51
        output          wire                                                            debug_o                                         // 1=bad match
52
        );
53
 
54
 
55
        /*
56
        ----------------------
57
        -- internal signals --
58
        ----------------------
59
        */
60
        `include "functions.h"  // for clog2()
61
        localparam      integer                                                 SH_SEL_W                        = clog2( DATA_W );
62
        localparam      integer                                                 ZSX_W                           = DATA_W+1;  // +1 extra bit
63
        localparam      integer                                                 DBL_W                           = DATA_W*2;  // double width
64
        //
65
        wire                                    [DATA_W-1:0]                     a, b;
66
        wire                                                                                            ext, pow, shl, sgn;
67
        wire                                                                                            b_neg;
68
        wire                                    [DATA_W-1:0]                     b_pow;
69
        wire                                    [ZSX_W-1:0]                              a_sex, b_sex;
70
        reg                                     [ZSX_W-1:0]                              a_mux, b_mux;
71
        reg                                                                                             ext_mux;
72
        wire                                                                                            ext_mux_r;
73
        wire                                    [DBL_W-1:0]                              res_dbl;
74
        reg                                     [DATA_W-1:0]                     result;
75
 
76
 
77
        /*
78
        ================
79
        == code start ==
80
        ================
81
        */
82
 
83
 
84
        // optional input data regs
85
        pipe
86
        #(
87
        .DEPTH          ( REGS_IN ),
88
        .WIDTH          ( DATA_W+DATA_W ),
89
        .RESET_VAL      ( 0 )
90
        )
91
        in_data_regs
92
        (
93
        .clk_i          ( clk_i ),
94
        .rst_i          ( rst_i ),
95
        .data_i         ( { b_i, a_i } ),
96
        .data_o         ( { b,   a   } )
97
        );
98
 
99
 
100
        // optional input control regs
101
        pipe
102
        #(
103
        .DEPTH          ( REGS_IN ),
104
        .WIDTH          ( 4 ),
105
        .RESET_VAL      ( 0 )
106
        )
107
        in_ctrl_regs
108
        (
109
        .clk_i          ( clk_i ),
110
        .rst_i          ( rst_i ),
111
        .data_i         ( { ext_i, pow_i, shl_i, sgn_i } ),
112
        .data_o         ( { ext,   pow,   shl,   sgn   } )
113
        );
114
 
115
 
116
        // some results pre-mux
117
        assign a_sex = { a[DATA_W-1], a };
118
        assign b_sex = { b[DATA_W-1], b };
119
        assign b_pow = 1'b1 << b[SH_SEL_W-1:0];
120
        assign b_neg = b[DATA_W-1];
121
 
122
 
123
        // mux inputs and extended result selector
124
        always @ ( * ) begin
125
                case ( { pow, shl, sgn } )
126
                        'b000 : begin  // unsigned multiply
127
                                a_mux <= a;
128
                                b_mux <= b;
129
                                ext_mux <= ext;
130
                        end
131
                        'b001 : begin  // signed multiply
132
                                a_mux <= a_sex;
133
                                b_mux <= b_sex;
134
                                ext_mux <= ext;
135
                        end
136
                        'b010 : begin  // unsigned shift
137
                                a_mux <= a;
138
                                b_mux <= b_pow;
139
                                ext_mux <= b_neg;
140
                        end
141
                        'b011 : begin  // signed shift
142
                                a_mux <= a_sex;
143
                                b_mux <= b_pow;
144
                                ext_mux <= b_neg;
145
                        end
146
                        'b100, 'b101 : begin  // pow (sign is don't care)
147
                                a_mux <= 1'b1;
148
                                b_mux <= b_pow;
149
                                ext_mux <= 1'b0;  // modulo rather than zero for negative shift values
150
                        end
151
                        'b110 : begin  // pow (0,+b) | unsigned shift (-b)
152
                                a_mux <= ( b_neg ) ? a : 1'b1;
153
                                b_mux <= b_pow;
154
                                ext_mux <= b_neg;
155
                        end
156
                        'b111 : begin  // pow (0,+b) | signed shift (-b)
157
                                a_mux <= ( b_neg ) ? a_sex : 1'b1;
158
                                b_mux <= b_pow;
159
                                ext_mux <= b_neg;
160
                        end
161
                endcase
162
        end
163
 
164
 
165
        // signed multiplier (4 registers deep)
166
        alu_multiply
167
        #(
168
        .DATA_W                 ( ZSX_W ),
169
        .DEBUG_MODE             ( DEBUG_MODE )
170
        )
171
        alu_multiply
172
        (
173
        .clk_i                  ( clk_i ),
174
        .rst_i                  ( rst_i ),
175
        .a_i                            ( a_mux ),
176
        .b_i                            ( b_mux ),
177
        .result_o               ( res_dbl ),
178
        .debug_o                        ( debug_o )
179
        );
180
 
181
 
182
        // pipeline extended result selector to match multiply
183
        pipe
184
        #(
185
        .DEPTH          ( 4 ),
186
        .WIDTH          ( 1 ),
187
        .RESET_VAL      ( 0 )
188
        )
189
        regs_ext
190
        (
191
        .clk_i          ( clk_i ),
192
        .rst_i          ( rst_i ),
193
        .data_i         ( ext_mux ),
194
        .data_o         ( ext_mux_r )
195
        );
196
 
197
 
198
        // multiplex
199
        always @ ( * ) begin
200
                case ( ext_mux_r )
201
                        'b1     : result <= res_dbl[DBL_W-1:DATA_W];
202
                        default : result <= res_dbl[DATA_W-1:0];
203
                endcase
204
        end
205
 
206
 
207
        // optional output regs
208
        pipe
209
        #(
210
        .DEPTH          ( REGS_OUT ),
211
        .WIDTH          ( DATA_W ),
212
        .RESET_VAL      ( 0 )
213
        )
214
        out_regs
215
        (
216
        .clk_i          ( clk_i ),
217
        .rst_i          ( rst_i ),
218
        .data_i         ( result ),
219
        .data_o         ( result_o )
220
        );
221
 
222
 
223
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.