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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [positVerilog/] [positMultiply.sv] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 47 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2020  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch@finitron.ca
6
//       ||
7
//
8 48 robfinch
//      positMultiply.sv
9 47 robfinch
//    - posit number multiplier, pipelined with latency of 13
10
//    - can issue every other clock cycle
11
//    - parameterized width
12
//
13
//
14
// This source file is free software: you can redistribute it and/or modify
15
// it under the terms of the GNU Lesser General Public License as published
16
// by the Free Software Foundation, either version 3 of the License, or
17
// (at your option) any later version.
18
//
19
// This source file is distributed in the hope that it will be useful,
20
// but WITHOUT ANY WARRANTY; without even the implied warranty of
21
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
// GNU General Public License for more details.
23
//
24
// You should have received a copy of the GNU General Public License
25
// along with this program.  If not, see .
26
//
27
// ============================================================================
28
 
29 48 robfinch
import posit::*;
30 47 robfinch
 
31
module positMultiply(clk, ce, a, b, o, zero, inf);
32
input clk;
33
input ce;
34
input [PSTWID-1:0] a;
35
input [PSTWID-1:0] b;
36
output reg [PSTWID-1:0] o;
37
output reg zero;
38
output reg inf;
39
 
40
wire sa, sb, so;
41
wire [rs-1:0] rgma, rgmb;
42
wire rgsa, rgsb;
43
wire [es-1:0] expa, expb;
44
wire [PSTWID-es-1:0] siga, sigb;
45
wire zera, zerb;
46
wire infa, infb;
47
wire [PSTWID-1:0] aa, bb;
48
 
49
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
50
// Clock #1
51
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
52
 
53 48 robfinch
positDecomposeReg #(PSTWID) u1 (
54 47 robfinch
  .clk(clk),
55
  .ce(ce),
56
  .i(a),
57
  .sgn(sa),
58
  .rgs(rgsa),
59
  .rgm(rgma),
60
  .exp(expa),
61
  .sig(siga),
62
  .zer(zera),
63
  .inf(infa)
64
);
65
 
66 48 robfinch
positDecomposeReg #(PSTWID) u2 (
67 47 robfinch
  .clk(clk),
68
  .ce(ce),
69
  .i(b),
70
  .sgn(sb),
71
  .rgs(rgsb),
72
  .rgm(rgmb),
73
  .exp(expb),
74
  .sig(sigb),
75
  .zer(zerb),
76
  .inf(infb)
77
);
78
 
79
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
80
// Clock #2
81
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
82
reg [rs+1:0] rgm1, rgm2;
83
reg [es-1:0] expa2, expb2;
84
reg so2;
85
reg inf2;
86
reg zero2;
87
reg [(PSTWID-es)*2-1:0] prod2;
88
 
89
always @(posedge clk)
90
  if (ce) prod2 <= siga * sigb;
91
always @(posedge clk)
92
  if (ce) so2 <= sa ^ sb;  // compute sign
93
always @(posedge clk)
94
  if (ce) inf2 <= infa|infb;
95
always @(posedge clk)
96
  if (ce) zero2 <= zera|zerb;
97
// Convert to the real +/- regime value
98
always @(posedge clk)
99
  if (ce) rgm1 <= rgsa ? rgma : -rgma;
100
always @(posedge clk)
101
  if (ce) rgm2 <= rgsb ? rgmb : -rgmb;
102
always @(posedge clk)
103
  if (ce) expa2 <= expa;
104
always @(posedge clk)
105
  if (ce) expb2 <= expb;
106
 
107
// The product could have one or two whole digits before the point. Detect which it is
108
// and realign the product.
109
wire mo = prod2[(PSTWID-es)*2-1];
110
 
111
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
112
// Clock #3
113
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
114
reg [(PSTWID-es)*2-1:0] prod3;
115
reg [rs+es+1:0] rxtmp;
116
 
