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

Subversion Repositories ft816float

[/] [ft816float/] [trunk/] [rtl/] [verilog2/] [BCDMath.v] - Blame information for rev 53

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

Line No. Rev Author Line
1 50 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4
//   \\__/ o\    (C) 2012-2020  Robert Finch, Waterloo
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch<remove>@finitron.ca
7
//       ||
8
//
9
//      BCDMath.sv
10
//
11
// BSD 3-Clause License
12
// Redistribution and use in source and binary forms, with or without
13
// modification, are permitted provided that the following conditions are met:
14
//
15
// 1. Redistributions of source code must retain the above copyright notice, this
16
//    list of conditions and the following disclaimer.
17
//
18
// 2. Redistributions in binary form must reproduce the above copyright notice,
19
//    this list of conditions and the following disclaimer in the documentation
20
//    and/or other materials provided with the distribution.
21
//
22
// 3. Neither the name of the copyright holder nor the names of its
23
//    contributors may be used to endorse or promote products derived from
24
//    this software without specific prior written permission.
25
//
26
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
30
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
34
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
//                                                                          
37
// ============================================================================
38
//
39
module BCDAdd(ci,a,b,o,c);
40
input ci;               // carry input
41
input [7:0] a;
42
input [7:0] b;
43
output [7:0] o;
44
output c;
45
 
46
wire c0,c1;
47
 
48
wire [4:0] hsN0 = a[3:0] + b[3:0] + ci;
49
wire [4:0] hsN1 = a[7:4] + b[7:4] + c0;
50
 
51
BCDAddAdjust u1 (hsN0,o[3:0],c0);
52
BCDAddAdjust u2 (hsN1,o[7:4],c);
53
 
54
endmodule
55
 
56
module BCDAdd4(ci,a,b,o,c,c8);
57
input ci;               // carry input
58
input [15:0] a;
59
input [15:0] b;
60
output [15:0] o;
61
output c;
62
output c8;
63
 
64
wire c0,c1,c2;
65
assign c8 = c1;
66
 
67
wire [4:0] hsN0 = a[3:0] + b[3:0] + ci;
68
wire [4:0] hsN1 = a[7:4] + b[7:4] + c0;
69
wire [4:0] hsN2 = a[11:8] + b[11:8] + c1;
70
wire [4:0] hsN3 = a[15:12] + b[15:12] + c2;
71
 
72
BCDAddAdjust u1 (hsN0,o[3:0],c0);
73
BCDAddAdjust u2 (hsN1,o[7:4],c1);
74
BCDAddAdjust u3 (hsN2,o[11:8],c2);
75
BCDAddAdjust u4 (hsN3,o[15:12],c);
76
 
77
endmodule
78
 
79
module BCDAddN(ci,a,b,o,co);
80
parameter N=24;
81
input ci;               // carry input
82
input [N*4-1:0] a;
83
input [N*4-1:0] b;
84
output [N*4-1:0] o;
85
output co;
86
 
87
genvar g;
88
generate begin : gBCDAddN
89
reg [4:0] hsN [0:N-1];
90
wire [N:0] c;
91
 
92
assign c[0] = ci;
93
assign co = c[N];
94
 
95
for (g = 0; g < N; g = g + 1)
96
        always @*
97
                hsN[g] = a[g*4+3:g*4] + b[g*4+3:g*4] + c[g];
98
 
99
for (g = 0; g < N; g = g + 1)
100
        BCDAddAdjust u1 (hsN[g],o[g*4+3:g*4],c[g+1]);
101
end
102
endgenerate
103
 
104
endmodule
105
 
106
module BCDSub(ci,a,b,o,c);
107
input ci;               // carry input
108
input [7:0] a;
109
input [7:0] b;
110
output [7:0] o;
111
output c;
112
 
113
wire c0,c1;
114
 
115
wire [4:0] hdN0 = a[3:0] - b[3:0] - ci;
116
wire [4:0] hdN1 = a[7:4] - b[7:4] - c0;
117
 
118
BCDSubAdjust u1 (hdN0,o[3:0],c0);
119
BCDSubAdjust u2 (hdN1,o[7:4],c);
120
 
121
endmodule
122
 
123
module BCDSub4(ci,a,b,o,c,c8);
124
input ci;               // carry input
125
input [15:0] a;
126
input [15:0] b;
127
output [15:0] o;
128
output c;
129
output c8;
130
 
131
wire c0,c1,c2;
132
assign c8 = c1;
133
 
134
wire [4:0] hdN0 = a[3:0] - b[3:0] - ci;
135
wire [4:0] hdN1 = a[7:4] - b[7:4] - c0;
136
wire [4:0] hdN2 = a[11:8] - b[11:8] - c1;
137
wire [4:0] hdN3 = a[15:12] - b[15:12] - c2;
138
 
