diff options
Diffstat (limited to 'techlibs')
-rw-r--r-- | techlibs/gowin/cells_sim.v | 45 | ||||
-rw-r--r-- | techlibs/intel/common/m9k_bb.v | 2 | ||||
-rw-r--r-- | techlibs/nexus/Makefile.inc | 1 | ||||
-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/synth_nexus.cc | 38 |
8 files changed, 736 insertions, 252 deletions
diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index 47ece84df..509bf3ef2 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -821,3 +821,48 @@ endspecify endmodule +(* blackbox *) +module rPLL (CLKOUT, CLKOUTP, CLKOUTD, CLKOUTD3, LOCK, CLKIN, CLKFB, FBDSEL, IDSEL, ODSEL, DUTYDA, PSDA, FDLY, RESET, RESET_P); +input CLKIN; +input CLKFB; +input RESET; +input RESET_P; +input [5:0] FBDSEL; +input [5:0] IDSEL; +input [5:0] ODSEL; +input [3:0] PSDA,FDLY; +input [3:0] DUTYDA; + +output CLKOUT; +output LOCK; +output CLKOUTP; +output CLKOUTD; +output CLKOUTD3; + +parameter FCLKIN = "100.0"; // frequency of CLKIN +parameter DYN_IDIV_SEL= "false"; // true:IDSEL, false:IDIV_SEL +parameter IDIV_SEL = 0; // 0:1, 1:2 ... 63:64 +parameter DYN_FBDIV_SEL= "false"; // true:FBDSEL, false:FBDIV_SEL +parameter FBDIV_SEL = 0; // 0:1, 1:2 ... 63:64 +parameter DYN_ODIV_SEL= "false"; // true:ODSEL, false:ODIV_SEL +parameter ODIV_SEL = 8; // 2/4/8/16/32/48/64/80/96/112/128 + +parameter PSDA_SEL= "0000"; +parameter DYN_DA_EN = "false"; // true:PSDA or DUTYDA or FDA, false: DA_SEL +parameter DUTYDA_SEL= "1000"; + +parameter CLKOUT_FT_DIR = 1'b1; // CLKOUT fine tuning direction. 1'b1 only +parameter CLKOUTP_FT_DIR = 1'b1; // 1'b1 only +parameter CLKOUT_DLY_STEP = 0; // 0, 1, 2, 4 +parameter CLKOUTP_DLY_STEP = 0; // 0, 1, 2 + +parameter CLKFB_SEL = "internal"; // "internal", "external" +parameter CLKOUT_BYPASS = "false"; // "true", "false" +parameter CLKOUTP_BYPASS = "false"; // "true", "false" +parameter CLKOUTD_BYPASS = "false"; // "true", "false" +parameter DYN_SDIV_SEL = 2; // 2~128, only even numbers +parameter CLKOUTD_SRC = "CLKOUT"; // CLKOUT, CLKOUTP +parameter CLKOUTD3_SRC = "CLKOUT"; // CLKOUT, CLKOUTP +parameter DEVICE = "GW1N-1"; // "GW1N-1", "GW1N-4", "GW1N-9", "GW1NR-4", "GW1NR-9", "GW1N-4B", "GW1NR-4B", "GW1NS-2", "GW1NS-2C", "GW1NZ-1", "GW1NSR-2", "GW1NSR-2C", "GW1N-1S", "GW1NSE-2C", "GW1NRF-4B", "GW1N-9C", "GW1NR-9C", "GW1N-4C", "GW1NR-4C" + +endmodule diff --git a/techlibs/intel/common/m9k_bb.v b/techlibs/intel/common/m9k_bb.v index b18a752f5..4bb230642 100644 --- a/techlibs/intel/common/m9k_bb.v +++ b/techlibs/intel/common/m9k_bb.v @@ -32,7 +32,7 @@ module altsyncram(data_a, address_a, wren_a, rden_a, q_a, data_b, address_b, wr parameter outdata_reg_a = "UNREGISTERED"; parameter operation_mode = "SINGLE_PORT"; parameter intended_device_family = "MAX 10 FPGA"; - parameter outdata_reg_a = "UNREGISTERED"; + parameter outdata_reg_b = "UNREGISTERED"; parameter lpm_type = "altsyncram"; parameter init_type = "unused"; parameter ram_block_type = "AUTO"; diff --git a/techlibs/nexus/Makefile.inc b/techlibs/nexus/Makefile.inc index e0ff40e15..c9a9ad4ff 100644 --- a/techlibs/nexus/Makefile.inc +++ b/techlibs/nexus/Makefile.inc @@ -11,4 +11,5 @@ $(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/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/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/synth_nexus.cc b/techlibs/nexus/synth_nexus.cc index 7e2185ab6..9eabbace7 100644 --- a/techlibs/nexus/synth_nexus.cc +++ b/techlibs/nexus/synth_nexus.cc @@ -89,6 +89,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 +101,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, nobram, nolutram, nowidelut, noiopad, nodsp, flatten, dff, retime, abc9; void clear_flags() override { @@ -112,6 +115,7 @@ struct SynthNexusPass : public ScriptPass nolutram = false; nowidelut = false; noiopad = false; + nodsp = false; flatten = true; dff = false; retime = false; @@ -161,6 +165,10 @@ struct SynthNexusPass : public ScriptPass dff = true; continue; } + if (args[argidx] == "-nodsp") { + nodsp = true; + continue; + } if (args[argidx] == "-retime") { retime = true; continue; @@ -211,6 +219,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,6 +268,18 @@ 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"); |