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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_shifter_multiply.v] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 Revanth
// -----------------------------------------------------------------------------
2
// --                                                                         --
3
// --                   (C) 2016-2018 Revanth Kamaraj.                        --
4
// --                                                                         -- 
5
// -- --------------------------------------------------------------------------
6
// --                                                                         --
7
// -- This program is free software; you can redistribute it and/or           --
8
// -- modify it under the terms of the GNU General Public License             --
9
// -- as published by the Free Software Foundation; either version 2          --
10
// -- of the License, or (at your option) any later version.                  --
11
// --                                                                         --
12
// -- This program is distributed in the hope that it will be useful,         --
13
// -- but WITHOUT ANY WARRANTY; without even the implied warranty of          --
14
// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           --
15
// -- GNU General Public License for more details.                            --
16
// --                                                                         --
17
// -- You should have received a copy of the GNU General Public License       --
18
// -- along with this program; if not, write to the Free Software             --
19
// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA           --
20
// -- 02110-1301, USA.                                                        --
21
// --                                                                         --
22
// -----------------------------------------------------------------------------
23
// --                                                                         -- 
24
// --  This unit handles 32x32=32/64 multiplication using an FSM using        --
25
// --  a 17x17 signed array multiplier.                                       -- 
26
// --                                                                         --
27
// -----------------------------------------------------------------------------
28
 
29
 
30
`default_nettype none
31
 
32
module zap_shifter_multiply
33
#(
34
        parameter PHY_REGS = 46,
35
        parameter ALU_OPS   = 32
36
)
37
(
38
        input wire                              i_clk,
39
        input wire                              i_reset,
40
 
41
        // Clear and stall signals.
42
        input wire                              i_clear_from_writeback,
43
        input wire                              i_data_stall,
44
        input wire                              i_clear_from_alu,
45
 
46
        // ALU operation to perform. Activate if this is multiplication.
47
        input wire   [$clog2(ALU_OPS)-1:0]      i_alu_operation_ff,
48
 
49
        // This is not used.
50
        input wire                              i_cc_satisfied,
51
 
52
        // rm.rs + {rh,rn}. For non accumulate versions, rn = 0x0 and rh = 0x0.
53
        input wire [31:0]                       i_rm,
54
        input wire [31:0]                       i_rn,
55
        input wire [31:0]                       i_rh,
56
        input wire [31:0]                       i_rs,
57
 
58
        //
59
        // Outputs.
60
        //
61
 
62
        output reg  [31:0]                      o_rd,    // Result.
63
        output reg                              o_busy,  // Unit busy.
64
        output reg                              o_nozero // Don't set zero flag.
65
);
66
 
67
`include "zap_defines.vh"
68
`include "zap_localparams.vh"
69
`include "zap_functions.vh"
70
 
71
///////////////////////////////////////////////////////////////////////////////
72
 
73
// States
74
localparam IDLE = 0;
75
localparam S1   = 1;
76
localparam S2   = 2;
77
localparam S3   = 3;
78
localparam S4   = 4;
79
localparam S5   = 5;
80
localparam NUMBER_OF_STATES = 6;
81
 
82
///////////////////////////////////////////////////////////////////////////////
83
 
84
reg [31:0] buffer_nxt, buffer_ff;
85
wire higher = i_alu_operation_ff[0];
86
wire sign   = (i_alu_operation_ff == SMLALL || i_alu_operation_ff == SMLALH);
87
wire signed [16:0] a;
88
wire signed [16:0] b;
89
wire signed [16:0] c;
90
wire signed [16:0] d;
91
reg signed [63:0] x_ff, x_nxt;
92
reg signed [16:0] in1;
93
reg signed [16:0] in2;
94
wire signed [63:0] prod;
95
 
96
// State variable.
97
reg [$clog2(NUMBER_OF_STATES)-1:0] state_ff, state_nxt;
98
 
99
///////////////////////////////////////////////////////////////////////////////
100
 
101
assign prod = in1 * in2; // 17x17 hard macro model.
102
 
103
///////////////////////////////////////////////////////////////////////////////
104
 