139
BCDSubAdjust u1 (hdN0,o[3:0],c0);
140
BCDSubAdjust u2 (hdN1,o[7:4],c1);
141
BCDSubAdjust u3 (hdN2,o[11:8],c2);
142
BCDSubAdjust u4 (hdN3,o[15:12],c);
143
 
144
endmodule
145
 
146
module BCDSubN(ci,a,b,o,co);
147
parameter N=24;
148
input ci;               // carry input
149
input [N*4-1:0] a;
150
input [N*4-1:0] b;
151
output [N*4-1:0] o;
152
output co;
153
 
154
genvar g;
155
generate begin : gBCDSubN
156
reg [4:0] hdN [0:N-1];
157
wire [N:0] c;
158
 
159
assign c[0] = ci;
160
assign co = c[N];
161
 
162
for (g = 0; g < N; g = g + 1)
163
        always @*
164
                hdN[g] = a[g*4+3:g*4] - b[g*4+3:g*4] - c[g];
165
 
166
for (g = 0; g < N; g = g + 1)
167
        BCDSubAdjust u1 (hdN[g],o[g*4+3:g*4],c[g+1]);
168
end
169
endgenerate
170
 
171
endmodule
172
 
173
module BCDAddAdjust(i,o,c);
174
input [4:0] i;
175
output [3:0] o;
176
reg [3:0] o;
177
output c;
178
reg c;
179
always @(i)
180
case(i)
181
5'h0: begin o = 4'h0; c = 1'b0; end
182
5'h1: begin o = 4'h1; c = 1'b0; end
183
5'h2: begin o = 4'h2; c = 1'b0; end
184
5'h3: begin o = 4'h3; c = 1'b0; end
185
5'h4: begin o = 4'h4; c = 1'b0; end
186
5'h5: begin o = 4'h5; c = 1'b0; end
187
5'h6: begin o = 4'h6; c = 1'b0; end
188
5'h7: begin o = 4'h7; c = 1'b0; end
189
5'h8: begin o = 4'h8; c = 1'b0; end
190
5'h9: begin o = 4'h9; c = 1'b0; end
191
5'hA: begin o = 4'h0; c = 1'b1; end
192
5'hB: begin o = 4'h1; c = 1'b1; end
193
5'hC: begin o = 4'h2; c = 1'b1; end
194
5'hD: begin o = 4'h3; c = 1'b1; end
195
5'hE: begin o = 4'h4; c = 1'b1; end
196
5'hF: begin o = 4'h5; c = 1'b1; end
197
5'h10:  begin o = 4'h6; c = 1'b1; end
198
5'h11:  begin o = 4'h7; c = 1'b1; end
199
5'h12:  begin o = 4'h8; c = 1'b1; end
200
5'h13:  begin o = 4'h9; c = 1'b1; end
201
default:        begin o = 4'h9; c = 1'b1; end
202
endcase
203
endmodule
204
 
205
module BCDSubAdjust(i,o,c);
206
input [4:0] i;
207
output [3:0] o;
208
reg [3:0] o;
209
output c;
210
reg c;
211
always @(i)
212
case(i)
213
5'h0: begin o = 4'h0; c = 1'b0; end
214
5'h1: begin o = 4'h1; c = 1'b0; end
215
5'h2: begin o = 4'h2; c = 1'b0; end
216
5'h3: begin o = 4'h3; c = 1'b0; end
217
5'h4: begin o = 4'h4; c = 1'b0; end
218
5'h5: begin o = 4'h5; c = 1'b0; end
219
5'h6: begin o = 4'h6; c = 1'b0; end
220
5'h7: begin o = 4'h7; c = 1'b0; end
221
5'h8: begin o = 4'h8; c = 1'b0; end
222
5'h9: begin o = 4'h9; c = 1'b0; end
223
5'h16: begin o = 4'h0; c = 1'b1; end
224
5'h17: begin o = 4'h1; c = 1'b1; end
225
5'h18: begin o = 4'h2; c = 1'b1; end
226
5'h19: begin o = 4'h3; c = 1'b1; end
227
5'h1A: begin o = 4'h4; c = 1'b1; end
228
5'h1B: begin o = 4'h5; c = 1'b1; end
229
5'h1C: begin o = 4'h6; c = 1'b1; end
230
5'h1D: begin o = 4'h7; c = 1'b1; end
231
5'h1E: begin o = 4'h8; c = 1'b1; end
232
5'h1F: begin o = 4'h9; c = 1'b1; end
233
default: begin o = 4'h9; c = 1'b1; end
234
endcase
235
endmodule
236
 
237
// Multiply two BCD digits
238
// Method used is table lookup
239
module BCDMul1(a,b,o);
240
input [3:0] a;
241
input [3:0] b;
242
output [7:0] o;
243
reg [7:0] o;
244
 
