URL
https://opencores.org/ocsvn/ft816float/ft816float/trunk
Subversion Repositories ft816float
Compare Revisions
- This comparison shows the changes necessary to convert path
/ft816float/trunk/rtl/verilog2
- from Rev 65 to Rev 66
- ↔ Reverse comparison
Rev 65 → Rev 66
/BCDAdd8NClk.sv
0,0 → 1,105
`timescale 1ns / 1ps |
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2012-2022 Robert Finch, Waterloo |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@finitron.ca |
// || |
// |
// BCDAdd8NClk.sv |
// |
// BSD 3-Clause License |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are met: |
// |
// 1. Redistributions of source code must retain the above copyright notice, this |
// list of conditions and the following disclaimer. |
// |
// 2. Redistributions in binary form must reproduce the above copyright notice, |
// this list of conditions and the following disclaimer in the documentation |
// and/or other materials provided with the distribution. |
// |
// 3. Neither the name of the copyright holder nor the names of its |
// contributors may be used to endorse or promote products derived from |
// this software without specific prior written permission. |
// |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// |
// ============================================================================ |
// |
// The following added breaks up the carry chain. |
// |
// The adder is organized into three rows and N*2 columns of digits. The first |
// row is set to the input a, b operands. The carry for the first row and column |
// is set to the carry input. The operands in a row are added without taking |
// carry into consideration. But the carry out is recorded and added as the 'B' |
// operand in the next row. The sum from one row is fed as the 'A' operand into |
// the next row. Values (sum and carry) are moved between rows in a clocked |
// fashion. The first row contains full BCD adders. After that only a single |
// bit is added. |
// |
// There cannot be more than three rows required. The worst case scenario occurs |
// when all the inputs are at a max and there is a carry input. This generates a |
// carry output from each digit in the second row. |
// |
// In that case |
// 99999999 |
// + 99999999 |
// + 1 (carry in) |
//--------------- |
// 188888889 <- first row result |
// + 11111110 <- carries out of first row |
//--------------- |
// 199999999 <- second row result |
|
module BCDAdd8NClk(clk, ld, a, b, o, ci, co, done); |
parameter N=33; |
input clk; |
input ld; |
input [N*8-1:0] a; |
input [N*8-1:0] b; |
output reg [N*8-1:0] o; |
input ci; |
output reg co; |
output reg done; |
|
reg [N-1:0] c [0:2]; |
wire [N*8-1:0] o1 [0:2]; |
reg [N*8-1:0] o2 [0:2]; |
wire [N:0] d [0:2]; |
|
genvar g,k; |
generate begin : gBCDadd |
for (g = 0; g < N; g = g + 1) begin |
for (k = 0; k < 3; k = k + 1) begin |
BCDAdd u1 ( |
.ci(k==0 && g==0 ? ci : 1'b0), |
.a(k==0 ? a[g*8+7:g*8] : o2[k-1][g*8+7:g*8]), |
.b(k==0 ? b[g*8+7:g*8] : {7'h00,c[k-1][g]}), |
.o(o1[k][g*8+7:g*8]), |
.c(d[k][g]) |
); |
always_ff @(posedge clk) |
o2[k] <= o1[k]; |
always_ff @(posedge clk) |
c[k][g] <= d[k][g]; |
end |
end |
always_ff @(posedge clk) |
begin |
o <= o1[2]; |
co <= c[2][N-1]; |
end |
end |
endgenerate |
endmodule |
|
/BCDMath.sv
0,0 → 1,593
`timescale 1ns / 1ps |
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2012-2022 Robert Finch, Waterloo |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@finitron.ca |
// || |
// |
// BCDMath.sv |
// |
// BSD 3-Clause License |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are met: |
// |
// 1. Redistributions of source code must retain the above copyright notice, this |
// list of conditions and the following disclaimer. |
// |
// 2. Redistributions in binary form must reproduce the above copyright notice, |
// this list of conditions and the following disclaimer in the documentation |
// and/or other materials provided with the distribution. |
// |
// 3. Neither the name of the copyright holder nor the names of its |
// contributors may be used to endorse or promote products derived from |
// this software without specific prior written permission. |
// |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// |
// ============================================================================ |
// |
// Could use the following approach for add/sub but it ends up being larger |
// than using an adjustment lookup table. |
|
module BCDAddNyb(ci,a,b,o,c); |
input ci; // carry input |
input [3:0] a; |
input [3:0] b; |
output [3:0] o; |
output c; |
|
wire c0; |
|
reg [4:0] hsN0; |
always @* |
begin |
hsN0 = a[3:0] + b[3:0] + ci; |
if (hsN0 > 5'd9) |
hsN0 = hsN0 + 3'd6; |
end |
assign o = hsN0[3:0]; |
assign c = hsN0[4]; |
|
endmodule |
|
module BCDAdd(ci,a,b,o,c); |
input ci; // carry input |
input [7:0] a; |
input [7:0] b; |
output [7:0] o; |
output c; |
|
wire c0,c1; |
|
wire [4:0] hsN0 = a[3:0] + b[3:0] + ci; |
wire [4:0] hsN1 = a[7:4] + b[7:4] + c0; |
|
BCDAddAdjust u1 (hsN0,o[3:0],c0); |
BCDAddAdjust u2 (hsN1,o[7:4],c); |
|
endmodule |
|
module BCDAdd4(ci,a,b,o,c,c8); |
input ci; // carry input |
input [15:0] a; |
input [15:0] b; |
output [15:0] o; |
output c; |
output c8; |
|
wire c0,c1,c2; |
assign c8 = c1; |
|
wire [4:0] hsN0 = a[3:0] + b[3:0] + ci; |
wire [4:0] hsN1 = a[7:4] + b[7:4] + c0; |
wire [4:0] hsN2 = a[11:8] + b[11:8] + c1; |
wire [4:0] hsN3 = a[15:12] + b[15:12] + c2; |
|
BCDAddAdjust u1 (hsN0,o[3:0],c0); |
BCDAddAdjust u2 (hsN1,o[7:4],c1); |
BCDAddAdjust u3 (hsN2,o[11:8],c2); |
BCDAddAdjust u4 (hsN3,o[15:12],c); |
|
endmodule |
|
module BCDAddN(ci,a,b,o,co); |
parameter N=24; |
input ci; // carry input |
input [N*4-1:0] a; |
input [N*4-1:0] b; |
output [N*4-1:0] o; |
output co; |
|
genvar g; |
generate begin : gBCDAddN |
reg [4:0] hsN [0:N-1]; |
wire [N:0] c; |
|
assign c[0] = ci; |
assign co = c[N]; |
|
for (g = 0; g < N; g = g + 1) |
always @* |
hsN[g] = a[g*4+3:g*4] + b[g*4+3:g*4] + c[g]; |
|
for (g = 0; g < N; g = g + 1) |
BCDAddAdjust u1 (hsN[g],o[g*4+3:g*4],c[g+1]); |
end |
endgenerate |
|
endmodule |
/* |
module BCDAdd8NClk(clk, a, b, o, ci, co); |
parameter N=33; |
input clk; |
input [N*8-1:0] a; |
input [N*8-1:0] b; |
output [N*8-1:0] o; |
input ci; |
output co; |
|
reg [N:0] c; |
wire [N:0] d; |
assign c[0] = ci; |
assign co = c[N]; |
|
genvar g; |
generate begin : gBCDadd |
for (g = 0; g < N; g = g + 1) begin |
BCDAdd u1 (c[g],a[g*8+7:g*8],b[g*8+7:g*8],o[g*8+7:g*8],d[g+1]); |
|
always_ff @(posedge clk) |
c[g+1] <= d[g+1]; |
end |
end |
endgenerate |
endmodule |
*/ |
|
module BCDSub(ci,a,b,o,c); |
input ci; // carry input |
input [7:0] a; |
input [7:0] b; |
output [7:0] o; |
output c; |
|
wire c0,c1; |
|
wire [4:0] hdN0 = a[3:0] - b[3:0] - ci; |
wire [4:0] hdN1 = a[7:4] - b[7:4] - c0; |
|
BCDSubAdjust u1 (hdN0,o[3:0],c0); |
BCDSubAdjust u2 (hdN1,o[7:4],c); |
|
endmodule |
|
module BCDSub4(ci,a,b,o,c,c8); |
input ci; // carry input |
input [15:0] a; |
input [15:0] b; |
output [15:0] o; |
output c; |
output c8; |
|
wire c0,c1,c2; |
assign c8 = c1; |
|
wire [4:0] hdN0 = a[3:0] - b[3:0] - ci; |
wire [4:0] hdN1 = a[7:4] - b[7:4] - c0; |
wire [4:0] hdN2 = a[11:8] - b[11:8] - c1; |
wire [4:0] hdN3 = a[15:12] - b[15:12] - c2; |
|
BCDSubAdjust u1 (hdN0,o[3:0],c0); |
BCDSubAdjust u2 (hdN1,o[7:4],c1); |
BCDSubAdjust u3 (hdN2,o[11:8],c2); |
BCDSubAdjust u4 (hdN3,o[15:12],c); |
|
endmodule |
|
module BCDSubN(ci,a,b,o,co); |
parameter N=24; |
input ci; // carry input |
input [N*4-1:0] a; |
input [N*4-1:0] b; |
output [N*4-1:0] o; |
output co; |
|
genvar g; |
generate begin : gBCDSubN |
reg [4:0] hdN [0:N-1]; |
wire [N:0] c; |
|
assign c[0] = ci; |
assign co = c[N]; |
|
for (g = 0; g < N; g = g + 1) |
always @* |
hdN[g] = a[g*4+3:g*4] - b[g*4+3:g*4] - c[g]; |
|
for (g = 0; g < N; g = g + 1) |
BCDSubAdjust u1 (hdN[g],o[g*4+3:g*4],c[g+1]); |
end |
endgenerate |
|
endmodule |
|
/* |
module BCDSub8NClk(clk, a, b, o, ci, co); |
parameter N=33; |
input clk; |
input [N*8-1:0] a; |
input [N*8-1:0] b; |
output [N*8-1:0] o; |
input ci; |
output co; |
|
reg [N:0] c; |
wire [N:0] d; |
assign c[0] = ci; |
assign co = c[N]; |
|
genvar g; |
generate begin : gBCDsub |
for (g = 0; g < N; g = g + 1) begin |
BCDSub u1 (c[g],a[g*8+7:g*8],b[g*8+7:g*8],o[g*8+7:g*8],d[g+1]); |
|
always_ff @(posedge clk) |
c[g+1] <= d[g+1]; |
end |
end |
endgenerate |
endmodule |
*/ |
|
module BCDAddAdjust(i,o,c); |
input [4:0] i; |
output [3:0] o; |
reg [3:0] o; |
output c; |
reg c; |
always @(i) |
case(i) |
5'h0: begin o = 4'h0; c = 1'b0; end |
5'h1: begin o = 4'h1; c = 1'b0; end |
5'h2: begin o = 4'h2; c = 1'b0; end |
5'h3: begin o = 4'h3; c = 1'b0; end |
5'h4: begin o = 4'h4; c = 1'b0; end |
5'h5: begin o = 4'h5; c = 1'b0; end |
5'h6: begin o = 4'h6; c = 1'b0; end |
5'h7: begin o = 4'h7; c = 1'b0; end |
5'h8: begin o = 4'h8; c = 1'b0; end |
5'h9: begin o = 4'h9; c = 1'b0; end |
5'hA: begin o = 4'h0; c = 1'b1; end |
5'hB: begin o = 4'h1; c = 1'b1; end |
5'hC: begin o = 4'h2; c = 1'b1; end |
5'hD: begin o = 4'h3; c = 1'b1; end |
5'hE: begin o = 4'h4; c = 1'b1; end |
5'hF: begin o = 4'h5; c = 1'b1; end |
5'h10: begin o = 4'h6; c = 1'b1; end |
5'h11: begin o = 4'h7; c = 1'b1; end |
5'h12: begin o = 4'h8; c = 1'b1; end |
5'h13: begin o = 4'h9; c = 1'b1; end |
default: begin o = 4'h9; c = 1'b1; end |
endcase |
endmodule |
|
module BCDSubAdjust(i,o,c); |
input [4:0] i; |
output [3:0] o; |
reg [3:0] o; |
output c; |
reg c; |
always @(i) |
case(i) |
5'h0: begin o = 4'h0; c = 1'b0; end |
5'h1: begin o = 4'h1; c = 1'b0; end |
5'h2: begin o = 4'h2; c = 1'b0; end |
5'h3: begin o = 4'h3; c = 1'b0; end |
5'h4: begin o = 4'h4; c = 1'b0; end |
5'h5: begin o = 4'h5; c = 1'b0; end |
5'h6: begin o = 4'h6; c = 1'b0; end |
5'h7: begin o = 4'h7; c = 1'b0; end |
5'h8: begin o = 4'h8; c = 1'b0; end |
5'h9: begin o = 4'h9; c = 1'b0; end |
5'h16: begin o = 4'h0; c = 1'b1; end |
5'h17: begin o = 4'h1; c = 1'b1; end |
5'h18: begin o = 4'h2; c = 1'b1; end |
5'h19: begin o = 4'h3; c = 1'b1; end |
5'h1A: begin o = 4'h4; c = 1'b1; end |
5'h1B: begin o = 4'h5; c = 1'b1; end |
5'h1C: begin o = 4'h6; c = 1'b1; end |
5'h1D: begin o = 4'h7; c = 1'b1; end |
5'h1E: begin o = 4'h8; c = 1'b1; end |
5'h1F: begin o = 4'h9; c = 1'b1; end |
default: begin o = 4'h9; c = 1'b1; end |
endcase |
endmodule |
|
// Multiply two BCD digits |
// Method used is table lookup |
module BCDMul1(a,b,o); |
input [3:0] a; |
input [3:0] b; |
output [7:0] o; |
reg [7:0] o; |
|
always @(a or b) |
casex({a,b}) |
8'h00: o = 8'h00; |
8'h01: o = 8'h00; |
8'h02: o = 8'h00; |
8'h03: o = 8'h00; |
8'h04: o = 8'h00; |
8'h05: o = 8'h00; |
8'h06: o = 8'h00; |
8'h07: o = 8'h00; |
8'h08: o = 8'h00; |
8'h09: o = 8'h00; |
8'h10: o = 8'h00; |
8'h11: o = 8'h01; |
8'h12: o = 8'h02; |
8'h13: o = 8'h03; |
8'h14: o = 8'h04; |
8'h15: o = 8'h05; |
8'h16: o = 8'h06; |
8'h17: o = 8'h07; |
8'h18: o = 8'h08; |
8'h19: o = 8'h09; |
8'h20: o = 8'h00; |
8'h21: o = 8'h02; |
8'h22: o = 8'h04; |
8'h23: o = 8'h06; |
8'h24: o = 8'h08; |
8'h25: o = 8'h10; |
8'h26: o = 8'h12; |
8'h27: o = 8'h14; |
8'h28: o = 8'h16; |
8'h29: o = 8'h18; |
8'h30: o = 8'h00; |
8'h31: o = 8'h03; |
8'h32: o = 8'h06; |
8'h33: o = 8'h09; |
8'h34: o = 8'h12; |
8'h35: o = 8'h15; |
8'h36: o = 8'h18; |
8'h37: o = 8'h21; |
8'h38: o = 8'h24; |
8'h39: o = 8'h27; |
8'h40: o = 8'h00; |
8'h41: o = 8'h04; |
8'h42: o = 8'h08; |
8'h43: o = 8'h12; |
8'h44: o = 8'h16; |
8'h45: o = 8'h20; |
8'h46: o = 8'h24; |
8'h47: o = 8'h28; |
8'h48: o = 8'h32; |
8'h49: o = 8'h36; |
8'h50: o = 8'h00; |
8'h51: o = 8'h05; |
8'h52: o = 8'h10; |
8'h53: o = 8'h15; |
8'h54: o = 8'h20; |
8'h55: o = 8'h25; |
8'h56: o = 8'h30; |
8'h57: o = 8'h35; |
8'h58: o = 8'h40; |
8'h59: o = 8'h45; |
8'h60: o = 8'h00; |
8'h61: o = 8'h06; |
8'h62: o = 8'h12; |
8'h63: o = 8'h18; |
8'h64: o = 8'h24; |
8'h65: o = 8'h30; |
8'h66: o = 8'h36; |
8'h67: o = 8'h42; |
8'h68: o = 8'h48; |
8'h69: o = 8'h54; |
8'h70: o = 8'h00; |
8'h71: o = 8'h07; |
8'h72: o = 8'h14; |
8'h73: o = 8'h21; |
8'h74: o = 8'h28; |
8'h75: o = 8'h35; |
8'h76: o = 8'h42; |
8'h77: o = 8'h49; |
8'h78: o = 8'h56; |
8'h79: o = 8'h63; |
8'h80: o = 8'h00; |
8'h81: o = 8'h08; |
8'h82: o = 8'h16; |
8'h83: o = 8'h24; |
8'h84: o = 8'h32; |
8'h85: o = 8'h40; |
8'h86: o = 8'h48; |
8'h87: o = 8'h56; |
8'h88: o = 8'h64; |
8'h89: o = 8'h72; |
8'h90: o = 8'h00; |
8'h91: o = 8'h09; |
8'h92: o = 8'h18; |
8'h93: o = 8'h27; |
8'h94: o = 8'h36; |
8'h95: o = 8'h45; |
8'h96: o = 8'h54; |
8'h97: o = 8'h63; |
8'h98: o = 8'h72; |
8'h99: o = 8'h81; |
default: o = 8'h00; |
endcase |
endmodule |
|
|
// Multiply two pairs of BCD digits |
// handles from 0x0 to 99x99 |
module BCDMul2(a,b,o); |
input [7:0] a; |
input [7:0] b; |
output [15:0] o; |
|
wire [7:0] p1,p2,p3,p4; |
wire [15:0] s1; |
|
BCDMul1 u1 (a[3:0],b[3:0],p1); |
BCDMul1 u2 (a[7:4],b[3:0],p2); |
BCDMul1 u3 (a[3:0],b[7:4],p3); |
BCDMul1 u4 (a[7:4],b[7:4],p4); |
|
BCDAdd4 u5 (1'b0,{p4,p1},{4'h0,p2,4'h0},s1); |
BCDAdd4 u6 (1'b0,s1,{4'h0,p3,4'h0},o); |
|
endmodule |
|
module BCDMul4(a,b,o); |
input [15:0] a; |
input [15:0] b; |
output [31:0] o; |
|
wire [15:0] p1,p2,p3,p4; |
wire [31:0] s1; |
|
BCDMul2 u1 (a[7:0],b[7:0],p1); |
BCDMul2 u2 (a[15:8],b[7:0],p2); |
BCDMul2 u3 (a[7:0],b[15:8],p3); |
BCDMul2 u4 (a[15:8],b[15:8],p4); |
|
BCDAddN #(.N(8)) u5 (1'b0,{p4,p1},{8'h0,p2,8'h0},s1); |
BCDAddN #(.N(8)) u6 (1'b0,s1,{8'h0,p3,8'h0},o); |
|
endmodule |
|
module BCDMul8(a,b,o); |
input [31:0] a; |
input [31:0] b; |
output [63:0] o; |
|
wire [31:0] p1,p2,p3,p4; |
wire [63:0] s1; |
|
BCDMul4 u1 (a[15:0],b[15:0],p1); |
BCDMul4 u2 (a[31:16],b[15:0],p2); |
BCDMul4 u3 (a[15:0],b[31:16],p3); |
BCDMul4 u4 (a[31:16],b[31:16],p4); |
|
BCDAddN #(.N(16)) u5 (1'b0,{p4,p1},{16'h0,p2,16'h0},s1); |
BCDAddN #(.N(16)) u6 (1'b0,s1,{16'h0,p3,16'h0},o); |
|
endmodule |
|
module BCDMul16(a,b,o); |
input [63:0] a; |
input [63:0] b; |
output [127:0] o; |
|
wire [63:0] p1,p2,p3,p4; |
wire [127:0] s1; |
|
BCDMul8 u1 (a[31:0],b[31:0],p1); |
BCDMul8 u2 (a[63:32],b[31:0],p2); |
BCDMul8 u3 (a[31:0],b[63:32],p3); |
BCDMul8 u4 (a[63:32],b[63:32],p4); |
|
BCDAddN #(.N(32)) u5 (1'b0,{p4,p1},{32'h0,p2,32'h0},s1); |
BCDAddN #(.N(32)) u6 (1'b0,s1,{32'h0,p3,32'h0},o); |
|
endmodule |
|
module BCDMul32(a,b,o); |
input [127:0] a; |
input [127:0] b; |
output [255:0] o; |
|
wire [127:0] p1,p2,p3,p4; |
wire [255:0] s1; |
|
BCDMul16 u1 (a[63:0],b[63:0],p1); |
BCDMul16 u2 (a[127:64],b[63:0],p2); |
BCDMul16 u3 (a[63:0],b[127:64],p3); |
BCDMul16 u4 (a[127:64],b[127:64],p4); |
|
BCDAddN #(.N(64)) u5 (1'b0,{p4,p1},{64'h0,p2,64'h0},s1); |
BCDAddN #(.N(64)) u6 (1'b0,s1,{64'h0,p3,64'h0},o); |
|
endmodule |
|
module BCDMul_tb(); |
|
wire [15:0] o1,o2,o3,o4; |
|
BCDMul2 u1 (8'h00,8'h00,o1); |
BCDMul2 u2 (8'h99,8'h99,o2); |
BCDMul2 u3 (8'h25,8'h18,o3); |
BCDMul2 u4 (8'h37,8'h21,o4); |
|
endmodule |
|
module BinToBCD(i, o); |
input [7:0] i; |
output [11:0] o; |
|
reg [11:0] tbl [0:255]; |
|
genvar g; |
generate begin : gTbl |
reg [3:0] n0 [0:255]; |
reg [3:0] n1 [0:255]; |
reg [3:0] n2 [0:255]; |
|
for (g = 0; g < 256; g = g + 1) begin |
initial begin |
n0[g] = g % 10; |
n1[g] = g / 10; |
n2[g] = g / 100; |
tbl[g] <= {n2[g],n1[g],n0[g]}; |
end |
end |
|
assign o = tbl[i]; |
|
end |
endgenerate |
|
endmodule |
|
// Perform a logical shift to the right. |
module BCDSRL(ci, i, o, co); |
parameter N=4; |
input ci; |
input [N*4-1:0] i; |
output reg [N*4-1:0] o; |
output co; |
|
reg [N:0] c; |
|
genvar g; |
generate begin |
always @* |
c[N] = ci; |
for (g = N - 1; g >= 0; g = g - 1) |
always @* |
c[g] = i[g*4]; |
for (g = N - 1; g >= 0; g = g - 1) |
always @* |
begin |
o[g*4+3:g*4] = {1'b0,i[g*4+3:g*4+1]}; |
// Because there is a divide by two, the value will range between 0 and 4. |
// Adding 5 keeps it within deicmal boundaries of 0 to 9. No carry can be |
// generated |
if (c[N+1]) |
o[g*4+3:g*4] = o[g*4+3:g*4] + 4'd5; |
end |
assign co = c[0]; |
end |
endgenerate |
|
endmodule |
/BCDSub8NClk.sv
0,0 → 1,105
`timescale 1ns / 1ps |
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2012-2022 Robert Finch, Waterloo |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@finitron.ca |
// || |
// |
// BCDSub8NClk.sv |
// |
// BSD 3-Clause License |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are met: |
// |
// 1. Redistributions of source code must retain the above copyright notice, this |
// list of conditions and the following disclaimer. |
// |
// 2. Redistributions in binary form must reproduce the above copyright notice, |
// this list of conditions and the following disclaimer in the documentation |
// and/or other materials provided with the distribution. |
// |
// 3. Neither the name of the copyright holder nor the names of its |
// contributors may be used to endorse or promote products derived from |
// this software without specific prior written permission. |
// |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// |
// ============================================================================ |
// |
// The following added breaks up the carry chain. |
// |
// The adder is organized into three rows and N*2 columns of digits. The first |
// row is set to the input a, b operands. The carry for the first row and column |
// is set to the carry input. The operands in a row are added without taking |
// carry into consideration. But the carry out is recorded and added as the 'B' |
// operand in the next row. The sum from one row is fed as the 'A' operand into |
// the next row. Values (sum and carry) are moved between rows in a clocked |
// fashion. The first row contains full BCD adders. After that only a single |
// bit is added. |
// |
// There cannot be more than three rows required. The worst case scenario occurs |
// when all the inputs are at a max and there is a carry input. This generates a |
// carry output from each digit in the second row. |
// |
// In that case |
// 99999999 |
// + 99999999 |
// + 1 (carry in) |
//--------------- |
// 188888889 <- first row result |
// + 11111110 <- carries out of first row |
//--------------- |
// 199999999 <- second row result |
|
module BCDSub8NClk(clk, ld, a, b, o, ci, co, done); |
parameter N=33; |
input clk; |
input ld; |
input [N*8-1:0] a; |
input [N*8-1:0] b; |
output reg [N*8-1:0] o; |
input ci; |
output reg co; |
output reg done; |
|
reg [N-1:0] c [0:2]; |
wire [N*8-1:0] o1 [0:2]; |
reg [N*8-1:0] o2 [0:2]; |
wire [N:0] d [0:2]; |
|
genvar g,k; |
generate begin : gBCDadd |
for (g = 0; g < N; g = g + 1) begin |
for (k = 0; k < 3; k = k + 1) begin |
BCDSub u1 ( |
.ci(k==0 && g==0 ? ci : 1'b0), |
.a(k==0 ? a[g*8+7:g*8] : o2[k-1][g*8+7:g*8]), |
.b(k==0 ? b[g*8+7:g*8] : {7'h00,c[k-1][g]}), |
.o(o1[k][g*8+7:g*8]), |
.c(d[k][g]) |
); |
always_ff @(posedge clk) |
o2[k] <= o1[k]; |
always_ff @(posedge clk) |
c[k][g] <= d[k][g]; |
end |
end |
always_ff @(posedge clk) |
begin |
o <= o1[2]; |
co <= c[2][N-1]; |
end |
end |
endgenerate |
endmodule |
|