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

Subversion Repositories rf68000

[/] [rf68000/] [trunk/] [rtl/] [lib/] [BCDMath.sv] - Blame information for rev 7

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

Line No. Rev Author Line
1 2 robfinch
`timescale 1ns / 1ps
2
// ============================================================================
3
//        __
4
//   \\__/ o\    (C) 2012-2022  Robert Finch, Waterloo
5
//    \  __ /    All rights reserved.
6
//     \/_//     robfinch@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
// Could use the following approach for add/sub but it ends up being larger
40
// than using an adjustment lookup table.
41
 
42
module BCDAddNyb(ci,a,b,o,c);
43
input ci;               // carry input
44
input [3:0] a;
45
input [3:0] b;
46
output [3:0] o;
47
output c;
48
 
49
wire c0;
50
 
51
reg [4:0] hsN0;
52
always  @*
53
begin
54
        hsN0 = a[3:0] + b[3:0] + ci;
55
        if (hsN0 > 5'd9)
56
                hsN0 = hsN0 + 3'd6;
57
end
58
assign o = hsN0[3:0];
59
assign c = hsN0[4];
60
 
61
endmodule
62
 
63
module BCDAdd(ci,a,b,o,c);
64
input ci;               // carry input
65
input [7:0] a;
66
input [7:0] b;
67
output [7:0] o;
68
output c;
69
 
70
wire c0,c1;
71
 
72
wire [4:0] hsN0 = a[3:0] + b[3:0] + ci;
73
wire [4:0] hsN1 = a[7:4] + b[7:4] + c0;
74
 
75
BCDAddAdjust u1 (hsN0,o[3:0],c0);
76
BCDAddAdjust u2 (hsN1,o[7:4],c);
77
 
78
endmodule
79
 
80
module BCDAdd4(ci,a,b,o,c,c8);
81
input ci;               // carry input
82
input [15:0] a;
83
input [15:0] b;
84
output [15:0] o;
85
output c;
86
output c8;
87
 
88
wire c0,c1,c2;
89
assign c8 = c1;
90
 
91
wire [4:0] hsN0 = a[3:0] + b[3:0] + ci;
92
wire [4:0] hsN1 = a[7:4] + b[7:4] + c0;
93
wire [4:0] hsN2 = a[11:8] + b[11:8] + c1;
94
wire [4:0] hsN3 = a[15:12] + b[15:12] + c2;
95
 
96
BCDAddAdjust u1 (hsN0,o[3:0],c0);
97
BCDAddAdjust u2 (hsN1,o[7:4],c1);
98
BCDAddAdjust u3 (hsN2,o[11:8],c2);
99
BCDAddAdjust u4 (hsN3,o[15:12],c);
100
 
101
endmodule
102
/*
103
module BCDAddN(ci,a,b,o,co);
104
parameter N=24;
105
input ci;               // carry input
106
input [N*4-1:0] a;
107
input [N*4-1:0] b;
108
output [N*4-1:0] o;
109
output co;
110
 
111
genvar g;
112
generate begin : gBCDAddN
113
reg [4:0] hsN [0:N-1];
114
wire [N:0] c;
115
 
116
assign c[0] = ci;
117
assign co = c[N];
118
 
119
for (g = 0; g < N; g = g + 1)
120
        always @*
121
                hsN[g] = a[g*4+3:g*4] + b[g*4+3:g*4] + c[g];
122
 
123
for (g = 0; g < N; g = g + 1)
124
        BCDAddAdjust u1 (hsN[g],o[g*4+3:g*4],c[g+1]);
125
end
126
endgenerate
127
 
128
endmodule
129
*/
130
/*
131
module BCDAddN(ci,a,b,o,co);
132
parameter N=34; // Number of digits
133
input ci;                               // carry input
134
input [N*4-1:0] a;
135
input [N*4-1:0] b;
136
output reg [N*4-1:0] o;
137
output reg co;
138
 
139
reg [N*4-1:0] sum1;
140
reg [N-1:0] c;  // inter-digit carries
141
reg [3:0] s1 [0:N-1];   // the digits of sum1 (just wires)
142
reg [4:0] s2 [0:N-1];   // the digits of sum2
143
reg [3:0] sixes [0:N-1];        // 0x666...
144
reg [3:0] ag [0:N-1];   // the digits of a
145
reg [3:0] bg [0:N-1];   // the digits of b
146
 
147
always_comb
148
        sum1 = a + b + ci;
149
always_comb
150
        c[0] = 1'b0;
151
genvar dig;
152
generate begin : gBCDAdd
153
for (dig = 0; dig < N; dig = dig + 1)
154
begin
155
        always_comb
156
                s1[dig] = sum1[dig*4+3:dig*4];  // these are just wires
157
        always_comb
158
                ag[dig] = a[dig*4+3:dig*4];                     // just wires
159
        always_comb
160
                bg[dig] = b[dig*4+3:dig*4];                     // just wires
161
        always_comb
162
                if (dig==0)
163
                        sixes[dig] = 4'd6 | ci;                         // except for first digt, the constant 6
164
                else
165
                        sixes[dig] = 4'd6;
166
        always_comb
167
                if (dig==0)
168
                        s2[dig] = ag[dig] + bg[dig] + sixes[dig];
169
                else
170
                        s2[dig] = ag[dig] + bg[dig] + (sixes[dig]|s2[dig-1][4]);
171
        always_comb                                                                                             // capture inter-digit carries
172
                c[dig] = s2[dig][4];
173
        always_comb                                                                                             // select based on digit value
174
                o[dig*4+3:dig*4] = (s1[dig] > 4'd9) ? s2[dig] : s1[dig];
175
end
176
always_comb
177
        co = c[N-1];
178
 
179
end
180
endgenerate
181
 
182
endmodule
183
*/
184
/* Does not work yet.
185
module BCDAddN(ci,a,b,o,co);
186
parameter N=34;
187
input ci;               // carry input
188
input [N*4-1:0] a;
189
input [N*4-1:0] b;
190
output reg [N*4-1:0] o;
191
output reg co;
192
 
193
reg [N*4:0] sum1, sum2, sum3, c;
194
reg [N*4-1:0] sixes;
195
always_comb
196
        sum1 = a + b;
197
always_comb
198
        sum2 = sum1 + {c,4'd0};
199
always_comb
200
        {co,o} = {c[N*4],sum3};
201
 
202
genvar g;
203
generate begin : gSixes
204
for (g = 0; g < N; g = g + 1)
205
begin
206
        always_comb
207
                c[g*4+3:g*4] = {3'b0,sum1[g*4+3:g*4] > 4'd9};
208
        always_comb
209
                if (g==0)
210
                        sixes[g*4+3:g*4] = (c[g*4] ? 4'd6 : 4'd0) | ci;
211
                else
212
                        sixes[g*4+3:g*4] = c[g*4] ? 4'd6 : 4'd0;
213
        always_comb
214
                if (g==N-1)
215
                        sum3[g*4+4:g*4] = sum2[g*4+3:g*4] + sixes[g*4+3:g*4];
216
                else
217
                        sum3[g*4+3:g*4] = sum2[g*4+3:g*4] + sixes[g*4+3:g*4];
218
end
219
always_comb
220
        c[N*4] = 1'b0;
221
 
222
end
223
endgenerate
224
 
225
endmodule
226
*/
227
module BCDSub(ci,a,b,o,c);
228
input ci;               // carry input
229
input [7:0] a;
230
input [7:0] b;
231
output [7:0] o;
232
output c;
233
 
234
wire c0,c1;
235
 
236
wire [4:0] hdN0 = a[3:0] - b[3:0] - ci;
237
wire [4:0] hdN1 = a[7:4] - b[7:4] - c0;
238
 
239
BCDSubAdjust u1 (hdN0,o[3:0],c0);
240
BCDSubAdjust u2 (hdN1,o[7:4],c);
241
 
242
endmodule
243
 
244
module BCDSub4(ci,a,b,o,c,c8);
245
input ci;               // carry input
246
input [15:0] a;
247
input [15:0] b;
248
output [15:0] o;
249
output c;
250
output c8;
251
 
252
wire c0,c1,c2;
253
assign c8 = c1;
254
 
255
wire [4:0] hdN0 = a[3:0] - b[3:0] - ci;
256
wire [4:0] hdN1 = a[7:4] - b[7:4] - c0;
257
wire [4:0] hdN2 = a[11:8] - b[11:8] - c1;
258
wire [4:0] hdN3 = a[15:12] - b[15:12] - c2;
259
 
260
BCDSubAdjust u1 (hdN0,o[3:0],c0);
261
BCDSubAdjust u2 (hdN1,o[7:4],c1);
262
BCDSubAdjust u3 (hdN2,o[11:8],c2);
263
BCDSubAdjust u4 (hdN3,o[15:12],c);
264
 
265
endmodule
266
 
267
/*
268
module BCDSubN(ci,a,b,o,co);
269
parameter N=34;
270
input ci;               // carry input
271
input [N*4-1:0] a;
272
input [N*4-1:0] b;
273
output reg [N*4-1:0] o;
274
output reg co;
275
 
276
reg [N*4:0] sum1, sum2, sum3, c;
277
reg [N*4-1:0] sixes;
278
always_comb
279
        sum1 = a - b;
280
always_comb
281
        sum2 = sum1 - {c,4'd0};
282
always_comb
283
        {co,o} = {c[N*4],sum3};
284
 
285
genvar g;
286
generate begin : gSixes
287
for (g = 0; g < N; g = g + 1)
288
begin
289
        always_comb
290
                c[g*4+3:g*4] = {3'b0,sum1[g*4+3:g*4] > 4'd9};
291
        always_comb
292
                if (g==0)
293
                        sixes[g*4+3:g*4] = (c[g*4] ? 4'd6 : 4'd0) | ci;
294
                else
295
                        sixes[g*4+3:g*4] = c[g*4] ? 4'd6 : 4'd0;
296
        always_comb
297
                sum3[g*4+3:g*4] = sum2[g*4+3:g*4] - sixes[g*4+3:g*4];
298
end
299
 
300
end
301
endgenerate
302
 
303
always_comb
304
        c[N*4] = 1'b0;
305
 
306
endmodule
307
*/
308
 
309
module BCDSubN(ci,a,b,o,co);
310
parameter N=24;
311
input ci;               // carry input
312
input [N*4-1:0] a;
313
input [N*4-1:0] b;
314
output [N*4-1:0] o;
315
output co;
316
 
317
genvar g;
318
generate begin : gBCDSubN
319
reg [4:0] hdN [0:N-1];
320
wire [N:0] c;
321
 
322
assign c[0] = ci;
323
assign co = c[N];
324
 
325
for (g = 0; g < N; g = g + 1)
326
        always @*
327
                hdN[g] = a[g*4+3:g*4] - b[g*4+3:g*4] - c[g];
328
 
329
for (g = 0; g < N; g = g + 1)
330
        BCDSubAdjust u1 (hdN[g],o[g*4+3:g*4],c[g+1]);
331
end
332
endgenerate
333
 
334
endmodule
335
 
336
 
337
module BCDAddAdjust(i,o,c);
338
input [4:0] i;
339
output [3:0] o;
340
reg [3:0] o;
341
output c;
342
reg c;
343
always @(i)
344
case(i)
345
5'h0: begin o = 4'h0; c = 1'b0; end
346
5'h1: begin o = 4'h1; c = 1'b0; end
347
5'h2: begin o = 4'h2; c = 1'b0; end
348
5'h3: begin o = 4'h3; c = 1'b0; end
349
5'h4: begin o = 4'h4; c = 1'b0; end
350
5'h5: begin o = 4'h5; c = 1'b0; end
351
5'h6: begin o = 4'h6; c = 1'b0; end
352
5'h7: begin o = 4'h7; c = 1'b0; end
353
5'h8: begin o = 4'h8; c = 1'b0; end
354
5'h9: begin o = 4'h9; c = 1'b0; end
355
5'hA: begin o = 4'h0; c = 1'b1; end
356
5'hB: begin o = 4'h1; c = 1'b1; end
357
5'hC: begin o = 4'h2; c = 1'b1; end
358
5'hD: begin o = 4'h3; c = 1'b1; end
359
5'hE: begin o = 4'h4; c = 1'b1; end
360
5'hF: begin o = 4'h5; c = 1'b1; end
361
5'h10:  begin o = 4'h6; c = 1'b1; end
362
5'h11:  begin o = 4'h7; c = 1'b1; end
363
5'h12:  begin o = 4'h8; c = 1'b1; end
364
5'h13:  begin o = 4'h9; c = 1'b1; end
365
default:        begin o = 4'h9; c = 1'b1; end
366
endcase
367
endmodule
368
 
369
module BCDSubAdjust(i,o,c);
370
input [4:0] i;
371
output [3:0] o;
372
reg [3:0] o;
373
output c;
374
reg c;
375
always @(i)
376
case(i)
377
5'h0: begin o = 4'h0; c = 1'b0; end
378
5'h1: begin o = 4'h1; c = 1'b0; end
379
5'h2: begin o = 4'h2; c = 1'b0; end
380
5'h3: begin o = 4'h3; c = 1'b0; end
381
5'h4: begin o = 4'h4; c = 1'b0; end
382
5'h5: begin o = 4'h5; c = 1'b0; end
383
5'h6: begin o = 4'h6; c = 1'b0; end
384
5'h7: begin o = 4'h7; c = 1'b0; end
385
5'h8: begin o = 4'h8; c = 1'b0; end
386
5'h9: begin o = 4'h9; c = 1'b0; end
387
5'h16: begin o = 4'h0; c = 1'b1; end
388
5'h17: begin o = 4'h1; c = 1'b1; end
389
5'h18: begin o = 4'h2; c = 1'b1; end
390
5'h19: begin o = 4'h3; c = 1'b1; end
391
5'h1A: begin o = 4'h4; c = 1'b1; end
392
5'h1B: begin o = 4'h5; c = 1'b1; end
393
5'h1C: begin o = 4'h6; c = 1'b1; end
394
5'h1D: begin o = 4'h7; c = 1'b1; end
395
5'h1E: begin o = 4'h8; c = 1'b1; end
396
5'h1F: begin o = 4'h9; c = 1'b1; end
397
default: begin o = 4'h9; c = 1'b1; end
398
endcase
399
endmodule
400
 
401
// Multiply two BCD digits
402
// Method used is table lookup
403
module BCDMul1(a,b,o);
404
input [3:0] a;
405
input [3:0] b;
406
output [7:0] o;
407
reg [7:0] o;
408
 
409
always @(a or b)
410
casex({a,b})
411
8'h00: o = 8'h00;
412
8'h01: o = 8'h00;
413
8'h02: o = 8'h00;
414
8'h03: o = 8'h00;
415
8'h04: o = 8'h00;
416
8'h05: o = 8'h00;
417
8'h06: o = 8'h00;
418
8'h07: o = 8'h00;
419
8'h08: o = 8'h00;
420
8'h09: o = 8'h00;
421
8'h10: o = 8'h00;
422
8'h11: o = 8'h01;
423
8'h12: o = 8'h02;
424
8'h13: o = 8'h03;
425
8'h14: o = 8'h04;
426
8'h15: o = 8'h05;
427
8'h16: o = 8'h06;
428
8'h17: o = 8'h07;
429
8'h18: o = 8'h08;
430
8'h19: o = 8'h09;
431
8'h20: o = 8'h00;
432
8'h21: o = 8'h02;
433
8'h22: o = 8'h04;
434
8'h23: o = 8'h06;
435
8'h24: o = 8'h08;
436
8'h25: o = 8'h10;
437
8'h26: o = 8'h12;
438
8'h27: o = 8'h14;
439
8'h28: o = 8'h16;
440
8'h29: o = 8'h18;
441
8'h30: o = 8'h00;
442
8'h31: o = 8'h03;
443
8'h32: o = 8'h06;
444
8'h33: o = 8'h09;
445
8'h34: o = 8'h12;
446
8'h35: o = 8'h15;
447
8'h36: o = 8'h18;
448
8'h37: o = 8'h21;
449
8'h38: o = 8'h24;
450
8'h39: o = 8'h27;
451
8'h40: o = 8'h00;
452
8'h41: o = 8'h04;
453
8'h42: o = 8'h08;
454
8'h43: o = 8'h12;
455
8'h44: o = 8'h16;
456
8'h45: o = 8'h20;
457
8'h46: o = 8'h24;
458
8'h47: o = 8'h28;
459
8'h48: o = 8'h32;
460
8'h49: o = 8'h36;
461
8'h50: o = 8'h00;
462
8'h51: o = 8'h05;
463
8'h52: o = 8'h10;
464
8'h53: o = 8'h15;
465
8'h54: o = 8'h20;
466
8'h55: o = 8'h25;
467
8'h56: o = 8'h30;
468
8'h57: o = 8'h35;
469
8'h58: o = 8'h40;
470
8'h59: o = 8'h45;
471
8'h60: o = 8'h00;
472
8'h61: o = 8'h06;
473
8'h62: o = 8'h12;
474
8'h63: o = 8'h18;
475
8'h64: o = 8'h24;
476
8'h65: o = 8'h30;
477
8'h66: o = 8'h36;
478
8'h67: o = 8'h42;
479
8'h68: o = 8'h48;
480
8'h69: o = 8'h54;
481
8'h70: o = 8'h00;
482
8'h71: o = 8'h07;
483
8'h72: o = 8'h14;
484
8'h73: o = 8'h21;
485
8'h74: o = 8'h28;
486
8'h75: o = 8'h35;
487
8'h76: o = 8'h42;
488
8'h77: o = 8'h49;
489
8'h78: o = 8'h56;
490
8'h79: o = 8'h63;
491
8'h80: o = 8'h00;
492
8'h81: o = 8'h08;
493
8'h82: o = 8'h16;
494
8'h83: o = 8'h24;
495
8'h84: o = 8'h32;
496
8'h85: o = 8'h40;
497
8'h86: o = 8'h48;
498
8'h87: o = 8'h56;
499
8'h88: o = 8'h64;
500
8'h89: o = 8'h72;
501
8'h90: o = 8'h00;
502
8'h91: o = 8'h09;
503
8'h92: o = 8'h18;
504
8'h93: o = 8'h27;
505
8'h94: o = 8'h36;
506
8'h95: o = 8'h45;
507
8'h96: o = 8'h54;
508
8'h97: o = 8'h63;
509
8'h98: o = 8'h72;
510
8'h99: o = 8'h81;
511
default:        o = 8'h00;
512
endcase
513
endmodule
514
 
515
 
516
// Multiply two pairs of BCD digits
517
// handles from 0x0 to 99x99
518
module BCDMul2(a,b,o);
519
input [7:0] a;
520
input [7:0] b;
521
output [15:0] o;
522
 
523
wire [7:0] p1,p2,p3,p4;
524
wire [15:0] s1;
525
 
526
BCDMul1 u1 (a[3:0],b[3:0],p1);
527
BCDMul1 u2 (a[7:4],b[3:0],p2);
528
BCDMul1 u3 (a[3:0],b[7:4],p3);
529
BCDMul1 u4 (a[7:4],b[7:4],p4);
530
 
531
BCDAdd4 u5 (1'b0,{p4,p1},{4'h0,p2,4'h0},s1);
532
BCDAdd4 u6 (1'b0,s1,{4'h0,p3,4'h0},o);
533
 
534
endmodule
535
 
536
module BCDMul4(a,b,o);
537
input [15:0] a;
538
input [15:0] b;
539
output [31:0] o;
540
 
541
wire [15:0] p1,p2,p3,p4;
542
wire [31:0] s1;
543
 
544
BCDMul2 u1 (a[7:0],b[7:0],p1);
545
BCDMul2 u2 (a[15:8],b[7:0],p2);
546
BCDMul2 u3 (a[7:0],b[15:8],p3);
547
BCDMul2 u4 (a[15:8],b[15:8],p4);
548
 
549
BCDAddN #(.N(8)) u5 (1'b0,{p4,p1},{8'h0,p2,8'h0},s1);
550
BCDAddN #(.N(8)) u6 (1'b0,s1,{8'h0,p3,8'h0},o);
551
 
552
endmodule
553
 
554
module BCDMul8(a,b,o);
555
input [31:0] a;
556
input [31:0] b;
557
output [63:0] o;
558
 
559
wire [31:0] p1,p2,p3,p4;
560
wire [63:0] s1;
561
 
562
BCDMul4 u1 (a[15:0],b[15:0],p1);
563
BCDMul4 u2 (a[31:16],b[15:0],p2);
564
BCDMul4 u3 (a[15:0],b[31:16],p3);
565
BCDMul4 u4 (a[31:16],b[31:16],p4);
566
 
567
BCDAddN #(.N(16)) u5 (1'b0,{p4,p1},{16'h0,p2,16'h0},s1);
568
BCDAddN #(.N(16)) u6 (1'b0,s1,{16'h0,p3,16'h0},o);
569
 
570
endmodule
571
 
572
module BCDMul16(a,b,o);
573
input [63:0] a;
574
input [63:0] b;
575
output [127:0] o;
576
 
577
wire [63:0] p1,p2,p3,p4;
578
wire [127:0] s1;
579
 
580
BCDMul8 u1 (a[31:0],b[31:0],p1);
581
BCDMul8 u2 (a[63:32],b[31:0],p2);
582
BCDMul8 u3 (a[31:0],b[63:32],p3);
583
BCDMul8 u4 (a[63:32],b[63:32],p4);
584
 
585
BCDAddN #(.N(32)) u5 (1'b0,{p4,p1},{32'h0,p2,32'h0},s1);
586
BCDAddN #(.N(32)) u6 (1'b0,s1,{32'h0,p3,32'h0},o);
587
 
588
endmodule
589
 
590
module BCDMul32(a,b,o);
591
input [127:0] a;
592
input [127:0] b;
593
output [255:0] o;
594
 
595
wire [127:0] p1,p2,p3,p4;
596
wire [255:0] s1;
597
 
598
BCDMul16 u1 (a[63:0],b[63:0],p1);
599
BCDMul16 u2 (a[127:64],b[63:0],p2);
600
BCDMul16 u3 (a[63:0],b[127:64],p3);
601
BCDMul16 u4 (a[127:64],b[127:64],p4);
602
 
603
BCDAddN #(.N(64)) u5 (1'b0,{p4,p1},{64'h0,p2,64'h0},s1);
604
BCDAddN #(.N(64)) u6 (1'b0,s1,{64'h0,p3,64'h0},o);
605
 
606
endmodule
607
 
608
module BCDMul_tb();
609
 
610
wire [15:0] o1,o2,o3,o4;
611
 
612
BCDMul2 u1 (8'h00,8'h00,o1);
613
BCDMul2 u2 (8'h99,8'h99,o2);
614
BCDMul2 u3 (8'h25,8'h18,o3);
615
BCDMul2 u4 (8'h37,8'h21,o4);
616
 
617
endmodule
618
 
619
module BinToBCD(i, o);
620
input [7:0] i;
621
output [11:0] o;
622
 
623
reg [11:0] tbl [0:255];
624
 
625
genvar g;
626
generate begin : gTbl
627
reg [3:0] n0 [0:255];
628
reg [3:0] n1 [0:255];
629
reg [3:0] n2 [0:255];
630
 
631
for (g = 0; g < 256; g = g + 1) begin
632
        initial begin
633
                n0[g] = g % 10;
634
                n1[g] = g / 10;
635
                n2[g] = g / 100;
636
                tbl[g] <= {n2[g],n1[g],n0[g]};
637
        end
638
end
639
 
640
assign o = tbl[i];
641
 
642
end
643
endgenerate
644
 
645
endmodule
646
 
647
// Perform a logical shift to the right.
648
module BCDSRL(ci, i, o, co);
649
parameter N=4;
650
input ci;
651
input [N*4-1:0] i;
652
output reg [N*4-1:0] o;
653
output co;
654
 
655
reg [N:0] c;
656
 
657
genvar g;
658
generate begin
659
always_comb
660
        c[N] = ci;
661
for (g = N - 1; g >= 0; g = g - 1)
662
always_comb
663
        c[g] = i[g*4];
664
for (g = N - 1; g >= 0; g = g - 1)
665
always_comb
666
begin
667
        o[g*4+3:g*4] = {1'b0,i[g*4+3:g*4+1]};
668
        // Because there is a divide by two, the value will range between 0 and 4.
669
        // Adding 5 keeps it within deicmal boundaries of 0 to 9. No carry can be
670
        // generated
671
        if (c[N+1])
672
                o[g*4+3:g*4] = o[g*4+3:g*4] + 4'd5;
673
end
674
        assign co = c[0];
675
end
676
endgenerate
677
 
678
endmodule

powered by: WebSVN 2.1.0

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