245
always @(a or b)
246
casex({a,b})
247
8'h00: o = 8'h00;
248
8'h01: o = 8'h00;
249
8'h02: o = 8'h00;
250
8'h03: o = 8'h00;
251
8'h04: o = 8'h00;
252
8'h05: o = 8'h00;
253
8'h06: o = 8'h00;
254
8'h07: o = 8'h00;
255
8'h08: o = 8'h00;
256
8'h09: o = 8'h00;
257
8'h10: o = 8'h00;
258
8'h11: o = 8'h01;
259
8'h12: o = 8'h02;
260
8'h13: o = 8'h03;
261
8'h14: o = 8'h04;
262
8'h15: o = 8'h05;
263
8'h16: o = 8'h06;
264
8'h17: o = 8'h07;
265
8'h18: o = 8'h08;
266
8'h19: o = 8'h09;
267
8'h20: o = 8'h00;
268
8'h21: o = 8'h02;
269
8'h22: o = 8'h04;
270
8'h23: o = 8'h06;
271
8'h24: o = 8'h08;
272
8'h25: o = 8'h10;
273
8'h26: o = 8'h12;
274
8'h27: o = 8'h14;
275
8'h28: o = 8'h16;
276
8'h29: o = 8'h18;
277
8'h30: o = 8'h00;
278
8'h31: o = 8'h03;
279
8'h32: o = 8'h06;
280
8'h33: o = 8'h09;
281
8'h34: o = 8'h12;
282
8'h35: o = 8'h15;
283
8'h36: o = 8'h18;
284
8'h37: o = 8'h21;
285
8'h38: o = 8'h24;
286
8'h39: o = 8'h27;
287
8'h40: o = 8'h00;
288
8'h41: o = 8'h04;
289
8'h42: o = 8'h08;
290
8'h43: o = 8'h12;
291
8'h44: o = 8'h16;
292
8'h45: o = 8'h20;
293
8'h46: o = 8'h24;
294
8'h47: o = 8'h28;
295
8'h48: o = 8'h32;
296
8'h49: o = 8'h36;
297
8'h50: o = 8'h00;
298
8'h51: o = 8'h05;
299
8'h52: o = 8'h10;
300
8'h53: o = 8'h15;
301
8'h54: o = 8'h20;
302
8'h55: o = 8'h25;
303
8'h56: o = 8'h30;
304
8'h57: o = 8'h35;
305
8'h58: o = 8'h40;
306
8'h59: o = 8'h45;
307
8'h60: o = 8'h00;
308
8'h61: o = 8'h06;
309
8'h62: o = 8'h12;
310
8'h63: o = 8'h18;
311
8'h64: o = 8'h24;
312
8'h65: o = 8'h30;
313
8'h66: o = 8'h36;
314
8'h67: o = 8'h42;
315
8'h68: o = 8'h48;
316
8'h69: o = 8'h54;
317
8'h70: o = 8'h00;
318
8'h71: o = 8'h07;
319
8'h72: o = 8'h14;
320
8'h73: o = 8'h21;
321
8'h74: o = 8'h28;
322
8'h75: o = 8'h35;
323
8'h76: o = 8'h42;
324
8'h77: o = 8'h49;
325
8'h78: o = 8'h56;
326
8'h79: o = 8'h63;
327
8'h80: o = 8'h00;
328
8'h81: o = 8'h08;
329
8'h82: o = 8'h16;
330
8'h83: o = 8'h24;
331
8'h84: o = 8'h32;
332
8'h85: o = 8'h40;
333
8'h86: o = 8'h48;
334
8'h87: o = 8'h56;
335
8'h88: o = 8'h64;
336
8'h89: o = 8'h72;
337
8'h90: o = 8'h00;
338
8'h91: o = 8'h09;
339
8'h92: o = 8'h18;
340
8'h93: o = 8'h27;
341
8'h94: o = 8'h36;
342
8'h95: o = 8'h45;
343
8'h96: o = 8'h54;
344
8'h97: o = 8'h63;
345
8'h98: o = 8'h72;
346
8'h99: o = 8'h81;
347
default:        o = 8'h00;
348
endcase
349
endmodule
350
 
351
 
352
// Multiply two pairs of BCD digits
353
// handles from 0x0 to 99x99
354
module BCDMul2(a,b,o);
355
input [7:0] a;
356
input [7:0] b;
357
output [15:0] o;
358
 
359
wire [7:0] p1,p2,p3,p4;
360
wire [15:0] s1;
361
 
362
BCDMul1 u1 (a[3:0],b[3:0],p1);
363
BCDMul1 u2 (a[7:4],b[3:0],p2);
364
BCDMul1 u3 (a[3:0],b[7:4],p3);
365
BCDMul1 u4 (a[7:4],b[7:4],p4);
366
 