105
assign a = sign ? {i_rm[31], i_rm[31:16]} : {1'd0, i_rm[31:16]};
106
assign b = sign ? {i_rs[31], i_rs[31:16]} : {1'd0, i_rs[31:16]};
107
assign c = {1'd0, i_rm[15:0]};
108
assign d = {1'd0, i_rs[15:0]};
109
 
110
///////////////////////////////////////////////////////////////////////////////
111
 
112
always @*
113
begin
114
        buffer_nxt = buffer_ff;
115
        o_nozero = 1'd0;
116
        o_busy = 1'd1;
117
        o_rd   = 32'd0;
118
        state_nxt = state_ff;
119
        x_nxt = x_ff;
120
        in1 = 0;
121
        in2 = 0;
122
 
123
        case ( state_ff )
124
                IDLE:
125
                begin
126
                        o_busy = 1'd0;
127
                        x_nxt  = 32'd0;
128
 
129
                        // If we have the go signal.
130
                        if ( i_cc_satisfied && (i_alu_operation_ff == UMLALL ||
131
                                                i_alu_operation_ff == UMLALH ||
132
                                                i_alu_operation_ff == SMLALL ||
133
                                                i_alu_operation_ff == SMLALH) )
134
                        begin
135
                                o_busy = 1'd1;
136
                                state_nxt = S1;
137
                        end
138
                end
139
                S1:
140
                begin
141
                        in1 = c;
142
                        in2 = d;
143
                        x_nxt     = x_ff + (prod << 0);
144
                        state_nxt = S2;
145
                end
146
                S2:
147
                begin
148
                        in1 = b;
149
                        in2 = c;
150
                        state_nxt = S3;
151
                        x_nxt     = x_ff + (prod << 16);
152
                end
153
                S3:
154
                begin
155
                        in1 = a;
156
                        in2 = d;
157
                        state_nxt = S4;
158
                        x_nxt     = x_ff + (prod << 16);
159
                end
160
                S4:
161
                begin
162
                        in1 = a;
163
                        in2 = b;
164
                        state_nxt = S5;
165
                        x_nxt    = x_ff + (prod << 32);
166
                end
167
                S5:
168
                begin
169
                        state_nxt  = IDLE;
170
                        x_nxt      = x_ff + {i_rh, i_rn};
171
                        o_rd       = higher ? x_nxt[63:32] : x_nxt[31:0];
172
 
173
                        if ( !higher )
174
                        begin
175
                                buffer_nxt = x_nxt[31:0];
176
                        end
177
 
178
                        o_busy     = 1'd0;
179
 
180
                        if ( higher && (buffer_ff != 32'd0) )
181
                        begin
182
                                o_nozero = 1'd1;
183
                        end
184
                end
185
        endcase
186
end
187
 
188
///////////////////////////////////////////////////////////////////////////////
189
 
190
always @ (posedge i_clk)
191
begin
192
        if ( i_reset )
193
        begin
194
                x_ff     <= 63'd0;
195
                state_ff <= IDLE;
196
                buffer_ff<= 32'd0;
197
        end
198
        else if ( i_clear_from_writeback )
199
        begin
200
                x_ff     <= 63'd0;
201
                state_ff <= IDLE;
202
                buffer_ff <= 32'd0;
203
        end
204
        else if ( i_data_stall )
205
        begin
206
                // Hold values
207
        end
208
        else if ( i_clear_from_alu )
209
        begin
210
                x_ff     <= 63'd0;
211
                state_ff <= IDLE;
212
                buffer_ff <= 32'd0;
213
        end
214
        else
215
        begin
216
                x_ff <= x_nxt;
217
                state_ff <= state_nxt;
218
                buffer_ff <= buffer_nxt;
219
        end
220
end
221
 
222
///////////////////////////////////////////////////////////////////////////////
223
 
224
endmodule // zap_multiply.v
225 51 Revanth
 
226 26 Revanth
`default_nettype wire
227 51 Revanth
 
228
// ----------------------------------------------------------------------------
229
// EOF
230
// ----------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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