diff options
Diffstat (limited to 'techlibs/nexus')
-rw-r--r-- | techlibs/nexus/Makefile.inc | 4 | ||||
-rw-r--r-- | techlibs/nexus/arith_map.v | 4 | ||||
-rw-r--r-- | techlibs/nexus/cells_sim.v | 564 | ||||
-rw-r--r-- | techlibs/nexus/cells_xtra.py | 18 | ||||
-rw-r--r-- | techlibs/nexus/cells_xtra.v | 241 | ||||
-rw-r--r-- | techlibs/nexus/dsp_map.v | 79 | ||||
-rw-r--r-- | techlibs/nexus/lrams.txt | 22 | ||||
-rw-r--r-- | techlibs/nexus/lrams_init.vh | 128 | ||||
-rw-r--r-- | techlibs/nexus/lrams_map.v | 56 | ||||
-rw-r--r-- | techlibs/nexus/synth_nexus.cc | 55 |
10 files changed, 918 insertions, 253 deletions
diff --git a/techlibs/nexus/Makefile.inc b/techlibs/nexus/Makefile.inc index e0ff40e15..9828d32c1 100644 --- a/techlibs/nexus/Makefile.inc +++ b/techlibs/nexus/Makefile.inc @@ -9,6 +9,10 @@ $(eval $(call add_share_file,share/nexus,techlibs/nexus/lutrams.txt)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/brams_init.vh)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/brams_map.v)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/brams.txt)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams_init.vh)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams_map.v)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/lrams.txt)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/arith_map.v)) $(eval $(call add_share_file,share/nexus,techlibs/nexus/latches_map.v)) +$(eval $(call add_share_file,share/nexus,techlibs/nexus/dsp_map.v)) diff --git a/techlibs/nexus/arith_map.v b/techlibs/nexus/arith_map.v index fd9d61be3..ce14a15ea 100644 --- a/techlibs/nexus/arith_map.v +++ b/techlibs/nexus/arith_map.v @@ -88,9 +88,9 @@ module _80_nexus_alu (A, B, CI, BI, X, Y, CO); .COUT(FCO[i+2]) ); - assign CO[i] = (AA[i] && BB[i]) || (((i == 0) ? CI : CO[i-1]) && (AA[i] || BB[i])); + assign CO[i] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i])); if (i+1 < Y_WIDTH) begin - assign CO[i+1] = (AA[i+1] && BB[i+1]) || (CO[i] && (AA[i+1] || BB[i+1])); + assign CO[i + 1] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i])); assign Y[i+1] = Y1[i]; end end endgenerate diff --git a/techlibs/nexus/cells_sim.v b/techlibs/nexus/cells_sim.v index 41c8a3c73..b5938e08f 100644 --- a/techlibs/nexus/cells_sim.v +++ b/techlibs/nexus/cells_sim.v @@ -377,3 +377,567 @@ module DPR16X4( mem[WAD] <= DI; assign DO = mem[RAD]; endmodule + +// Used for all the DSP models to reduce duplication +module OXIDE_DSP_REG #( + parameter W = 18, + parameter USED = "REGISTER", + parameter RESETMODE = "SYNC" +) ( + input CLK, CE, RST, + input [W-1:0] D, + output reg [W-1:0] Q +); + generate + if (USED == "BYPASS") + always @* Q = D; + else if (USED == "REGISTER") begin + initial Q = 0; + if (RESETMODE == "ASYNC") + always @(posedge CLK, posedge RST) begin + if (RST) + Q <= 0; + else if (CE) + Q <= D; + end + else if (RESETMODE == "SYNC") + always @(posedge CLK) begin + if (RST) + Q <= 0; + else if (CE) + Q <= D; + end + end + endgenerate +endmodule + +module OXIDE_DSP_SIM #( + // User facing parameters + parameter REGINPUTA = "BYPASS", + parameter REGINPUTB = "BYPASS", + parameter REGINPUTC = "BYPASS", + parameter REGADDSUB = "BYPASS", + parameter REGLOADC = "BYPASS", + parameter REGLOADC2 = "BYPASS", + parameter REGCIN = "BYPASS", + parameter REGPIPELINE = "BYPASS", + parameter REGOUTPUT = "BYPASS", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC", + // Internally used parameters + parameter A_WIDTH = 36, + parameter B_WIDTH = 36, + parameter C_WIDTH = 36, + parameter Z_WIDTH = 72, + parameter PREADD_USED = 0, + parameter ADDSUB_USED = 0 +) ( + input [A_WIDTH-1:0] A, + input [B_WIDTH-1:0] B, + input [C_WIDTH-1:0] C, + input SIGNEDA, + input SIGNEDB, + input SIGNEDC, + input CIN, + input LOADC, + input ADDSUB, + input CLK, + input CEA, CEB, CEC, CEPIPE, CECTRL, CECIN, CEOUT, + input RSTA, RSTB, RSTC, RSTPIPE, RSTCTRL, RSTCIN, RSTOUT, + output wire [Z_WIDTH-1:0] Z +); + + localparam M_WIDTH = (A_WIDTH+B_WIDTH); + + /******** REGISTERS ********/ + + wire [M_WIDTH-1:0] pipe_d, pipe_q; + wire [Z_WIDTH-1:0] z_d; + + wire [A_WIDTH-1:0] a_r; + wire [B_WIDTH-1:0] b_r; + wire [C_WIDTH-1:0] c_r, c_r2; + wire asgd_r, bsgd_r, csgd_r, csgd_r2; + + wire addsub_r, addsub_r2, cin_r, cin_r2, sgd_r, sgd_r2; + wire loadc_r, loadc_r2; + + OXIDE_DSP_REG #(A_WIDTH+1, REGINPUTA, RESETMODE) a_reg(CLK, CEA, RSTA, {SIGNEDA, A}, {asgd_r, a_r}); + OXIDE_DSP_REG #(B_WIDTH+1, REGINPUTB, RESETMODE) b_reg(CLK, CEB, RSTB, {SIGNEDB, B}, {bsgd_r, b_r}); + OXIDE_DSP_REG #(C_WIDTH+1, REGINPUTC, RESETMODE) c_reg(CLK, CEC, RSTC, {SIGNEDC, C}, {csgd_r, c_r}); + + OXIDE_DSP_REG #(M_WIDTH, REGPIPELINE, RESETMODE) pipe_reg(CLK, CEPIPE, RSTPIPE, pipe_d, pipe_q); + + OXIDE_DSP_REG #(2, REGADDSUB, RESETMODE) addsub_reg(CLK, CECTRL, RSTCTRL, {SIGNEDA, ADDSUB}, {sgd_r, addsub_r}); + OXIDE_DSP_REG #(1, REGLOADC, RESETMODE) loadc_reg(CLK, CECTRL, RSTCTRL, LOADC, loadc_r); + OXIDE_DSP_REG #(2, REGPIPELINE, RESETMODE) addsub2_reg(CLK, CECTRL, RSTCTRL, {sgd_r, addsub_r}, {sgd_r2, addsub_r2}); + OXIDE_DSP_REG #(1, REGLOADC2, RESETMODE) loadc2_reg(CLK, CECTRL, RSTCTRL, loadc_r, loadc_r2); + + OXIDE_DSP_REG #(1, REGCIN, RESETMODE) cin_reg(CLK, CECIN, RSTCIN, CIN, cin_r); + OXIDE_DSP_REG #(1, REGPIPELINE, RESETMODE) cin2_reg(CLK, CECIN, RSTCIN, cin_r, cin_r2); + + OXIDE_DSP_REG #(C_WIDTH+1, REGPIPELINE, RESETMODE) c2_reg(CLK, CEC, RSTC, {csgd_r, c_r}, {csgd_r2, c_r2}); + + OXIDE_DSP_REG #(Z_WIDTH, REGOUTPUT, RESETMODE) z_reg(CLK, CEOUT, RSTOUT, z_d, Z); + + /******** PREADDER ********/ + + wire [B_WIDTH-1:0] mult_b; + wire mult_b_sgd; + + generate + if (PREADD_USED) begin + assign mult_b = (b_r + c_r); + assign mult_b_sgd = (bsgd_r | csgd_r); + end else begin + assign mult_b = b_r; + assign mult_b_sgd = bsgd_r; + end + endgenerate + + /******** MULTIPLIER ********/ + + // sign extend operands if needed + wire [M_WIDTH-1:0] mult_a_ext = {{(M_WIDTH-A_WIDTH){asgd_r ? a_r[A_WIDTH-1] : 1'b0}}, a_r}; + wire [M_WIDTH-1:0] mult_b_ext = {{(M_WIDTH-B_WIDTH){mult_b_sgd ? mult_b[B_WIDTH-1] : 1'b0}}, mult_b}; + + wire [M_WIDTH-1:0] mult_m = mult_a_ext * mult_b_ext; + + /******** ACCUMULATOR ********/ + + wire [Z_WIDTH-1:0] m_ext; + + generate + if (ADDSUB_USED) begin + assign pipe_d = mult_m; + assign m_ext = {{(Z_WIDTH-M_WIDTH){sgd_r2 ? pipe_q[M_WIDTH-1] : 1'b0}}, pipe_q}; + assign z_d = (loadc_r2 ? c_r2 : Z) + cin_r2 + (addsub_r2 ? -m_ext : m_ext); + end else begin + assign z_d = mult_m; + end + endgenerate + + +endmodule + +module MULT9X9 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [8:0] A, + input [8:0] B, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input SIGNEDA, + input SIGNEDB, + input RSTOUT, + input CEOUT, + output [17:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(9), + .B_WIDTH(9), + .Z_WIDTH(18), + .PREADD_USED(0), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + +module MULT18X18 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [17:0] A, + input [17:0] B, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input SIGNEDA, + input SIGNEDB, + input RSTOUT, + input CEOUT, + output [35:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(18), + .B_WIDTH(18), + .Z_WIDTH(36), + .PREADD_USED(0), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + +module MULT18X36 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [17:0] A, + input [35:0] B, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input SIGNEDA, + input SIGNEDB, + input RSTOUT, + input CEOUT, + output [53:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(18), + .B_WIDTH(36), + .Z_WIDTH(54), + .PREADD_USED(0), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + +module MULT36X36 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [35:0] A, + input [35:0] B, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input SIGNEDA, + input SIGNEDB, + input RSTOUT, + input CEOUT, + output [71:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(36), + .B_WIDTH(36), + .Z_WIDTH(72), + .PREADD_USED(0), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + + +module MULTPREADD9X9 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGINPUTC = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [8:0] A, + input [8:0] B, + input [8:0] C, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input CEC, + input RSTC, + input SIGNEDA, + input SIGNEDB, + input SIGNEDC, + input RSTOUT, + input CEOUT, + output [17:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGINPUTC(REGINPUTC), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(9), + .B_WIDTH(9), + .C_WIDTH(9), + .Z_WIDTH(18), + .PREADD_USED(1), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), .C(C), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .CEC(CEC), .RSTC(RSTC), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), .SIGNEDC(SIGNEDC), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + + +module MULTPREADD18X18 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGINPUTC = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [17:0] A, + input [17:0] B, + input [17:0] C, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input CEC, + input RSTC, + input SIGNEDA, + input SIGNEDB, + input SIGNEDC, + input RSTOUT, + input CEOUT, + output [35:0] Z +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGINPUTC(REGINPUTC), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(18), + .B_WIDTH(18), + .C_WIDTH(18), + .Z_WIDTH(36), + .PREADD_USED(1), + .ADDSUB_USED(0) + ) dsp_i ( + .A(A), .B(B), .C(C), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .CEC(CEC), .RSTC(RSTC), + .SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), .SIGNEDC(SIGNEDC), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + + +module MULTADDSUB18X18 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGINPUTC = "REGISTER", + parameter REGADDSUB = "REGISTER", + parameter REGLOADC = "REGISTER", + parameter REGLOADC2 = "REGISTER", + parameter REGCIN = "REGISTER", + parameter REGPIPELINE = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [17:0] A, + input [17:0] B, + input [53:0] C, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input CEC, + input RSTC, + input SIGNED, + input RSTPIPE, + input CEPIPE, + input RSTCTRL, + input CECTRL, + input RSTCIN, + input CECIN, + input LOADC, + input ADDSUB, + output [53:0] Z, + input RSTOUT, + input CEOUT, + input CIN +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGINPUTC(REGINPUTC), + .REGADDSUB(REGADDSUB), + .REGLOADC(REGLOADC), + .REGLOADC2(REGLOADC2), + .REGCIN(REGCIN), + .REGPIPELINE(REGPIPELINE), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(18), + .B_WIDTH(18), + .C_WIDTH(54), + .Z_WIDTH(54), + .PREADD_USED(0), + .ADDSUB_USED(1) + ) dsp_i ( + .A(A), .B(B), .C(C), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .CEC(CEC), .RSTC(RSTC), + .CEPIPE(CEPIPE), .RSTPIPE(RSTPIPE), + .CECTRL(CECTRL), .RSTCTRL(RSTCTRL), + .CECIN(CECIN), .RSTCIN(RSTCIN), + .CIN(CIN), .LOADC(LOADC), .ADDSUB(ADDSUB), + .SIGNEDA(SIGNED), .SIGNEDB(SIGNED), .SIGNEDC(SIGNED), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule + + +module MULTADDSUB36X36 #( + parameter REGINPUTA = "REGISTER", + parameter REGINPUTB = "REGISTER", + parameter REGINPUTC = "REGISTER", + parameter REGADDSUB = "REGISTER", + parameter REGLOADC = "REGISTER", + parameter REGLOADC2 = "REGISTER", + parameter REGCIN = "REGISTER", + parameter REGPIPELINE = "REGISTER", + parameter REGOUTPUT = "REGISTER", + parameter GSR = "ENABLED", + parameter RESETMODE = "SYNC" +) ( + input [35:0] A, + input [35:0] B, + input [107:0] C, + input CLK, + input CEA, + input RSTA, + input CEB, + input RSTB, + input CEC, + input RSTC, + input SIGNED, + input RSTPIPE, + input CEPIPE, + input RSTCTRL, + input CECTRL, + input RSTCIN, + input CECIN, + input LOADC, + input ADDSUB, + output [107:0] Z, + input RSTOUT, + input CEOUT, + input CIN +); + OXIDE_DSP_SIM #( + .REGINPUTA(REGINPUTA), + .REGINPUTB(REGINPUTB), + .REGINPUTC(REGINPUTC), + .REGADDSUB(REGADDSUB), + .REGLOADC(REGLOADC), + .REGLOADC2(REGLOADC2), + .REGCIN(REGCIN), + .REGPIPELINE(REGPIPELINE), + .REGOUTPUT(REGOUTPUT), + .GSR(GSR), + .RESETMODE(RESETMODE), + + .A_WIDTH(36), + .B_WIDTH(36), + .C_WIDTH(108), + .Z_WIDTH(108), + .PREADD_USED(0), + .ADDSUB_USED(1) + ) dsp_i ( + .A(A), .B(B), .C(C), + .CLK(CLK), + .CEA(CEA), .RSTA(RSTA), + .CEB(CEB), .RSTB(RSTB), + .CEC(CEC), .RSTC(RSTC), + .CEPIPE(CEPIPE), .RSTPIPE(RSTPIPE), + .CECTRL(CECTRL), .RSTCTRL(RSTCTRL), + .CECIN(CECIN), .RSTCIN(RSTCIN), + .CIN(CIN), .LOADC(LOADC), .ADDSUB(ADDSUB), + .SIGNEDA(SIGNED), .SIGNEDB(SIGNED), .SIGNEDC(SIGNED), + .RSTOUT(RSTOUT), .CEOUT(CEOUT), + .Z(Z) + ); +endmodule diff --git a/techlibs/nexus/cells_xtra.py b/techlibs/nexus/cells_xtra.py index dc462c29a..6ced76950 100644 --- a/techlibs/nexus/cells_xtra.py +++ b/techlibs/nexus/cells_xtra.py @@ -74,20 +74,20 @@ devices = [ Cell("M18X36"), Cell("MIPI"), Cell("MULT18"), - Cell("MULT18X18"), - Cell("MULT18X36"), +# Cell("MULT18X18"), +# Cell("MULT18X36"), Cell("MULT36"), - Cell("MULT36X36"), +# Cell("MULT36X36"), Cell("MULT9"), - Cell("MULT9X9"), - Cell("MULTADDSUB18X18"), +# Cell("MULT9X9"), +# Cell("MULTADDSUB18X18"), Cell("MULTADDSUB18X18WIDE"), - Cell("MULTADDSUB18X36"), - Cell("MULTADDSUB36X36"), +# Cell("MULTADDSUB18X36"), +# Cell("MULTADDSUB36X36"), Cell("MULTADDSUB9X9WIDE"), Cell("MULTIBOOT", keep=True), - Cell("MULTPREADD18X18"), - Cell("MULTPREADD9X9"), +# Cell("MULTPREADD18X18"), +# Cell("MULTPREADD9X9"), Cell("ODDR71"), Cell("ODDRX1"), Cell("ODDRX2DQS"), diff --git a/techlibs/nexus/cells_xtra.v b/techlibs/nexus/cells_xtra.v index b275e610a..6cf3a645d 100644 --- a/techlibs/nexus/cells_xtra.v +++ b/techlibs/nexus/cells_xtra.v @@ -2114,46 +2114,6 @@ module MULT18 (...); input ROUNDEN; endmodule -module MULT18X18 (...); - parameter REGINPUTA = "REGISTER"; - parameter REGINPUTB = "REGISTER"; - parameter REGOUTPUT = "REGISTER"; - parameter GSR = "ENABLED"; - parameter RESETMODE = "SYNC"; - input [17:0] A; - input [17:0] B; - input CLK; - input CEA; - input RSTA; - input CEB; - input RSTB; - input SIGNEDA; - input SIGNEDB; - input RSTOUT; - input CEOUT; - output [35:0] Z; -endmodule - -module MULT18X36 (...); - parameter REGINPUTA = "REGISTER"; - parameter REGINPUTB = "REGISTER"; - parameter REGOUTPUT = "REGISTER"; - parameter GSR = "ENABLED"; - parameter RESETMODE = "SYNC"; - input [17:0] A; - input [35:0] B; - input CLK; - input CEA; - input RSTA; - input CEB; - input RSTB; - input SIGNEDA; - input SIGNEDB; - input RSTOUT; - input CEOUT; - output [53:0] Z; -endmodule - module MULT36 (...); parameter MULT36X36 = "ENABLED"; input [72:0] PH72; @@ -2162,26 +2122,6 @@ module MULT36 (...); output [71:0] PMH72; endmodule -module MULT36X36 (...); - parameter REGINPUTA = "REGISTER"; - parameter REGINPUTB = "REGISTER"; - parameter REGOUTPUT = "REGISTER"; - parameter GSR = "ENABLED"; - parameter RESETMODE = "SYNC"; - input [35:0] A; - input [35:0] B; - input CLK; - input CEA; - input RSTA; - input CEB; - input RSTB; - input SIGNEDA; - input SIGNEDB; - input RSTOUT; - input CEOUT; - output [71:0] Z; -endmodule - module MULT9 (...); parameter SIGNEDSTATIC_EN = "DISABLED"; parameter ASIGNED_OPERAND_EN = "DISABLED"; @@ -2215,63 +2155,6 @@ module MULT9 (...); input RSTP; endmodule -module MULT9X9 (...); - parameter REGINPUTA = "REGISTER"; - parameter REGINPUTB = "REGISTER"; - parameter REGOUTPUT = "REGISTER"; - parameter GSR = "ENABLED"; - parameter RESETMODE = "SYNC"; - input [8:0] A; - input [8:0] B; - input CLK; - input CEA; - input RSTA; - input CEB; - input RSTB; - input SIGNEDA; - input SIGNEDB; - input RSTOUT; - input CEOUT; - output [17:0] Z; -endmodule - -module MULTADDSUB18X18 (...); - parameter REGINPUTA = "REGISTER"; - parameter REGINPUTB = "REGISTER"; - parameter REGINPUTC = "REGISTER"; - parameter REGADDSUB = "REGISTER"; - parameter REGLOADC = "REGISTER"; - parameter REGLOADC2 = "REGISTER"; - parameter REGCIN = "REGISTER"; - parameter REGPIPELINE = "REGISTER"; - parameter REGOUTPUT = "REGISTER"; - parameter GSR = "ENABLED"; - parameter RESETMODE = "SYNC"; - input [17:0] A; - input [17:0] B; - input [53:0] C; - input CLK; - input CEA; - input RSTA; - input CEB; - input RSTB; - input CEC; - input RSTC; - input SIGNED; - input RSTPIPE; - input CEPIPE; - input RSTCTRL; - input CECTRL; - input RSTCIN; - input CECIN; - input LOADC; - input ADDSUB; - output [53:0] Z; - input RSTOUT; - input CEOUT; - input CIN; -endmodule - module MULTADDSUB18X18WIDE (...); parameter REGINPUTAB0 = "REGISTER"; parameter REGINPUTAB1 = "REGISTER"; @@ -2311,80 +2194,6 @@ module MULTADDSUB18X18WIDE (...); input [1:0] ADDSUB; endmodule -module MULTADDSUB18X36 (...); - parameter REGINPUTA = "REGISTER"; - parameter REGINPUTB = "REGISTER"; - parameter REGINPUTC = "REGISTER"; - parameter REGADDSUB = "REGISTER"; - parameter REGLOADC = "REGISTER"; - parameter REGLOADC2 = "REGISTER"; - parameter REGCIN = "REGISTER"; - parameter REGPIPELINE = "REGISTER"; - parameter REGOUTPUT = "REGISTER"; - parameter GSR = "ENABLED"; - parameter RESETMODE = "SYNC"; - input [17:0] A; - input [35:0] B; - input [53:0] C; - input CLK; - input CEA; - input RSTA; - input CEB; - input RSTB; - input CEC; - input RSTC; - input RSTCTRL; - input CECTRL; - input RSTCIN; - input CECIN; - input SIGNED; - input RSTPIPE; - input CEPIPE; - input RSTOUT; - input CEOUT; - output [53:0] Z; - input LOADC; - input ADDSUB; - input CIN; -endmodule - -module MULTADDSUB36X36 (...); - parameter REGINPUTA = "REGISTER"; - parameter REGINPUTB = "REGISTER"; - parameter REGINPUTC = "REGISTER"; - parameter REGADDSUB = "REGISTER"; - parameter REGLOADC = "REGISTER"; - parameter REGLOADC2 = "REGISTER"; - parameter REGCIN = "REGISTER"; - parameter REGPIPELINE = "REGISTER"; - parameter REGOUTPUT = "REGISTER"; - parameter GSR = "ENABLED"; - parameter RESETMODE = "SYNC"; - input [35:0] A; - input [35:0] B; - input [107:0] C; - input CLK; - input CEA; - input RSTA; - input CEB; - input RSTB; - input CEC; - input RSTC; - input RSTCTRL; - input CECTRL; - input RSTCIN; - input CECIN; - input SIGNED; - input RSTPIPE; - input CEPIPE; - input RSTOUT; - input CEOUT; - output [107:0] Z; - input LOADC; - input ADDSUB; - input CIN; -endmodule - module MULTADDSUB9X9WIDE (...); parameter REGINPUTAB0 = "REGISTER"; parameter REGINPUTAB1 = "REGISTER"; @@ -2438,56 +2247,6 @@ module MULTIBOOT (...); input [31:0] MSPIMADDR; endmodule -module MULTPREADD18X18 (...); - parameter REGINPUTA = "REGISTER"; - parameter REGINPUTB = "REGISTER"; - parameter REGINPUTC = "REGISTER"; - parameter REGOUTPUT = "REGISTER"; - parameter GSR = "ENABLED"; - parameter RESETMODE = "SYNC"; - input [17:0] A; - input [17:0] B; - input [17:0] C; - input CLK; - input CEA; - input RSTA; - input CEB; - input RSTB; - input CEC; - input RSTC; - input SIGNEDA; - input SIGNEDB; - input SIGNEDC; - input RSTOUT; - input CEOUT; - output [35:0] Z; -endmodule - -module MULTPREADD9X9 (...); - parameter REGINPUTA = "REGISTER"; - parameter REGINPUTB = "REGISTER"; - parameter REGINPUTC = "REGISTER"; - parameter REGOUTPUT = "REGISTER"; - parameter GSR = "ENABLED"; - parameter RESETMODE = "SYNC"; - input [8:0] A; - input [8:0] B; - input [8:0] C; - input CLK; - input CEA; - input RSTA; - input CEB; - input RSTB; - input CEC; - input RSTC; - input SIGNEDA; - input SIGNEDB; - input SIGNEDC; - input RSTOUT; - input CEOUT; - output [17:0] Z; -endmodule - module ODDR71 (...); parameter GSR = "ENABLED"; input D0; diff --git a/techlibs/nexus/dsp_map.v b/techlibs/nexus/dsp_map.v new file mode 100644 index 000000000..b12528309 --- /dev/null +++ b/techlibs/nexus/dsp_map.v @@ -0,0 +1,79 @@ +module \$__NX_MUL36X36 (input [35:0] A, input [35:0] B, output [71:0] Y); + + parameter A_WIDTH = 36; + parameter B_WIDTH = 36; + parameter Y_WIDTH = 72; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT36X36 #( + .REGINPUTA("BYPASS"), + .REGINPUTB("BYPASS"), + .REGOUTPUT("BYPASS") + ) _TECHMAP_REPLACE_ ( + .A(A), .B(B), + .SIGNEDA(A_SIGNED ? 1'b1 : 1'b0), + .SIGNEDB(B_SIGNED ? 1'b1 : 1'b0), + .Z(Y) + ); +endmodule + +module \$__NX_MUL36X18 (input [35:0] A, input [17:0] B, output [53:0] Y); + + parameter A_WIDTH = 36; + parameter B_WIDTH = 18; + parameter Y_WIDTH = 54; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT18X36 #( + .REGINPUTA("BYPASS"), + .REGINPUTB("BYPASS"), + .REGOUTPUT("BYPASS") + ) _TECHMAP_REPLACE_ ( + .A(B), .B(A), + .SIGNEDA(B_SIGNED ? 1'b1 : 1'b0), + .SIGNEDB(A_SIGNED ? 1'b1 : 1'b0), + .Z(Y) + ); +endmodule + +module \$__NX_MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y); + + parameter A_WIDTH = 18; + parameter B_WIDTH = 18; + parameter Y_WIDTH = 36; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT18X18 #( + .REGINPUTA("BYPASS"), + .REGINPUTB("BYPASS"), + .REGOUTPUT("BYPASS") + ) _TECHMAP_REPLACE_ ( + .A(A), .B(B), + .SIGNEDA(A_SIGNED ? 1'b1 : 1'b0), + .SIGNEDB(B_SIGNED ? 1'b1 : 1'b0), + .Z(Y) + ); +endmodule + +module \$__NX_MUL9X9 (input [8:0] A, input [8:0] B, output [17:0] Y); + + parameter A_WIDTH = 9; + parameter B_WIDTH = 9; + parameter Y_WIDTH = 18; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT9X9 #( + .REGINPUTA("BYPASS"), + .REGINPUTB("BYPASS"), + .REGOUTPUT("BYPASS") + ) _TECHMAP_REPLACE_ ( + .A(A), .B(B), + .SIGNEDA(A_SIGNED ? 1'b1 : 1'b0), + .SIGNEDB(B_SIGNED ? 1'b1 : 1'b0), + .Z(Y) + ); +endmodule diff --git a/techlibs/nexus/lrams.txt b/techlibs/nexus/lrams.txt new file mode 100644 index 000000000..481629b98 --- /dev/null +++ b/techlibs/nexus/lrams.txt @@ -0,0 +1,22 @@ +bram $__NX_PDPSC512K + init 1 + + abits 14 + dbits 32 + + groups 2 + ports 1 1 + wrmode 1 0 + enable 4 1 + transp 0 0 + clocks 2 2 + clkpol 2 2 +endbram + +match $__NX_PDPSC512K + # explicitly requested LRAM only, due to limited availability and + # slower Fmax + attribute lram + shuffle_enable A + make_transp +endmatch diff --git a/techlibs/nexus/lrams_init.vh b/techlibs/nexus/lrams_init.vh new file mode 100644 index 000000000..31a7ba4a8 --- /dev/null +++ b/techlibs/nexus/lrams_init.vh @@ -0,0 +1,128 @@ +.INITVAL_00($sformatf("0x%05120x", permute_init(INIT[0 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_01($sformatf("0x%05120x", permute_init(INIT[1 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_02($sformatf("0x%05120x", permute_init(INIT[2 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_03($sformatf("0x%05120x", permute_init(INIT[3 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_04($sformatf("0x%05120x", permute_init(INIT[4 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_05($sformatf("0x%05120x", permute_init(INIT[5 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_06($sformatf("0x%05120x", permute_init(INIT[6 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_07($sformatf("0x%05120x", permute_init(INIT[7 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_08($sformatf("0x%05120x", permute_init(INIT[8 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_09($sformatf("0x%05120x", permute_init(INIT[9 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0A($sformatf("0x%05120x", permute_init(INIT[10 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0B($sformatf("0x%05120x", permute_init(INIT[11 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0C($sformatf("0x%05120x", permute_init(INIT[12 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0D($sformatf("0x%05120x", permute_init(INIT[13 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0E($sformatf("0x%05120x", permute_init(INIT[14 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_0F($sformatf("0x%05120x", permute_init(INIT[15 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_10($sformatf("0x%05120x", permute_init(INIT[16 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_11($sformatf("0x%05120x", permute_init(INIT[17 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_12($sformatf("0x%05120x", permute_init(INIT[18 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_13($sformatf("0x%05120x", permute_init(INIT[19 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_14($sformatf("0x%05120x", permute_init(INIT[20 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_15($sformatf("0x%05120x", permute_init(INIT[21 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_16($sformatf("0x%05120x", permute_init(INIT[22 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_17($sformatf("0x%05120x", permute_init(INIT[23 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_18($sformatf("0x%05120x", permute_init(INIT[24 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_19($sformatf("0x%05120x", permute_init(INIT[25 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1A($sformatf("0x%05120x", permute_init(INIT[26 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1B($sformatf("0x%05120x", permute_init(INIT[27 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1C($sformatf("0x%05120x", permute_init(INIT[28 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1D($sformatf("0x%05120x", permute_init(INIT[29 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1E($sformatf("0x%05120x", permute_init(INIT[30 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_1F($sformatf("0x%05120x", permute_init(INIT[31 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_20($sformatf("0x%05120x", permute_init(INIT[32 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_21($sformatf("0x%05120x", permute_init(INIT[33 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_22($sformatf("0x%05120x", permute_init(INIT[34 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_23($sformatf("0x%05120x", permute_init(INIT[35 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_24($sformatf("0x%05120x", permute_init(INIT[36 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_25($sformatf("0x%05120x", permute_init(INIT[37 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_26($sformatf("0x%05120x", permute_init(INIT[38 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_27($sformatf("0x%05120x", permute_init(INIT[39 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_28($sformatf("0x%05120x", permute_init(INIT[40 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_29($sformatf("0x%05120x", permute_init(INIT[41 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2A($sformatf("0x%05120x", permute_init(INIT[42 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2B($sformatf("0x%05120x", permute_init(INIT[43 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2C($sformatf("0x%05120x", permute_init(INIT[44 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2D($sformatf("0x%05120x", permute_init(INIT[45 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2E($sformatf("0x%05120x", permute_init(INIT[46 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_2F($sformatf("0x%05120x", permute_init(INIT[47 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_30($sformatf("0x%05120x", permute_init(INIT[48 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_31($sformatf("0x%05120x", permute_init(INIT[49 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_32($sformatf("0x%05120x", permute_init(INIT[50 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_33($sformatf("0x%05120x", permute_init(INIT[51 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_34($sformatf("0x%05120x", permute_init(INIT[52 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_35($sformatf("0x%05120x", permute_init(INIT[53 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_36($sformatf("0x%05120x", permute_init(INIT[54 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_37($sformatf("0x%05120x", permute_init(INIT[55 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_38($sformatf("0x%05120x", permute_init(INIT[56 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_39($sformatf("0x%05120x", permute_init(INIT[57 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3A($sformatf("0x%05120x", permute_init(INIT[58 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3B($sformatf("0x%05120x", permute_init(INIT[59 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3C($sformatf("0x%05120x", permute_init(INIT[60 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3D($sformatf("0x%05120x", permute_init(INIT[61 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3E($sformatf("0x%05120x", permute_init(INIT[62 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_3F($sformatf("0x%05120x", permute_init(INIT[63 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_40($sformatf("0x%05120x", permute_init(INIT[64 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_41($sformatf("0x%05120x", permute_init(INIT[65 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_42($sformatf("0x%05120x", permute_init(INIT[66 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_43($sformatf("0x%05120x", permute_init(INIT[67 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_44($sformatf("0x%05120x", permute_init(INIT[68 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_45($sformatf("0x%05120x", permute_init(INIT[69 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_46($sformatf("0x%05120x", permute_init(INIT[70 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_47($sformatf("0x%05120x", permute_init(INIT[71 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_48($sformatf("0x%05120x", permute_init(INIT[72 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_49($sformatf("0x%05120x", permute_init(INIT[73 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4A($sformatf("0x%05120x", permute_init(INIT[74 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4B($sformatf("0x%05120x", permute_init(INIT[75 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4C($sformatf("0x%05120x", permute_init(INIT[76 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4D($sformatf("0x%05120x", permute_init(INIT[77 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4E($sformatf("0x%05120x", permute_init(INIT[78 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_4F($sformatf("0x%05120x", permute_init(INIT[79 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_50($sformatf("0x%05120x", permute_init(INIT[80 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_51($sformatf("0x%05120x", permute_init(INIT[81 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_52($sformatf("0x%05120x", permute_init(INIT[82 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_53($sformatf("0x%05120x", permute_init(INIT[83 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_54($sformatf("0x%05120x", permute_init(INIT[84 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_55($sformatf("0x%05120x", permute_init(INIT[85 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_56($sformatf("0x%05120x", permute_init(INIT[86 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_57($sformatf("0x%05120x", permute_init(INIT[87 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_58($sformatf("0x%05120x", permute_init(INIT[88 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_59($sformatf("0x%05120x", permute_init(INIT[89 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5A($sformatf("0x%05120x", permute_init(INIT[90 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5B($sformatf("0x%05120x", permute_init(INIT[91 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5C($sformatf("0x%05120x", permute_init(INIT[92 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5D($sformatf("0x%05120x", permute_init(INIT[93 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5E($sformatf("0x%05120x", permute_init(INIT[94 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_5F($sformatf("0x%05120x", permute_init(INIT[95 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_60($sformatf("0x%05120x", permute_init(INIT[96 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_61($sformatf("0x%05120x", permute_init(INIT[97 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_62($sformatf("0x%05120x", permute_init(INIT[98 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_63($sformatf("0x%05120x", permute_init(INIT[99 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_64($sformatf("0x%05120x", permute_init(INIT[100 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_65($sformatf("0x%05120x", permute_init(INIT[101 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_66($sformatf("0x%05120x", permute_init(INIT[102 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_67($sformatf("0x%05120x", permute_init(INIT[103 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_68($sformatf("0x%05120x", permute_init(INIT[104 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_69($sformatf("0x%05120x", permute_init(INIT[105 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6A($sformatf("0x%05120x", permute_init(INIT[106 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6B($sformatf("0x%05120x", permute_init(INIT[107 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6C($sformatf("0x%05120x", permute_init(INIT[108 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6D($sformatf("0x%05120x", permute_init(INIT[109 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6E($sformatf("0x%05120x", permute_init(INIT[110 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_6F($sformatf("0x%05120x", permute_init(INIT[111 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_70($sformatf("0x%05120x", permute_init(INIT[112 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_71($sformatf("0x%05120x", permute_init(INIT[113 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_72($sformatf("0x%05120x", permute_init(INIT[114 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_73($sformatf("0x%05120x", permute_init(INIT[115 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_74($sformatf("0x%05120x", permute_init(INIT[116 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_75($sformatf("0x%05120x", permute_init(INIT[117 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_76($sformatf("0x%05120x", permute_init(INIT[118 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_77($sformatf("0x%05120x", permute_init(INIT[119 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_78($sformatf("0x%05120x", permute_init(INIT[120 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_79($sformatf("0x%05120x", permute_init(INIT[121 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7A($sformatf("0x%05120x", permute_init(INIT[122 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7B($sformatf("0x%05120x", permute_init(INIT[123 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7C($sformatf("0x%05120x", permute_init(INIT[124 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7D($sformatf("0x%05120x", permute_init(INIT[125 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7E($sformatf("0x%05120x", permute_init(INIT[126 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), +.INITVAL_7F($sformatf("0x%05120x", permute_init(INIT[127 * INIT_CHUNK_SIZE +: INIT_CHUNK_SIZE]))), diff --git a/techlibs/nexus/lrams_map.v b/techlibs/nexus/lrams_map.v new file mode 100644 index 000000000..938a0e843 --- /dev/null +++ b/techlibs/nexus/lrams_map.v @@ -0,0 +1,56 @@ +module \$__NX_PDPSC512K (CLK2, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 14; + parameter CFG_DBITS = 32; + parameter CFG_ENABLE_A = 4; + + parameter CLKPOL2 = 1; + parameter [524287:0] INIT = 524287'b0; + + input CLK2; + + input [CFG_ABITS-1:0] A1ADDR; + input [CFG_DBITS-1:0] A1DATA; + input [CFG_ENABLE_A-1:0] A1EN; + + input [CFG_ABITS-1:0] B1ADDR; + output [CFG_DBITS-1:0] B1DATA; + input B1EN; + + wire clk; + wire [31:0] rd; + assign B1DATA = rd[CFG_DBITS-1:0]; + + generate + if (CLKPOL2) + assign clk = CLK2; + else + INV clk_inv_i (.A(CLK2), .Z(clk)); + endgenerate + + wire we = |A1EN; + + localparam INIT_CHUNK_SIZE = 4096; + + function [5119:0] permute_init; + input [INIT_CHUNK_SIZE-1:0] chunk; + integer i; + begin + for (i = 0; i < 128; i = i + 1'b1) + permute_init[i * 40 +: 40] = {8'b0, chunk[i * 32 +: 32]}; + end + endfunction + + generate + PDPSC512K #( + .OUTREG("NO_REG"), + .ECC_BYTE_SEL("BYTE_EN"), +`include "lrams_init.vh" + .GSR("DISABLED") + ) _TECHMAP_REPLACE_ ( + .CLK(clk), .RSTR(1'b0), + .DI(A1DATA), .ADW(A1ADDR), .CEW(we), .WE(we), .CSW(1'b1), + .ADR(B1ADDR), .DO(rd), .CER(B1EN), .CSR(1'b1), + ); + endgenerate + +endmodule diff --git a/techlibs/nexus/synth_nexus.cc b/techlibs/nexus/synth_nexus.cc index 7e2185ab6..7f36eb282 100644 --- a/techlibs/nexus/synth_nexus.cc +++ b/techlibs/nexus/synth_nexus.cc @@ -77,6 +77,11 @@ struct SynthNexusPass : public ScriptPass log(" -nodffe\n"); log(" do not use flipflops with CE in output netlist\n"); log("\n"); + log(" -nolram\n"); + log(" do not use large RAM cells in output netlist\n"); + log(" note that large RAM must be explicitly requested with a (* lram *)\n"); + log(" attribute on the memory.\n"); + log("\n"); log(" -nobram\n"); log(" do not use block RAM cells in output netlist\n"); log("\n"); @@ -89,6 +94,9 @@ struct SynthNexusPass : public ScriptPass log(" -noiopad\n"); log(" do not insert IO buffers\n"); log("\n"); + log(" -nodsp\n"); + log(" do not infer DSP multipliers\n"); + log("\n"); log(" -abc9\n"); log(" use new ABC9 flow (EXPERIMENTAL)\n"); log("\n"); @@ -98,7 +106,7 @@ struct SynthNexusPass : public ScriptPass } string top_opt, json_file, vm_file, family; - bool noccu2, nodffe, nobram, nolutram, nowidelut, noiopad, flatten, dff, retime, abc9; + bool noccu2, nodffe, nolram, nobram, nolutram, nowidelut, noiopad, nodsp, flatten, dff, retime, abc9; void clear_flags() override { @@ -108,10 +116,12 @@ struct SynthNexusPass : public ScriptPass vm_file = ""; noccu2 = false; nodffe = false; + nolram = false; nobram = false; nolutram = false; nowidelut = false; noiopad = false; + nodsp = false; flatten = true; dff = false; retime = false; @@ -161,6 +171,10 @@ struct SynthNexusPass : public ScriptPass dff = true; continue; } + if (args[argidx] == "-nodsp") { + nodsp = true; + continue; + } if (args[argidx] == "-retime") { retime = true; continue; @@ -173,6 +187,10 @@ struct SynthNexusPass : public ScriptPass nodffe = true; continue; } + if (args[argidx] == "-nolram") { + nolram = true; + continue; + } if (args[argidx] == "-nobram") { nobram = true; continue; @@ -211,6 +229,22 @@ struct SynthNexusPass : public ScriptPass log_pop(); } + struct DSPRule { + int a_maxwidth; + int b_maxwidth; + int a_minwidth; + int b_minwidth; + std::string prim; + }; + + const std::vector<DSPRule> dsp_rules = { + {36, 36, 22, 22, "$__NX_MUL36X36"}, + {36, 18, 22, 10, "$__NX_MUL36X18"}, + {18, 18, 10, 4, "$__NX_MUL18X18"}, + {18, 18, 4, 10, "$__NX_MUL18X18"}, + { 9, 9, 4, 4, "$__NX_MUL9X9"}, + }; + void script() override { @@ -244,12 +278,31 @@ struct SynthNexusPass : public ScriptPass run("opt_expr"); run("opt_clean"); + if (help_mode) { + run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)"); + run("techmap -map +/nexus/dsp_map.v", "(unless -nodsp)"); + } else if (!nodsp) { + for (const auto &rule : dsp_rules) { + run(stringf("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=%d -D DSP_B_MAXWIDTH=%d -D DSP_A_MINWIDTH=%d -D DSP_B_MINWIDTH=%d -D DSP_NAME=%s", + rule.a_maxwidth, rule.b_maxwidth, rule.a_minwidth, rule.b_minwidth, rule.prim.c_str())); + run("chtype -set $mul t:$__soft_mul"); + } + run("techmap -map +/nexus/dsp_map.v"); + } + run("alumacc"); run("opt"); run("memory -nomap"); run("opt_clean"); } + if (!nolram && check_label("map_lram", "(skip if -nolram)")) + { + run("memory_bram -rules +/nexus/lrams.txt"); + run("setundef -zero -params t:$__NX_PDPSC512K"); + run("techmap -map +/nexus/lrams_map.v"); + } + if (!nobram && check_label("map_bram", "(skip if -nobram)")) { run("memory_bram -rules +/nexus/brams.txt"); |