From 12c34c25f3f122c90b8a99f6fdb4590f721fe0d2 Mon Sep 17 00:00:00 2001 From: "James E. Stine" Date: Mon, 31 May 2021 08:36:19 -0400 Subject: [PATCH] Modify elements of generics for LZD and shifter wrote for integer divider. --- wally-pipelined/src/generic/lzd.sv | 195 +++++++++++++++++++++++++++ wally-pipelined/src/generic/lzd.sv~ | 195 +++++++++++++++++++++++++++ wally-pipelined/src/generic/shift.sv | 76 +++++++++++ wally-pipelined/src/muldiv/div.sv | 146 +------------------- 4 files changed, 471 insertions(+), 141 deletions(-) create mode 100755 wally-pipelined/src/generic/lzd.sv create mode 100755 wally-pipelined/src/generic/lzd.sv~ create mode 100755 wally-pipelined/src/generic/shift.sv diff --git a/wally-pipelined/src/generic/lzd.sv b/wally-pipelined/src/generic/lzd.sv new file mode 100755 index 00000000..98642c15 --- /dev/null +++ b/wally-pipelined/src/generic/lzd.sv @@ -0,0 +1,195 @@ +/////////////////////////////////////////// +// lzd.sv +// +// Written: James.Stine@okstate.edu 1 February 2021 +// Modified: +// +// Purpose: Integer Divide instructions +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" +/* verilator lint_off DECLFILENAME */ + +// Original idea came from V. G. Oklobdzija, "An algorithmic and novel +// design of a leading zero detector circuit: comparison with logic +// synthesis," in IEEE Transactions on Very Large Scale Integration +// (VLSI) Systems, vol. 2, no. 1, pp. 124-128, March 1994, doi: +// 10.1109/92.273153. + +// Modified to be more hierarchical + +module lzd2 (P, V, B); + + input logic [1:0] B; + + output logic P; + output logic V; + + assign V = B[0] | B[1]; + assign P = B[0] & ~B[1]; + +endmodule // lz2 + +module lzd_hier #(parameter WIDTH=8) + (input logic [WIDTH-1:0] B, + output logic [$clog2(WIDTH)-1:0] ZP, + output logic ZV); + + if (WIDTH == 128) + lzd128 lz127 (ZP, ZV, B); + else if (WIDTH == 64) + lzd64 lz64 (ZP, ZV, B); + else if (WIDTH == 32) + lzd32 lz32 (ZP, ZV, B); + else if (WIDTH == 16) + lzd16 lz16 (ZP, ZV, B); + else if (WIDTH == 8) + lzd8 lz8 (ZP, ZV, B); + else if (WIDTH == 4) + lzd4 lz4 (ZP, ZV, B); + +endmodule // lzd_hier + +module lzd4 (ZP, ZV, B); + + input logic [3:0] B; + + logic ZPa; + logic ZPb; + logic ZVa; + logic ZVb; + + output logic [1:0] ZP; + output logic ZV; + + lz2 l1(ZPa, ZVa, B[1:0]); + lz2 l2(ZPb, ZVb, B[3:2]); + + assign ZP[0:0] = ZVb ? ZPb : ZPa; + assign ZP[1] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule // lzd4 + +module lzd8 (ZP, ZV, B); + + input logic [7:0] B; + + logic [1:0] ZPa; + logic [1:0] ZPb; + logic ZVa; + logic ZVb; + + output logic [2:0] ZP; + output logic ZV; + + lz4 l1(ZPa, ZVa, B[3:0]); + lz4 l2(ZPb, ZVb, B[7:4]); + + assign ZP[1:0] = ZVb ? ZPb : ZPa; + assign ZP[2] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule // lzd8 + +module lzd16 (ZP, ZV, B); + + input logic [15:0] B; + + logic [2:0] ZPa; + logic [2:0] ZPb; + logic ZVa; + logic ZVb; + + output logic [3:0] ZP; + output logic ZV; + + lz8 l1(ZPa, ZVa, B[7:0]); + lz8 l2(ZPb, ZVb, B[15:8]); + + assign ZP[2:0] = ZVb ? ZPb : ZPa; + assign ZP[3] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule // lzd16 + +module lzd32 (ZP, ZV, B); + + input logic [31:0] B; + + logic [3:0] ZPa; + logic [3:0] ZPb; + logic ZVa; + logic ZVb; + + output logic [4:0] ZP; + output logic ZV; + + lz16 l1(ZPa, ZVa, B[15:0]); + lz16 l2(ZPb, ZVb, B[31:16]); + + assign ZP[3:0] = ZVb ? ZPb : ZPa; + assign ZP[4] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule // lzd32 + +module lzd64 (ZP, ZV, B); + + input logic [63:0] B; + + logic [4:0] ZPa; + logic [4:0] ZPb; + logic ZVa; + logic ZVb; + + output logic [5:0] ZP; + output logic ZV; + + lz32 l1(ZPa, ZVa, B[31:0]); + lz32 l2(ZPb, ZVb, B[63:32]); + + assign ZP[4:0] = ZVb ? ZPb : ZPa; + assign ZP[5] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule // lzd64 + +module lzd128 (ZP, ZV, B); + + input logic [127:0] B; + + logic [5:0] ZPa; + logic [5:0] ZPb; + logic ZVa; + logic ZVb; + + output logic [6:0] ZP; + output logic ZV; + + lz64 l1(ZPa, ZVa, B[64:0]); + lz64 l2(ZPb, ZVb, B[127:63]); + + assign ZP[5:0] = ZVb ? ZPb : ZPa; + assign ZP[6] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule // lzd128 + +/* verilator lint_on DECLFILENAME */ diff --git a/wally-pipelined/src/generic/lzd.sv~ b/wally-pipelined/src/generic/lzd.sv~ new file mode 100755 index 00000000..bfffe5e5 --- /dev/null +++ b/wally-pipelined/src/generic/lzd.sv~ @@ -0,0 +1,195 @@ +/////////////////////////////////////////// +// lzd.sv +// +// Written: James.Stine@okstate.edu 1 February 2021 +// Modified: +// +// Purpose: Integer Divide instructions +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" +/* verilator lint_off DECLFILENAME */ + +// Original idea came from V. G. Oklobdzija, "An algorithmic and novel +// design of a leading zero detector circuit: comparison with logic +// synthesis," in IEEE Transactions on Very Large Scale Integration +// (VLSI) Systems, vol. 2, no. 1, pp. 124-128, March 1994, doi: +// 10.1109/92.273153. + +// Modified to be more hierarchical + +module lz2 (P, V, B); + + input logic [1:0] B; + + output logic P; + output logic V; + + assign V = B[0] | B[1]; + assign P = B[0] & ~B[1]; + +endmodule // lz2 + +module lzd_hier #(parameter WIDTH=8) + (input logic [WIDTH-1:0] B, + output logic [$clog2(WIDTH)-1:0] ZP, + output logic ZV); + + if (WIDTH == 128) + lz128 lzd127 (ZP, ZV, B); + else if (WIDTH == 64) + lz64 lzd64 (ZP, ZV, B); + else if (WIDTH == 32) + lz32 lzd32 (ZP, ZV, B); + else if (WIDTH == 16) + lz16 lzd16 (ZP, ZV, B); + else if (WIDTH == 8) + lz8 lzd8 (ZP, ZV, B); + else if (WIDTH == 4) + lz4 lzd4 (ZP, ZV, B); + +endmodule // lzd_hier + +module lz4 (ZP, ZV, B); + + input logic [3:0] B; + + logic ZPa; + logic ZPb; + logic ZVa; + logic ZVb; + + output logic [1:0] ZP; + output logic ZV; + + lz2 l1(ZPa, ZVa, B[1:0]); + lz2 l2(ZPb, ZVb, B[3:2]); + + assign ZP[0:0] = ZVb ? ZPb : ZPa; + assign ZP[1] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule + +module lz8 (ZP, ZV, B); + + input logic [7:0] B; + + logic [1:0] ZPa; + logic [1:0] ZPb; + logic ZVa; + logic ZVb; + + output logic [2:0] ZP; + output logic ZV; + + lz4 l1(ZPa, ZVa, B[3:0]); + lz4 l2(ZPb, ZVb, B[7:4]); + + assign ZP[1:0] = ZVb ? ZPb : ZPa; + assign ZP[2] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule + +module lz16 (ZP, ZV, B); + + input logic [15:0] B; + + logic [2:0] ZPa; + logic [2:0] ZPb; + logic ZVa; + logic ZVb; + + output logic [3:0] ZP; + output logic ZV; + + lz8 l1(ZPa, ZVa, B[7:0]); + lz8 l2(ZPb, ZVb, B[15:8]); + + assign ZP[2:0] = ZVb ? ZPb : ZPa; + assign ZP[3] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule // lz16 + +module lz32 (ZP, ZV, B); + + input logic [31:0] B; + + logic [3:0] ZPa; + logic [3:0] ZPb; + logic ZVa; + logic ZVb; + + output logic [4:0] ZP; + output logic ZV; + + lz16 l1(ZPa, ZVa, B[15:0]); + lz16 l2(ZPb, ZVb, B[31:16]); + + assign ZP[3:0] = ZVb ? ZPb : ZPa; + assign ZP[4] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule // lz32 + +module lz64 (ZP, ZV, B); + + input logic [63:0] B; + + logic [4:0] ZPa; + logic [4:0] ZPb; + logic ZVa; + logic ZVb; + + output logic [5:0] ZP; + output logic ZV; + + lz32 l1(ZPa, ZVa, B[31:0]); + lz32 l2(ZPb, ZVb, B[63:32]); + + assign ZP[4:0] = ZVb ? ZPb : ZPa; + assign ZP[5] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule // lz64 + +module lz128 (ZP, ZV, B); + + input logic [127:0] B; + + logic [5:0] ZPa; + logic [5:0] ZPb; + logic ZVa; + logic ZVb; + + output logic [6:0] ZP; + output logic ZV; + + lz64 l1(ZPa, ZVa, B[64:0]); + lz64 l2(ZPb, ZVb, B[127:63]); + + assign ZP[5:0] = ZVb ? ZPb : ZPa; + assign ZP[6] = ~ZVb; + assign ZV = ZVa | ZVb; + +endmodule // lz128 + +/* verilator lint_on DECLFILENAME */ diff --git a/wally-pipelined/src/generic/shift.sv b/wally-pipelined/src/generic/shift.sv new file mode 100755 index 00000000..88152588 --- /dev/null +++ b/wally-pipelined/src/generic/shift.sv @@ -0,0 +1,76 @@ +/////////////////////////////////////////// +// shifters.sv +// +// Written: James.Stine@okstate.edu 1 February 2021 +// Modified: +// +// Purpose: Integer Divide instructions +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" +/* verilator lint_off DECLFILENAME */ +/* verilator lint_off UNOPTFLAT */ + +module shift_right #(parameter WIDTH=8) + (input logic [WIDTH-1:0] A, + input logic [$clog2(WIDTH)-1:0] Shift, + output logic [WIDTH-1:0] Z); + + logic [WIDTH-1:0] stage [$clog2(WIDTH):0]; + logic sign; + genvar i; + + assign stage[0] = A; + generate + for (i=0;i<$clog2(WIDTH);i=i+1) + begin : genbit + mux2 #(WIDTH) mux_inst (stage[i], + {{(WIDTH/(2**(i+1))){1'b0}}, stage[i][WIDTH-1:WIDTH/(2**(i+1))]}, + Shift[$clog2(WIDTH)-i-1], + stage[i+1]); + end + endgenerate + assign Z = stage[$clog2(WIDTH)]; + +endmodule // shift_right + +module shift_left #(parameter WIDTH=8) + (input logic [WIDTH-1:0] A, + input logic [$clog2(WIDTH)-1:0] Shift, + output logic [WIDTH-1:0] Z); + + logic [WIDTH-1:0] stage [$clog2(WIDTH):0]; + genvar i; + + assign stage[0] = A; + generate + for (i=0;i<$clog2(WIDTH);i=i+1) + begin : genbit + mux2 #(WIDTH) mux_inst (stage[i], + {stage[i][WIDTH-1-WIDTH/(2**(i+1)):0], {(WIDTH/(2**(i+1))){1'b0}}}, + Shift[$clog2(WIDTH)-i-1], + stage[i+1]); + end + endgenerate + assign Z = stage[$clog2(WIDTH)]; + +endmodule // shift_left + +/* verilator lint_on DECLFILENAME */ +/* verilator lint_on UNOPTFLAT */ diff --git a/wally-pipelined/src/muldiv/div.sv b/wally-pipelined/src/muldiv/div.sv index db830ca3..4266ae61 100755 --- a/wally-pipelined/src/muldiv/div.sv +++ b/wally-pipelined/src/muldiv/div.sv @@ -78,11 +78,7 @@ module div (Qf, remf, done, divBusy, div0, N, D, clk, reset, start, S); assign D_NegOne = &D; // Divider goes the distance to 37 cycles - // (thanks the evil divisor for D = 0x1) - // but could theoretically be stopped when - // divdone is asserted. The enable signal - // turns off register storage thus invalidating - // any future cycles. + // (thanks to the evil divisor for D = 0x1) // Shift D, if needed (for integer) // needed to allow qst to be in range for integer @@ -93,8 +89,8 @@ module div (Qf, remf, done, divBusy, div0, N, D, clk, reset, start, S); // exception is given to FSM to tell the operation to // quit gracefully. - lz64 p1 (P, V, twoD); - shifter_l64 p2 (op2, twoD, P); + lzd_hier #(64) p1 (.ZP(P), .ZV(V), .B(twoD)); + shift_left #(64) p2 (twoD, P, op2); assign op1 = twoN; assign div0 = ~V; @@ -141,9 +137,8 @@ module div (Qf, remf, done, divBusy, div0, N, D, clk, reset, start, S); assign Q = Qd2[63:0]; assign Rem5 = Rd2[64:1]; - // Adjust remainder by m (no need to adjust by - // n ln(r) - shifter_r64 p4 (rem0, Rem5, RemShift); + // Adjust remainder by m + shift_right #(64) p4 (Rem5, RemShift, rem0); // Adjust Q/Rem for Signed assign tcQ = (SignN ^ SignD) & S; @@ -368,8 +363,6 @@ module qst4 (input logic [6:0] s, input logic [2:0] d, endmodule // qst4 -// LZD - module lz2 (P, V, B0, B1); input logic B0; @@ -497,7 +490,6 @@ module lz64 (ZP, ZV, B); endmodule // lz64 // FSM Control for Integer Divider - module fsm64 (en, state0, done, divdone, otfzero, divBusy, start, error, NumIter, clk, reset); @@ -1505,134 +1497,6 @@ module magcompare8 (LT, EQ, A, B); endmodule // magcompare8 -module shifter_l64 (Z, A, Shift); - - input logic [63:0] A; - input logic [5:0] Shift; - - logic [63:0] stage1; - logic [63:0] stage2; - logic [63:0] stage3; - logic [63:0] stage4; - logic [63:0] stage5; - - output logic [63:0] Z; - - mux2 #(64) mx01(A, {A[31:0], 32'h0}, Shift[5], stage1); - mux2 #(64) mx02(stage1, {stage1[47:0], 16'h0}, Shift[4], stage2); - mux2 #(64) mx03(stage2, {stage2[55:0], 8'h0}, Shift[3], stage3); - mux2 #(64) mx04(stage3, {stage3[59:0], 4'h0}, Shift[2], stage4); - mux2 #(64) mx05(stage4, {stage4[61:0], 2'h0}, Shift[1], stage5); - mux2 #(64) mx06(stage5, {stage5[62:0], 1'h0}, Shift[0], Z); - -endmodule // shifter_l64 - -module shifter_r64 (Z, A, Shift); - - input logic [63:0] A; - input logic [5:0] Shift; - - logic [63:0] stage1; - logic [63:0] stage2; - logic [63:0] stage3; - logic [63:0] stage4; - logic [63:0] stage5; - - output logic [63:0] Z; - - mux2 #(64) mx01(A, {32'h0, A[63:32]}, Shift[5], stage1); - mux2 #(64) mx02(stage1, {16'h0, stage1[63:16]}, Shift[4], stage2); - mux2 #(64) mx03(stage2, {8'h0, stage2[63:8]}, Shift[3], stage3); - mux2 #(64) mx04(stage3, {4'h0, stage3[63:4]}, Shift[2], stage4); - mux2 #(64) mx05(stage4, {2'h0, stage4[63:2]}, Shift[1], stage5); - mux2 #(64) mx06(stage5, {1'h0, stage5[63:1]}, Shift[0], Z); - -endmodule // shifter_r64 - -module shifter_l32 (Z, A, Shift); - - input logic [31:0] A; - input logic [4:0] Shift; - - logic [31:0] stage1; - logic [31:0] stage2; - logic [31:0] stage3; - logic [31:0] stage4; - - output logic [31:0] Z; - - mux2 #(32) mx01(A, {A[15:0], 16'h0}, Shift[4], stage1); - mux2 #(32) mx02(stage1, {stage1[23:0], 8'h0}, Shift[3], stage2); - mux2 #(32) mx03(stage2, {stage2[27:0], 4'h0}, Shift[2], stage3); - mux2 #(32) mx04(stage3, {stage3[29:0], 2'h0}, Shift[1], stage4); - mux2 #(32) mx05(stage4, {stage4[30:0], 1'h0}, Shift[0], Z); - -endmodule // shifter_l32 - -module shifter_r32 (Z, A, Shift); - - input logic [31:0] A; - input logic [4:0] Shift; - - logic [31:0] stage1; - logic [31:0] stage2; - logic [31:0] stage3; - logic [31:0] stage4; - - output logic [31:0] Z; - - mux2 #(32) mx01(A, {16'h0, A[31:16]}, Shift[4], stage1); - mux2 #(32) mx02(stage1, {8'h0, stage1[31:8]}, Shift[3], stage2); - mux2 #(32) mx03(stage2, {4'h0, stage2[31:4]}, Shift[2], stage3); - mux2 #(32) mx04(stage3, {2'h0, stage3[31:2]}, Shift[1], stage4); - mux2 #(32) mx05(stage4, {1'h0, stage4[31:1]}, Shift[0], Z); - -endmodule // shifter_r32 - -module shift_right #(parameter WIDTH=8) - (input logic [`XLEN-1:0] A, - input logic [$clog2(`XLEN)-1:0] Shift, - output logic [`XLEN-1:0] Z); - - logic [`XLEN-1:0] stage [$clog2(`XLEN):0]; - genvar i; - - assign stage[0] = A; - generate - for (i=0;i<$clog2(`XLEN);i=i+1) - begin : genbit - mux2 #(`XLEN) mux_inst (stage[i], - {{(`XLEN/(2**(i+1))){1'b0}}, stage[i][`XLEN-1:`XLEN/(2**(i+1))]}, - Shift[$clog2(`XLEN)-i-1], - stage[i+1]); - end - endgenerate - assign Z = stage[$clog2(`XLEN)]; - -endmodule // shift_right - -module shift_left #(parameter WIDTH=8) - (input logic [`XLEN-1:0] A, - input logic [$clog2(`XLEN)-1:0] Shift, - output logic [`XLEN-1:0] Z); - - logic [`XLEN-1:0] stage [$clog2(`XLEN):0]; - genvar i; - - assign stage[0] = A; - generate - for (i=0;i<$clog2(`XLEN);i=i+1) - begin : genbit - mux2 #(`XLEN) mux_inst (stage[i], - {stage[i][`XLEN-1-`XLEN/(2**(i+1)):0], {(`XLEN/(2**(i+1))){1'b0}}}, - Shift[$clog2(`XLEN)-i-1], - stage[i+1]); - end - endgenerate - assign Z = stage[$clog2(`XLEN)]; - -endmodule // shift_right - module exception_int (Q, rem, op1, S, div0, Max_N, D_NegOne, Qf, remf); input logic [63:0] Q;