aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/nexus
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/nexus')
-rw-r--r--techlibs/nexus/Makefile.inc4
-rw-r--r--techlibs/nexus/arith_map.v4
-rw-r--r--techlibs/nexus/cells_sim.v564
-rw-r--r--techlibs/nexus/cells_xtra.py18
-rw-r--r--techlibs/nexus/cells_xtra.v241
-rw-r--r--techlibs/nexus/dsp_map.v79
-rw-r--r--techlibs/nexus/lrams.txt22
-rw-r--r--techlibs/nexus/lrams_init.vh128
-rw-r--r--techlibs/nexus/lrams_map.v56
-rw-r--r--techlibs/nexus/synth_nexus.cc55
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");