367
BCDAdd4 u5 (1'b0,{p4,p1},{4'h0,p2,4'h0},s1);
368
BCDAdd4 u6 (1'b0,s1,{4'h0,p3,4'h0},o);
369
 
370
endmodule
371
 
372 53 robfinch
module BCDMul4(a,b,o);
373
input [15:0] a;
374
input [15:0] b;
375
output [31:0] o;
376
 
377
wire [15:0] p1,p2,p3,p4;
378
wire [31:0] s1;
379
 
380
BCDMul2 u1 (a[7:0],b[7:0],p1);
381
BCDMul2 u2 (a[15:8],b[7:0],p2);
382
BCDMul2 u3 (a[7:0],b[15:8],p3);
383
BCDMul2 u4 (a[15:8],b[15:8],p4);
384
 
385
BCDAddN #(.N(8)) u5 (1'b0,{p4,p1},{8'h0,p2,8'h0},s1);
386
BCDAddN #(.N(8)) u6 (1'b0,s1,{8'h0,p3,8'h0},o);
387
 
388
endmodule
389
 
390
module BCDMul8(a,b,o);
391
input [31:0] a;
392
input [31:0] b;
393
output [63:0] o;
394
 
395
wire [31:0] p1,p2,p3,p4;
396
wire [63:0] s1;
397
 
398
BCDMul4 u1 (a[15:0],b[15:0],p1);
399
BCDMul4 u2 (a[31:16],b[15:0],p2);
400
BCDMul4 u3 (a[15:0],b[31:16],p3);
401
BCDMul4 u4 (a[31:16],b[31:16],p4);
402
 
403
BCDAddN #(.N(16)) u5 (1'b0,{p4,p1},{16'h0,p2,16'h0},s1);
404
BCDAddN #(.N(16)) u6 (1'b0,s1,{16'h0,p3,16'h0},o);
405
 
406
endmodule
407
 
408
module BCDMul16(a,b,o);
409
input [63:0] a;
410
input [63:0] b;
411
output [127:0] o;
412
 
413
wire [63:0] p1,p2,p3,p4;
414
wire [127:0] s1;
415
 
416
BCDMul8 u1 (a[31:0],b[31:0],p1);
417
BCDMul8 u2 (a[63:32],b[31:0],p2);
418
BCDMul8 u3 (a[31:0],b[63:32],p3);
419
BCDMul8 u4 (a[63:32],b[63:32],p4);
420
 
421
BCDAddN #(.N(32)) u5 (1'b0,{p4,p1},{32'h0,p2,32'h0},s1);
422
BCDAddN #(.N(32)) u6 (1'b0,s1,{32'h0,p3,32'h0},o);
423
 
424
endmodule
425
 
426
module BCDMul32(a,b,o);
427
input [127:0] a;
428
input [127:0] b;
429
output [255:0] o;
430
 
431
wire [127:0] p1,p2,p3,p4;
432
wire [255:0] s1;
433
 
434
BCDMul16 u1 (a[63:0],b[63:0],p1);
435
BCDMul16 u2 (a[127:64],b[63:0],p2);
436
BCDMul16 u3 (a[63:0],b[127:64],p3);
437
BCDMul16 u4 (a[127:64],b[127:64],p4);
438
 
439
BCDAddN #(.N(64)) u5 (1'b0,{p4,p1},{64'h0,p2,64'h0},s1);
440
BCDAddN #(.N(64)) u6 (1'b0,s1,{64'h0,p3,64'h0},o);
441
 
442
endmodule
443
 
444 50 robfinch
module BCDMul_tb();
445
 
446
wire [15:0] o1,o2,o3,o4;
447
 
448
BCDMul2 u1 (8'h00,8'h00,o1);
449
BCDMul2 u2 (8'h99,8'h99,o2);
450
BCDMul2 u3 (8'h25,8'h18,o3);
451
BCDMul2 u4 (8'h37,8'h21,o4);
452
 
453
endmodule
454
 
455
module BinToBCD(i, o);
456
input [7:0] i;
457
output [11:0] o;
458
 
459
reg [11:0] tbl [0:255];
460
 
461
genvar g;
462
generate begin : gTbl
463
reg [3:0] n0 [0:255];
464
reg [3:0] n1 [0:255];
465
reg [3:0] n2 [0:255];
466
 
467
for (g = 0; g < 256; g = g + 1) begin
468
        initial begin
469
                n0[g] = g % 10;
470
                n1[g] = g / 10;
471
                n2[g] = g / 100;
472
                tbl[g] <= {n2[g],n1[g],n0[g]};
473
        end
474
end
475
 
476
assign o = tbl[i];
477
 
478
end
479
endgenerate
480
 
481
endmodule

powered by: WebSVN 2.1.0

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