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

Subversion Repositories hive

[/] [hive/] [trunk/] [v01.09/] [alu_mult_shift.v] - Blame information for rev 10

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 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) vector_sr.v (debug mode only)
15
- (3x) vector_sr.v
16
 
17
Notes:
18
- I/O optionally registered.
19
- 5 stage pipeline w/ 4 mid registers (not counting I/O registering).
20
- Shift left signed uses signed B to shift signed A left (B+) and right (B-).
21
- Shift left unsigned and B(0,+) gives 2^B (one-hot / power of 2).
22
- Shift left unsigned and B(-) gives unsigned A shift right.
23
- Shift takes precedence over multiply.
24
- Copy takes precedence over shift & multiply.
25
- Copy unsigned & signed unextended results s/b the same.
26
- Copy unsigned extended result s/b all zero.
27
- Copy signed extended result s/b all B sign.
28
- Debug mode for comparison to native signed multiplication, only use for
29
  simulation as it consumes resources and negatively impacts top speed.
30
 
31
--------------------------------------------------------------------------------
32
*/
33
 
34
module alu_mult_shift
35
        #(
36
        parameter       integer                                                 REGS_IN                 = 1,            // in register option
37
        parameter       integer                                                 REGS_OUT                        = 1,            // out register option
38
        parameter       integer                                                 DATA_W                  = 4,            // data width
39
        parameter       integer                                                 DEBUG_MODE              = 1             // 1=debug mode; 0=normal mode
40
        )
41
        (
42
        // clocks & resets
43
        input                   wire                                                            clk_i,                                          // clock
44
        input                   wire                                                            rst_i,                                          // async. reset, active high
45
        // control I/O
46
        input                   wire                                                            sgn_i,                                          // 1=signed
47
        input                   wire                                                            ext_i,                                          // 1=extended result
48
        input                   wire                                                            shl_i,                                          // 1=shift left
49
        input                   wire                                                            cpy_i,                                          // 1=copy b
50
        // data I/O
51
        input                   wire    [DATA_W-1:0]                     a_i,                                                    // operand
52
        input                   wire    [DATA_W-1:0]                     b_i,                                                    // operand
53
        output          wire    [DATA_W-1:0]                     result_o,                                       // result
54
        // debug
55
        output          wire                                                            debug_o                                         // 1=bad match
56
        );
57
 
58
 
59
        /*
60
        ----------------------
61
        -- internal signals --
62
        ----------------------
63
        */
64
        `include "functions.h"  // for clog2()
65
        localparam      integer                                                 SH_SEL_W                        = clog2( DATA_W );
66
        localparam      integer                                                 ZSX_W                           = DATA_W+1;  // +1 extra bit
67
        localparam      integer                                                 DBL_W                           = DATA_W*2;  // double width
68
        //
69
        wire                                    [DATA_W-1:0]                     a, b;
70
        wire                                                                                            cpy, shl, ext, sgn;
71
        reg                                     [DATA_W:0]                               a_mux, b_mux;  // +1 extra bit
72
        reg                                                                                             ext_mux;
73
        wire                                                                                            ext_mux_r;
74
        wire                                    [DBL_W-1:0]                              res_dbl;
75
        reg                                     [DATA_W-1:0]                     result;
76
 
77
 
78
        /*
79
        ================
80
        == code start ==
81
        ================
82
        */
83
 
84
 
85
        // optional input regs
86
        vector_sr
87
        #(
88
        .REGS                   ( REGS_IN ),
89
        .DATA_W         ( DATA_W+DATA_W+4 ),
90
        .RESET_VAL      ( 0 )
91
        )
92
        in_regs
93
        (
94
        .clk_i          ( clk_i ),
95
        .rst_i          ( rst_i ),
96
        .data_i         ( { a_i, b_i, cpy_i, shl_i, ext_i, sgn_i } ),
97
        .data_o         ( { a,   b,   cpy,   shl,   ext,   sgn } )
98
        );
99
 
100
 
101
        // mux inputs and extended result selector
102
        always @ ( * ) begin
103
                casex ( { cpy, shl, sgn } )
104
                        'b000 : begin  // unsigned multiply
105
                                a_mux <= a;  // zero extend
106
                                b_mux <= b;  // zero extend
107
                                ext_mux <= ext;  // follow input
108
                        end
109
                        'b001 : begin  // signed multiply
110
                                a_mux <= { a[DATA_W-1], a };  // sign extend
111
                                b_mux <= { b[DATA_W-1], b };  // sign extend
112
                                ext_mux <= ext;  // follow input
113
                        end
114
                        'b010 : begin  // unsigned shift / pow2
115
                                a_mux <= ( b[DATA_W-1] ) ? a : 1'b1;  // a=1 for positive shifts
116
                                b_mux <= 1'b1 << b[SH_SEL_W-1:0];  // pow2
117
                                ext_mux <= b[DATA_W-1];  // sign selects output
118
                        end
119
                        'b011 : begin  // signed shift
120
                                a_mux <= { a[DATA_W-1], a };  // sign extend
121
                                b_mux <= 1'b1 << b[SH_SEL_W-1:0];  // pow2
122
                                ext_mux <= b[DATA_W-1];  // sign selects output
123
                        end
124
                        'b1x0 : begin  // unsigned copy b
125
                                a_mux <= 1'b1;  // a=1
126
                                b_mux <= b;  // zero extend
127
                                ext_mux <= ext;  // follow input
128
                        end
129
                        'b1x1 : begin  // signed copy b
130
                                a_mux <= 1'b1;  // a=1
131
                                b_mux <= { b[DATA_W-1], b };  // sign extend
132
                                ext_mux <= ext;  // follow input
133
                        end
134
                endcase
135
        end
136
 
137
 
138
        // signed multiplier (4 registers deep)
139
        alu_multiply
140
        #(
141
        .DATA_W                 ( ZSX_W ),
142
        .DEBUG_MODE             ( DEBUG_MODE )
143
        )
144
        alu_multiply
145
        (
146
        .clk_i                  ( clk_i ),
147
        .rst_i                  ( rst_i ),
148
        .a_i                            ( a_mux ),
149
        .b_i                            ( b_mux ),
150
        .result_o               ( res_dbl ),
151
        .debug_o                        ( debug_o )
152
        );
153
 
154
 
155
        // pipeline extended result selector to match multiply
156
        vector_sr
157
        #(
158
        .REGS                   ( 4 ),
159
        .DATA_W         ( 1 ),
160
        .RESET_VAL      ( 0 )
161
        )
162
        regs_ext
163
        (
164
        .clk_i          ( clk_i ),
165
        .rst_i          ( rst_i ),
166
        .data_i         ( ext_mux ),
167
        .data_o         ( ext_mux_r )
168
        );
169
 
170
 
171
        // multiplex
172
        always @ ( * ) begin
173
                case ( ext_mux_r )
174
                        'b0 : result <= res_dbl[DATA_W-1:0];
175
                        'b1 : result <= res_dbl[DBL_W-1:DATA_W];
176
                endcase
177
        end
178
 
179
 
180
        // optional output regs
181
        vector_sr
182
        #(
183
        .REGS                   ( REGS_OUT ),
184
        .DATA_W         ( DATA_W ),
185
        .RESET_VAL      ( 0 )
186
        )
187
        out_regs
188
        (
189
        .clk_i          ( clk_i ),
190
        .rst_i          ( rst_i ),
191
        .data_i         ( result ),
192
        .data_o         ( result_o )
193
        );
194
 
195
 
196
endmodule

powered by: WebSVN 2.1.0

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