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

Subversion Repositories hive

[/] [hive/] [trunk/] [v01.10/] [alu_multiply.v] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 ericw
/*
2
--------------------------------------------------------------------------------
3
 
4
Module : alu_multiply
5
 
6
--------------------------------------------------------------------------------
7
 
8
Function:
9
- Signed multiply unit for a processor ALU.
10
 
11
Instantiates:
12
- (1x) vector_sr.v (debug mode only)
13
 
14
Notes:
15
- 3 stage 4 register pipeline.
16
- Multiply stage I/O registers are likely free (part of multiplier fabric).
17
- Debug mode for comparison to native signed multiplication, only use for
18
  simulation / verification as it consumes resources and negatively impacts
19
  top speed.
20
 
21
--------------------------------------------------------------------------------
22
*/
23
 
24
module alu_multiply
25
        #(
26
        parameter       integer                                                 DATA_W                  = 33,           // data width
27
        parameter       integer                                                 DEBUG_MODE              = 1             // 1=debug mode; 0=normal mode
28
        )
29
        (
30
        // clocks & resets
31
        input                   wire                                                            clk_i,                                          // clock
32
        input                   wire                                                            rst_i,                                          // async. reset, active high
33
        // data I/O
34
        input                   wire    [DATA_W-1:0]                     a_i,                                                    // operand
35
        input                   wire    [DATA_W-1:0]                     b_i,                                                    // operand
36
        output          reg     [DATA_W*2-1:0]                   result_o,                                       // = ( a_i * b_i )
37
        // debug
38
        output          wire                                                            debug_o                                         // 1=bad match
39
        );
40
 
41
 
42
        /*
43
        ----------------------
44
        -- internal signals --
45
        ----------------------
46
        */
47
        localparam      integer                                                 HI_W                            = DATA_W/2;             // 16
48
        localparam      integer                                                 LO_W                            = DATA_W-HI_W;  // 17
49
        localparam      integer                                                 MULT_W                  = LO_W*2;               // 34
50
        localparam      integer                                                 DBL_W                           = DATA_W*2;             // 66
51
        //
52
        reg     signed          [DATA_W-1:0]                     a, b;
53
        wire    signed          [HI_W-1:0]                               a_hi, b_hi;
54
        wire    signed          [LO_W:0]                                 a_lo_ze, b_lo_ze;  // 35 (extra zero MSB)
55
        reg     signed          [MULT_W-1:0]                     mult_hi_hi, mult_hi_lo, mult_lo_hi, mult_lo_lo;
56
        reg     signed          [DBL_W-1:0]                              inner_sum, outer_cat;
57
 
58
 
59
        /*
60
        ================
61
        == code start ==
62
        ================
63
        */
64
 
65
 
66
        // input registering (likely free)
67
        always @ ( posedge clk_i or posedge rst_i ) begin
68
                if ( rst_i ) begin
69
                        a <= 'b0;
70
                        b <= 'b0;
71
                end else begin
72
                        a <= a_i;
73
                        b <= b_i;
74
                end
75
        end
76
 
77
        // select & extend inputs
78
        assign a_hi = a[DATA_W-1:LO_W];
79
        assign b_hi = b[DATA_W-1:LO_W];
80
        assign a_lo_ze = { 1'b0, a[LO_W-1:0] };
81
        assign b_lo_ze = { 1'b0, b[LO_W-1:0] };
82
 
83
        // do all multiplies & register (registers are likely free)
84
        always @ ( posedge clk_i or posedge rst_i ) begin
85
                if ( rst_i ) begin
86
                        mult_hi_hi <= 'b0;
87
                        mult_hi_lo <= 'b0;
88
                        mult_lo_hi <= 'b0;
89
                        mult_lo_lo <= 'b0;
90
                end else begin
91
                        mult_hi_hi <= a_hi * b_hi;
92
                        mult_hi_lo <= a_hi * b_lo_ze;
93
                        mult_lo_hi <= a_lo_ze * b_hi;
94
                        mult_lo_lo <= a_lo_ze * b_lo_ze;
95
                end
96
        end
97
 
98
        // add and shift inner terms, concatenate outer terms, register
99
        always @ ( posedge clk_i or posedge rst_i ) begin
100
                if ( rst_i ) begin
101
                        inner_sum <= 'b0;
102
                        outer_cat <= 'b0;
103
                end else begin
104
                        inner_sum <= ( mult_hi_lo + mult_lo_hi ) << LO_W;
105
                        outer_cat <= { mult_hi_hi[HI_W*2-1:0], mult_lo_lo };
106
                end
107
        end
108
 
109
        // final add & register
110
        always @ ( posedge clk_i or posedge rst_i ) begin
111
                if ( rst_i ) begin
112
                        result_o <= 'b0;
113
                end else begin
114
                        result_o <= outer_cat + inner_sum;
115
                end
116
        end
117
 
118
 
119
        // optional debug mode
120
        generate
121
                if ( DEBUG_MODE ) begin
122
                        wire signed [DBL_W-1:0] debug_mult, debug_mult_r;
123
                        reg debug;
124
                        assign debug_mult = a * b;
125
                        // delay regs
126
                        vector_sr
127
                        #(
128
                        .REGS                   ( 3 ),
129
                        .DATA_W         ( DBL_W ),
130
                        .RESET_VAL      ( 0 )
131
                        )
132
                        regs_debug
133
                        (
134
                        .clk_i          ( clk_i ),
135
                        .rst_i          ( rst_i ),
136
                        .data_i         ( debug_mult ),
137
                        .data_o         ( debug_mult_r )
138
                        );
139
                        // compare & register
140
                        always @ ( posedge clk_i or posedge rst_i ) begin
141
                                if ( rst_i ) begin
142
                                        debug <= 'b0;
143
                                end else begin
144
                                        debug <= ( debug_mult_r != result_o );
145
                                end
146
                        end
147
                        //
148
                        assign debug_o = debug;
149
                end else begin
150
                        assign debug_o = 'b0;
151
                end
152
        endgenerate
153
 
154
 
155
endmodule

powered by: WebSVN 2.1.0

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