117
always @(posedge clk)
118
  if (ce) prod3 <= mo ? prod2 : {prod2,1'b0};  // left align product
119
 
120
// Compute regime and exponent, include product alignment shift.
121
always @(posedge clk)
122
  if (ce) rxtmp <= {rgm1,expa2} + {rgm2,expb2} + mo;
123
 
124
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
125
// Clock #4
126
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
127
reg [rs+es+1:0] rxtmp2c;
128
reg [es-1:0] exp;
129
reg [(PSTWID-es)*2-1:0] prod4;
130
reg [rs+es+1:0] rxtmp4;
131
reg srxtmp;
132
 
133
// Make a negative rx positive
134
always @(posedge clk)
135
  if (ce) rxtmp2c <= rxtmp[rs+es+1] ? ~rxtmp + 2'd1 : rxtmp;
136
 
137
always @(posedge clk)
138
  if (ce) prod4 <= prod3;
139
always @(posedge clk)
140
  if (ce) rxtmp4 <= rxtmp;
141
// Break out the exponent and regime portions
142
always @(posedge clk)
143
  if (ce) exp <= rxtmp[es-1:0];
144
// Take absolute value of regime portion
145
always @(posedge clk)
146
  if (ce) srxtmp <= rxtmp[rs+es+1];
147
 
148
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
149
// Clock #5
150
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
151
reg [rs:0] rgm;
152
reg [rs+es+1:0] rxn;
153
reg [rs+es+1:0] rxtmp2c5;
154
reg [(PSTWID-es)*2-1:0] prod5;
155
reg [es-1:0] exp5;
156
reg srxtmp5;
157
 
158
always @(posedge clk)
159
  if (ce) rgm = srxtmp ? -rxtmp4[rs+es+1:es] : rxtmp4[rs+es+1:es];
160
 
161
// Compute the length of the regime bit string, +1 for positive regime
162
always @(posedge clk)
163
  if (ce) rxn <= rxtmp4[rs+es+1] ? rxtmp2c : rxtmp4;
164
 
165
always @(posedge clk)
166
  if (ce) prod5 <= prod4;
167
always @(posedge clk)
168
  if (ce) exp5 <= exp;
169
always @(posedge clk)
170
  if (ce) srxtmp5 <= srxtmp;
171
always @(posedge clk)
172
  if (ce) rxtmp2c5 <= rxtmp2c;
173
 
174
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
175
// Clock #6
176
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
177
reg [rs:0] rgml;
178
reg [PSTWID*2-1+3:0] tmp;
179
 
180
always @(posedge clk)
181
  if (ce) rgml <= (~srxtmp5 | |(rxn[es-1:0])) ? rxtmp2c5[rs+es:es] + 2'd1 : rxtmp2c5[rs+es:es];
182
 
183
// Build expanded posit number:
184
// trim one leading bit off the product bits
185
// and keep guard, round bits, and create sticky bit
186
always @(posedge clk)
187
  if (ce) tmp <= {{PSTWID-1{~srxtmp5}},srxtmp5,exp5,prod5[(PSTWID-es)*2-2:(PSTWID-es-2)],|prod5[(PSTWID-es-3):0]};
188
 
189
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
190
// Clock #7
191
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
192
reg [PSTWID*3-1+3:0] tmp7;
193
reg [rs:0] rgml7;
194
 
195
always @(posedge clk)
196
  if (ce) tmp7 <= {tmp,{PSTWID{1'b0}}} >> rgml;
197
always @(posedge clk)
198
  if (ce) rgml7 <= rgml;
199
 
200
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
201
// Clock #8
202
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
203
// Rounding
204
// Guard, Round, and Sticky
205
reg L, G, R, St;
206
reg [PSTWID*3-1+3:0] tmp8;
207
reg [rs:0] rgml8;
208
 
209
always @(posedge clk)
210
  if (ce) rgml8 <= rgml7;
211
always @(posedge clk)
212
  if (ce) L <= tmp7[PSTWID+4];
213
always @(posedge clk)
214
  if (ce) G <= tmp7[PSTWID+3];
215
always @(posedge clk)
216
  if (ce) R <= tmp7[PSTWID+2];
217
always @(posedge clk)
218
  if (ce) St <= |tmp7[PSTWID+1:0];
219
always @(posedge clk)
220
  if (ce) tmp8 <= tmp7;
221
 
222
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
223
// Clock #9
224
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
225
reg ulp;
226
wire [PSTWID-1:0] rnd_ulp;
227
reg [PSTWID*3-1+3:0] tmp9;
228
reg [rs:0] rgml9;
229
 
230
always @(posedge clk)
231
  if (ce) ulp <= ((G & (R | St)) | (L & G & ~(R | St)));
232
always @(posedge clk)
233
  if (ce) tmp9 <= tmp8;
234
always @(posedge clk)
235
  if (ce) rgml9 <= rgml8;
236
assign rnd_ulp = {{PSTWID-1{1'b0}},ulp};
237
 
238
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
239
// Clock #10
240
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
241
reg [PSTWID:0] tmp10_rnd_ulp;
242
reg [PSTWID*3-1+3:0] tmp10;
243
reg [rs:0] rgml10;
244
 
245
always @(posedge clk)
246
  if (ce) tmp10 <= tmp9;
247
always @(posedge clk)
248
  if (ce) tmp10_rnd_ulp <= tmp9[2*PSTWID-1+3:PSTWID+3] + rnd_ulp;
249
always @(posedge clk)
250
  if (ce) rgml10 <= rgml9;
251
 
252
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
253
// Clock #11
254
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
255
reg [PSTWID-1:0] tmp11_rnd;
256
 
257
always @(posedge clk)
258
  if (ce) tmp11_rnd <= (rgml10 < PSTWID-es-2) ? tmp10_rnd_ulp[PSTWID-1:0] : tmp10[2*PSTWID-1+3:PSTWID+3];
259
 
260
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
261
// Clock #12
262
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
263
reg [PSTWID-1:0] abs_tmp;
264
wire so11;
265
reg so12;
266
delay #(.WID(1),.DEP(9)) udly1 (.clk(clk), .ce(ce), .i(so2), .o(so11));
267
 
268
always @(posedge clk)
269
  if (ce) abs_tmp <= so11 ? -tmp11_rnd : tmp11_rnd;
270
always @(posedge clk)
271
  if (ce) so12 <= so11;
272
 
273
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
274
// Clock #13
275
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
276
wire zero12, inf12;
277
 
278
delay #(.WID(1),.DEP(10)) udly2 (.clk(clk), .ce(ce), .i(zero2), .o(zero12));
279
delay #(.WID(1),.DEP(10)) udly3 (.clk(clk), .ce(ce), .i(inf2), .o(inf12));
280
 
281
always @(posedge clk)
282
  if (ce) zero <= zero12;
283
always @(posedge clk)
284
  if (ce) inf <= inf12;
285
 
286
always @(posedge clk)
287
  if (ce)
288
    casez({zero12,inf12})
289
    2'b1?: o <= {PSTWID{1'b0}};
290
    2'b01: o <= {1'b1,{PSTWID-1{1'b0}}};
291
    default:  o <= {so12,abs_tmp[PSTWID-1:1]};
292
    endcase
293
 
294
endmodule

powered by: WebSVN 2.1.0

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