diff options
Diffstat (limited to 'techlibs/intel_alm')
-rw-r--r-- | techlibs/intel_alm/Makefile.inc | 1 | ||||
-rw-r--r-- | techlibs/intel_alm/common/alm_sim.v | 76 | ||||
-rw-r--r-- | techlibs/intel_alm/common/arith_alm_map.v | 2 | ||||
-rw-r--r-- | techlibs/intel_alm/common/bram_m10k.txt | 12 | ||||
-rw-r--r-- | techlibs/intel_alm/common/bram_m20k_map.v | 62 | ||||
-rw-r--r-- | techlibs/intel_alm/common/dff_sim.v | 19 | ||||
-rw-r--r-- | techlibs/intel_alm/common/dsp_sim.v | 47 | ||||
-rw-r--r-- | techlibs/intel_alm/common/megafunction_bb.v | 88 | ||||
-rw-r--r-- | techlibs/intel_alm/common/mem_sim.v | 56 | ||||
-rw-r--r-- | techlibs/intel_alm/common/misc_sim.v | 21 | ||||
-rw-r--r-- | techlibs/intel_alm/common/quartus_rename.v | 73 | ||||
-rw-r--r-- | techlibs/intel_alm/cyclonev/cells_sim.v | 30 | ||||
-rw-r--r-- | techlibs/intel_alm/synth_intel_alm.cc | 38 |
13 files changed, 463 insertions, 62 deletions
diff --git a/techlibs/intel_alm/Makefile.inc b/techlibs/intel_alm/Makefile.inc index da88762c4..614d5802c 100644 --- a/techlibs/intel_alm/Makefile.inc +++ b/techlibs/intel_alm/Makefile.inc @@ -13,6 +13,7 @@ $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/df $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dsp_sim.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/dsp_map.v)) $(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/mem_sim.v)) +$(eval $(call add_share_file,share/intel_alm/common,techlibs/intel_alm/common/misc_sim.v)) $(eval $(call add_share_file,share/intel_alm/cyclonev,techlibs/intel_alm/cyclonev/cells_sim.v)) diff --git a/techlibs/intel_alm/common/alm_sim.v b/techlibs/intel_alm/common/alm_sim.v index 906a95b0b..242f1003f 100644 --- a/techlibs/intel_alm/common/alm_sim.v +++ b/techlibs/intel_alm/common/alm_sim.v @@ -77,6 +77,14 @@ // SUMOUT 368 1342 1323 887 927 - 785 - // CARRYOUT 71 1082 1062 866 813 - 1198 - +// Arria V LUT output timings (picoseconds): +// +// CARRY A B C D E F G +// COMBOUT - 387 375 316 317 - 76 319 (LUT6) +// COMBOUT - 387 375 316 317 218 76 319 (LUT7) +// SUMOUT 249 744 732 562 576 - 511 - +// CARRYOUT 19 629 623 530 514 - 696 - + (* abc9_lut=2, lib_whitebox *) module MISTRAL_ALUT6(input A, B, C, D, E, F, output Q); @@ -92,6 +100,16 @@ specify (F => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 387; + (B => Q) = 375; + (C => Q) = 316; + (D => Q) = 317; + (E => Q) = 319; + (F => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 275; @@ -122,6 +140,15 @@ specify (E => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 375; + (B => Q) = 316; + (C => Q) = 317; + (D => Q) = 319; + (E => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 272; @@ -150,6 +177,14 @@ specify (D => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 316; + (B => Q) = 317; + (C => Q) = 319; + (D => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 175; @@ -176,6 +211,13 @@ specify (C => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 316; + (B => Q) = 317; + (C => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 165; @@ -200,6 +242,12 @@ specify (B => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 316; + (B => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 162; @@ -220,6 +268,11 @@ specify (A => Q) = 97; endspecify `endif +`ifdef arriav +specify + (A => Q) = 76; +endspecify +`endif `ifdef cyclone10gx specify (A => Q) = 53; @@ -230,8 +283,10 @@ assign Q = ~A; endmodule -(* abc9_box, lib_whitebox *) -module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, (* abc9_carry *) input CI, output SO, (* abc9_carry *) output CO); +// Despite the abc9_carry attributes, this doesn't seem to stop ABC9 adding illegal fanout to the carry chain that nextpnr cannot handle. +// So we treat it as a total blackbox from ABC9's perspective for now. +// (* abc9_box, lib_whitebox *) +module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, /* (* abc9_carry *) */ input CI, output SO, /* (* abc9_carry *) */ output CO); parameter LUT0 = 16'h0000; parameter LUT1 = 16'h0000; @@ -253,6 +308,23 @@ specify (CI => CO) = 36; // Divided by 2 to account for there being two ALUT_ARITHs in an ALM) endspecify `endif +`ifdef arriav +specify + (A => SO) = 744; + (B => SO) = 732; + (C => SO) = 562; + (D0 => SO) = 576; + (D1 => SO) = 511; + (CI => SO) = 249; + + (A => CO) = 629; + (B => CO) = 623; + (C => CO) = 530; + (D0 => CO) = 514; + (D1 => CO) = 696; + (CI => CO) = 10; // Divided by 2 to account for there being two ALUT_ARITHs in an ALM) +endspecify +`endif `ifdef cyclone10gx specify (A => SO) = 644; diff --git a/techlibs/intel_alm/common/arith_alm_map.v b/techlibs/intel_alm/common/arith_alm_map.v index 8515eeb56..7cbf02e9c 100644 --- a/techlibs/intel_alm/common/arith_alm_map.v +++ b/techlibs/intel_alm/common/arith_alm_map.v @@ -34,7 +34,7 @@ wire [Y_WIDTH:0] ALM_CARRY; // Start of carry chain generate - if (_TECHMAP_CONSTMSK_CI_ == 1) begin + if (_TECHMAP_CONSTMSK_CI_ == 1 && _TECHMAP_CONSTVAL_CI_ == 1'b0) begin assign ALM_CARRY[0] = _TECHMAP_CONSTVAL_CI_; end else begin MISTRAL_ALUT_ARITH #( diff --git a/techlibs/intel_alm/common/bram_m10k.txt b/techlibs/intel_alm/common/bram_m10k.txt index e9355fe2c..0d9a49b7d 100644 --- a/techlibs/intel_alm/common/bram_m10k.txt +++ b/techlibs/intel_alm/common/bram_m10k.txt @@ -4,18 +4,12 @@ bram MISTRAL_M10K dbits 1 @D8192x1 abits 12 @D4096x2 dbits 2 @D4096x2 - abits 11 @D2048x4 @D2048x5 - dbits 4 @D2048x4 + abits 11 @D2048x5 dbits 5 @D2048x5 - abits 10 @D1024x8 @D1024x10 - dbits 8 @D1024x8 + abits 10 @D1024x10 dbits 10 @D1024x10 - abits 9 @D512x16 @D512x20 - dbits 16 @D512x16 + abits 9 @D512x20 dbits 20 @D512x20 - abits 8 @D256x32 @D256x40 - dbits 32 @D256x32 - dbits 40 @D256x40 groups 2 ports 1 1 wrmode 1 0 diff --git a/techlibs/intel_alm/common/bram_m20k_map.v b/techlibs/intel_alm/common/bram_m20k_map.v index 92f41310f..15739d66a 100644 --- a/techlibs/intel_alm/common/bram_m20k_map.v +++ b/techlibs/intel_alm/common/bram_m20k_map.v @@ -1,31 +1,31 @@ -module __MISTRAL_M20K_SDP(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
-
-parameter CFG_ABITS = 10;
-parameter CFG_DBITS = 20;
-parameter CFG_ENABLE_A = 1;
-parameter CFG_ENABLE_B = 1;
-
-input CLK1;
-input [CFG_ABITS-1:0] A1ADDR, B1ADDR;
-input [CFG_DBITS-1:0] A1DATA;
-output [CFG_DBITS-1:0] B1DATA;
-input [CFG_ENABLE_A-1:0] A1EN, B1EN;
-
-altsyncram #(
- .operation_mode("dual_port"),
- .ram_block_type("m20k"),
- .widthad_a(CFG_ABITS),
- .width_a(CFG_DBITS),
- .widthad_b(CFG_ABITS),
- .width_b(CFG_DBITS),
-) _TECHMAP_REPLACE_ (
- .address_a(A1ADDR),
- .data_a(A1DATA),
- .wren_a(A1EN),
- .address_b(B1ADDR),
- .q_b(B1DATA),
- .clock0(CLK1),
- .clock1(CLK1)
-);
-
-endmodule
+module __MISTRAL_M20K_SDP(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + +parameter CFG_ABITS = 10; +parameter CFG_DBITS = 20; +parameter CFG_ENABLE_A = 1; +parameter CFG_ENABLE_B = 1; + +input CLK1; +input [CFG_ABITS-1:0] A1ADDR, B1ADDR; +input [CFG_DBITS-1:0] A1DATA; +output [CFG_DBITS-1:0] B1DATA; +input [CFG_ENABLE_A-1:0] A1EN, B1EN; + +altsyncram #( + .operation_mode("dual_port"), + .ram_block_type("m20k"), + .widthad_a(CFG_ABITS), + .width_a(CFG_DBITS), + .widthad_b(CFG_ABITS), + .width_b(CFG_DBITS), +) _TECHMAP_REPLACE_ ( + .address_a(A1ADDR), + .data_a(A1DATA), + .wren_a(A1EN), + .address_b(B1ADDR), + .q_b(B1DATA), + .clock0(CLK1), + .clock1(CLK1) +); + +endmodule diff --git a/techlibs/intel_alm/common/dff_sim.v b/techlibs/intel_alm/common/dff_sim.v index d2cff0adb..8d58bf614 100644 --- a/techlibs/intel_alm/common/dff_sim.v +++ b/techlibs/intel_alm/common/dff_sim.v @@ -56,7 +56,9 @@ (* abc9_box, lib_whitebox *) module MISTRAL_FF( - input DATAIN, CLK, ACLR, ENA, SCLR, SLOAD, SDATA, + input DATAIN, + (* clkbuf_sink *) input CLK, + input ACLR, ENA, SCLR, SLOAD, SDATA, output reg Q ); @@ -75,6 +77,21 @@ specify if (ACLR === 1'b0) (ACLR => Q) = 282; endspecify `endif +`ifdef arriav +specify + if (ENA && ACLR !== 1'b0 && !SCLR && !SLOAD) (posedge CLK => (Q : DATAIN)) = 470; + if (ENA && SCLR) (posedge CLK => (Q : 1'b0)) = 633; + if (ENA && !SCLR && SLOAD) (posedge CLK => (Q : SDATA)) = 439; + + $setup(DATAIN, posedge CLK, /* -170 */ 0); + $setup(ENA, posedge CLK, /* -170 */ 0); + $setup(SCLR, posedge CLK, /* -170 */ 0); + $setup(SLOAD, posedge CLK, /* -170 */ 0); + $setup(SDATA, posedge CLK, /* -170 */ 0); + + if (ACLR === 1'b0) (ACLR => Q) = 215; +endspecify +`endif `ifdef cyclone10gx specify // TODO (long-term): investigate these numbers. diff --git a/techlibs/intel_alm/common/dsp_sim.v b/techlibs/intel_alm/common/dsp_sim.v index bdb6d18d5..3d4b5590b 100644 --- a/techlibs/intel_alm/common/dsp_sim.v +++ b/techlibs/intel_alm/common/dsp_sim.v @@ -1,14 +1,31 @@ +`default_nettype none + (* abc9_box *) module MISTRAL_MUL27X27(input [26:0] A, input [26:0] B, output [53:0] Y); parameter A_SIGNED = 1; parameter B_SIGNED = 1; +`ifdef cyclonev +specify + (A *> Y) = 3732; + (B *> Y) = 3928; +endspecify +`endif +`ifdef arriav +// NOTE: Arria V appears to have only one set of timings for all DSP modes... +specify + (A *> Y) = 1895; + (B *> Y) = 2053; +endspecify +`endif +`ifdef cyclone10gx // TODO: Cyclone 10 GX timings; the below are for Cyclone V specify (A *> Y) = 3732; (B *> Y) = 3928; endspecify +`endif wire [53:0] A_, B_; @@ -32,11 +49,26 @@ module MISTRAL_MUL18X18(input [17:0] A, input [17:0] B, output [35:0] Y); parameter A_SIGNED = 1; parameter B_SIGNED = 1; +`ifdef cyclonev +specify + (A *> Y) = 3180; + (B *> Y) = 3982; +endspecify +`endif +`ifdef arriav +// NOTE: Arria V appears to have only one set of timings for all DSP modes... +specify + (A *> Y) = 1895; + (B *> Y) = 2053; +endspecify +`endif +`ifdef cyclone10gx // TODO: Cyclone 10 GX timings; the below are for Cyclone V specify (A *> Y) = 3180; (B *> Y) = 3982; endspecify +`endif wire [35:0] A_, B_; @@ -60,11 +92,26 @@ module MISTRAL_MUL9X9(input [8:0] A, input [8:0] B, output [17:0] Y); parameter A_SIGNED = 1; parameter B_SIGNED = 1; +`ifdef cyclonev +specify + (A *> Y) = 2818; + (B *> Y) = 3051; +endspecify +`endif +`ifdef arriav +// NOTE: Arria V appears to have only one set of timings for all DSP modes... +specify + (A *> Y) = 1895; + (B *> Y) = 2053; +endspecify +`endif +`ifdef cyclone10gx // TODO: Cyclone 10 GX timings; the below are for Cyclone V specify (A *> Y) = 2818; (B *> Y) = 3051; endspecify +`endif wire [17:0] A_, B_; diff --git a/techlibs/intel_alm/common/megafunction_bb.v b/techlibs/intel_alm/common/megafunction_bb.v index 874f293b1..d4ed95173 100644 --- a/techlibs/intel_alm/common/megafunction_bb.v +++ b/techlibs/intel_alm/common/megafunction_bb.v @@ -627,3 +627,91 @@ output [port_b_data_width-1:0] portbdataout; input clk0, portawe, portbre; endmodule + +(* blackbox *) +module cyclone10gx_io_ibuf(i, ibar, dynamicterminationcontrol, o); + +parameter differential_mode ="false"; +parameter bus_hold = "false"; +parameter simulate_z_as = "Z"; +parameter lpm_type = "cyclone10gx_io_ibuf"; + +(* iopad_external_pin *) input i; +(* iopad_external_pin *) input ibar; +input dynamicterminationcontrol; +output o; + +endmodule + +(* blackbox *) +module cyclone10gx_io_obuf(i, oe, dynamicterminationcontrol, seriesterminationcontrol, parallelterminationcontrol, devoe, o, obar); + +parameter open_drain_output = "false"; +parameter bus_hold = "false"; +parameter shift_series_termination_control = "false"; +parameter sim_dynamic_termination_control_is_connected = "false"; +parameter lpm_type = "cyclone10gx_io_obuf"; + +input i; +input oe; +input devoe; +input dynamicterminationcontrol; +input [15:0] seriesterminationcontrol; +input [15:0] parallelterminationcontrol; +(* iopad_external_pin *) output o; +(* iopad_external_pin *) output obar; + +endmodule + +(* blackbox *) +module cyclonev_clkena(inclk, ena, enaout, outclk); + +parameter clock_type = "auto"; +parameter ena_register_mode = "always enabled"; +parameter lpm_type = "cyclonev_clkena"; +parameter ena_register_power_up = "high"; +parameter disable_mode = "low"; +parameter test_syn = "high"; + +input inclk; +input ena; +output enaout; +output outclk; + +endmodule + +(* blackbox *) +module cyclone10gx_clkena(inclk, ena, enaout, outclk); + +parameter clock_type = "auto"; +parameter ena_register_mode = "always enabled"; +parameter lpm_type = "cyclone10gx_clkena"; +parameter ena_register_power_up = "high"; +parameter disable_mode = "low"; +parameter test_syn = "high"; + +input inclk; +input ena; +output enaout; +output outclk; + +endmodule + +// Internal interfaces +(* keep *) +module cyclonev_oscillator(oscena, clkout, clkout1); + +input oscena; +output clkout; +output clkout1; + +endmodule + +// HPS interfaces +(* keep *) +module cyclonev_hps_interface_mpu_general_purpose(gp_in, gp_out); + +input [31:0] gp_in; +output [31:0] gp_out; + +endmodule diff --git a/techlibs/intel_alm/common/mem_sim.v b/techlibs/intel_alm/common/mem_sim.v index e09aafaa2..370e17f27 100644 --- a/techlibs/intel_alm/common/mem_sim.v +++ b/techlibs/intel_alm/common/mem_sim.v @@ -50,10 +50,39 @@ // model can be treated as always returning a defined result. (* abc9_box, lib_whitebox *) -module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, CLK1, input [4:0] B1ADDR, output B1DATA); +module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN, + (* clkbuf_sink *) input CLK1, + input [4:0] B1ADDR, output B1DATA); reg [31:0] mem = 32'b0; +`ifdef cyclonev +specify + $setup(A1ADDR, posedge CLK1, 86); + $setup(A1DATA, posedge CLK1, 86); + $setup(A1EN, posedge CLK1, 86); + + (B1ADDR[0] => B1DATA) = 487; + (B1ADDR[1] => B1DATA) = 475; + (B1ADDR[2] => B1DATA) = 382; + (B1ADDR[3] => B1DATA) = 284; + (B1ADDR[4] => B1DATA) = 96; +endspecify +`endif +`ifdef arriav +specify + $setup(A1ADDR, posedge CLK1, 62); + $setup(A1DATA, posedge CLK1, 62); + $setup(A1EN, posedge CLK1, 62); + + (B1ADDR[0] => B1DATA) = 370; + (B1ADDR[1] => B1DATA) = 292; + (B1ADDR[2] => B1DATA) = 218; + (B1ADDR[3] => B1DATA) = 74; + (B1ADDR[4] => B1DATA) = 177; +endspecify +`endif +`ifdef cyclone10gx // TODO: Cyclone 10 GX timings; the below timings are for Cyclone V specify $setup(A1ADDR, posedge CLK1, 86); @@ -66,6 +95,7 @@ specify (B1ADDR[3] => B1DATA) = 284; (B1ADDR[4] => B1DATA) = 96; endspecify +`endif always @(posedge CLK1) if (A1EN) mem[A1ADDR] <= A1DATA; @@ -83,7 +113,7 @@ module MISTRAL_M10K(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CFG_ABITS = 10; parameter CFG_DBITS = 10; -input CLK1; +(* clkbuf_sink *) input CLK1; input [CFG_ABITS-1:0] A1ADDR, B1ADDR; input [CFG_DBITS-1:0] A1DATA; input A1EN, B1EN; @@ -91,12 +121,28 @@ output reg [CFG_DBITS-1:0] B1DATA; reg [2**CFG_ABITS * CFG_DBITS - 1 : 0] mem = 0; +`ifdef cyclonev +specify + $setup(A1ADDR, posedge CLK1, 125); + $setup(A1DATA, posedge CLK1, 97); + $setup(A1EN, posedge CLK1, 140); + $setup(B1ADDR, posedge CLK1, 125); + $setup(B1EN, posedge CLK1, 161); + + if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 1004; +endspecify +`endif +`ifdef arriav specify - $setup(A1ADDR, posedge CLK1, 0); - $setup(A1DATA, posedge CLK1, 0); + $setup(A1ADDR, posedge CLK1, 97); + $setup(A1DATA, posedge CLK1, 74); + $setup(A1EN, posedge CLK1, 109); + $setup(B1ADDR, posedge CLK1, 97); + $setup(B1EN, posedge CLK1, 126); - if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 0; + if (B1EN) (posedge CLK1 => (B1DATA : A1DATA)) = 787; endspecify +`endif always @(posedge CLK1) begin if (A1EN) diff --git a/techlibs/intel_alm/common/misc_sim.v b/techlibs/intel_alm/common/misc_sim.v new file mode 100644 index 000000000..b1f970a21 --- /dev/null +++ b/techlibs/intel_alm/common/misc_sim.v @@ -0,0 +1,21 @@ +module MISTRAL_IB((* iopad_external_pin *) input PAD, output O); + assign O = PAD; +endmodule + +module MISTRAL_OB((* iopad_external_pin *) output PAD, input I); + assign PAD = I; +endmodule + +module MISTRAL_IO((* iopad_external_pin *) inout PAD, input I, input OE, output O); + assign PAD = OE ? I : 1'bz; + assign O = PAD; +endmodule + +// Eventually, we should support clock enables and model them here too. +// For now, CLKENA is used as a basic entry point to global routing. +module MISTRAL_CLKBUF ( + input A, + (* clkbuf_driver *) output Q +); + assign Q = A; +endmodule
\ No newline at end of file diff --git a/techlibs/intel_alm/common/quartus_rename.v b/techlibs/intel_alm/common/quartus_rename.v index 3b4628675..5850f6907 100644 --- a/techlibs/intel_alm/common/quartus_rename.v +++ b/techlibs/intel_alm/common/quartus_rename.v @@ -2,11 +2,28 @@ `define LCELL cyclonev_lcell_comb `define MAC cyclonev_mac `define MLAB cyclonev_mlab_cell +`define RAM_BLOCK cyclonev_ram_block +`define IBUF cyclonev_io_ibuf +`define OBUF cyclonev_io_obuf +`define CLKENA cyclonev_clkena +`endif +`ifdef arriav +`define LCELL arriav_lcell_comb +`define MAC arriav_mac +`define MLAB arriav_mlab_cell +`define RAM_BLOCK arriav_ram_block +`define IBUF arriav_io_ibuf +`define OBUF arriav_io_obuf +`define CLKENA arriav_clkena `endif `ifdef cyclone10gx `define LCELL cyclone10gx_lcell_comb `define MAC cyclone10gx_mac `define MLAB cyclone10gx_mlab_cell +`define RAM_BLOCK cyclone10gx_ram_block +`define IBUF cyclone10gx_io_ibuf +`define OBUF cyclone10gx_io_obuf +`define CLKENA cyclone10gx_clkena `endif module __MISTRAL_VCC(output Q); @@ -140,7 +157,7 @@ output [CFG_DBITS-1:0] B1DATA; // Much like the MLAB, the M10K has mem_init[01234] parameters which would let // you initialise the RAM cell via hex literals. If they were implemented. -cyclonev_ram_block #( +`RAM_BLOCK #( .operation_mode("dual_port"), .logical_ram_name(_TECHMAP_CELLNAME_), .port_a_address_width(CFG_ABITS), @@ -233,3 +250,57 @@ parameter B_SIGNED = 1; ); endmodule + +module MISTRAL_IB(input PAD, output O); +`IBUF #( + .bus_hold("false"), + .differential_mode("false") +) _TECHMAP_REPLACE_ ( + .i(PAD), + .o(O) +); +endmodule + +module MISTRAL_OB(output PAD, input I, OE); +`OBUF #( + .bus_hold("false"), + .differential_mode("false") +) _TECHMAP_REPLACE_ ( + .i(I), + .o(PAD), + .oe(OE) +); +endmodule + +module MISTRAL_IO(output PAD, input I, OE, output O); +`IBUF #( + .bus_hold("false"), + .differential_mode("false") +) ibuf ( + .i(PAD), + .o(O) +); + +`OBUF #( + .bus_hold("false"), + .differential_mode("false") +) obuf ( + .i(I), + .o(PAD), + .oe(OE) +); +endmodule + +module MISTRAL_CLKBUF (input A, output Q); +`CLKENA #( + .clock_type("auto"), + .ena_register_mode("always enabled"), + .ena_register_power_up("high"), + .disable_mode("low"), + .test_syn("high") +) _TECHMAP_REPLACE_ ( + .inclk(A), + .ena(1'b1), + .outclk(Q) +); +endmodule diff --git a/techlibs/intel_alm/cyclonev/cells_sim.v b/techlibs/intel_alm/cyclonev/cells_sim.v index 9b2a10e72..14bb756cf 100644 --- a/techlibs/intel_alm/cyclonev/cells_sim.v +++ b/techlibs/intel_alm/cyclonev/cells_sim.v @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> + * Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -26,16 +26,34 @@ endmodule // GND /* Altera Cyclone V devices Input Buffer Primitive */ module cyclonev_io_ibuf - (output o, input i, input ibar); - assign ibar = ibar; + (output o, + (* iopad_external_pin *) input i, + (* iopad_external_pin *) input ibar, + input dynamicterminationcontrol); + + parameter differential_mode = "false"; + parameter bus_hold = "false"; + parameter simulate_z_as = "Z"; + parameter lpm_type = "cyclonev_io_ibuf"; + assign o = i; endmodule // cyclonev_io_ibuf /* Altera Cyclone V devices Output Buffer Primitive */ module cyclonev_io_obuf - (output o, input i, input oe); - assign o = i; - assign oe = oe; + ((* iopad_external_pin *) output o, + input i, oe, dynamicterminationcontrol, + input [15:0] seriesterminationcontrol, parallelterminationcontrol, + input devoe, + (* iopad_external_pin *) output obar); + + parameter open_drain_output = "false"; + parameter bus_hold = "false"; + parameter shift_series_termination_control = "false"; + parameter sim_dynamic_termination_control_is_connected = "false"; + parameter lpm_type = "cyclonev_io_obuf"; + + assign o = oe ? i : 1'bz; endmodule // cyclonev_io_obuf /* Altera Cyclone V LUT Primitive */ diff --git a/techlibs/intel_alm/synth_intel_alm.cc b/techlibs/intel_alm/synth_intel_alm.cc index 6719eb65c..34a5ffa5d 100644 --- a/techlibs/intel_alm/synth_intel_alm.cc +++ b/techlibs/intel_alm/synth_intel_alm.cc @@ -1,7 +1,7 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2012 Claire Wolf <claire@symbioticeda.com> + * Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com> * Copyright (C) 2019 Dan Ravensloft <dan.ravensloft@gmail.com> * * Permission to use, copy, modify, and/or distribute this software for any @@ -43,6 +43,7 @@ struct SynthIntelALMPass : public ScriptPass { log(" -family <family>\n"); log(" target one of:\n"); log(" \"cyclonev\" - Cyclone V (default)\n"); + log(" \"arriav\" - Arria V (non-GZ)"); log(" \"cyclone10gx\" - Cyclone 10GX\n"); log("\n"); log(" -vqm <file>\n"); @@ -72,13 +73,19 @@ struct SynthIntelALMPass : public ScriptPass { log(" -nodsp\n"); log(" do not map multipliers to MISTRAL_MUL cells\n"); log("\n"); + log(" -noiopad\n"); + log(" do not instantiate IO buffers\n"); + log("\n"); + log(" -noclkbuf\n"); + log(" do not insert global clock buffers\n"); + log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } string top_opt, family_opt, bram_type, vout_file; - bool flatten, quartus, nolutram, nobram, dff, nodsp; + bool flatten, quartus, nolutram, nobram, dff, nodsp, noiopad, noclkbuf; void clear_flags() override { @@ -92,6 +99,8 @@ struct SynthIntelALMPass : public ScriptPass { nobram = false; dff = false; nodsp = false; + noiopad = false; + noclkbuf = false; } void execute(std::vector<std::string> args, RTLIL::Design *design) override @@ -146,6 +155,14 @@ struct SynthIntelALMPass : public ScriptPass { dff = true; continue; } + if (args[argidx] == "-noiopad") { + noiopad = true; + continue; + } + if (args[argidx] == "-noclkbuf") { + noclkbuf = true; + continue; + } break; } extra_args(args, argidx, design); @@ -153,10 +170,14 @@ struct SynthIntelALMPass : public ScriptPass { if (!design->full_selection()) log_cmd_error("This command only operates on fully selected designs!\n"); - if (family_opt == "cyclonev") { + if (family_opt == "cyclonev" || family_opt == "arriav") { bram_type = "m10k"; } else if (family_opt == "cyclone10gx") { bram_type = "m20k"; + } else if (family_opt == "arriva") { + // I have typoed "arriav" as "arriva" (a local bus company) + // so many times I thought it would be funny to have an easter egg. + log_cmd_error("synth_intel_alm cannot synthesize for bus companies. (did you mean '-family arriav'?)\n"); } else { log_cmd_error("Invalid family specified: '%s'\n", family_opt.c_str()); } @@ -183,8 +204,8 @@ struct SynthIntelALMPass : public ScriptPass { run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dff_sim.v", family_opt.c_str())); run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/dsp_sim.v", family_opt.c_str())); run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/mem_sim.v", family_opt.c_str())); + run(stringf("read_verilog -specify -lib -D %s +/intel_alm/common/misc_sim.v", family_opt.c_str())); run(stringf("read_verilog -specify -lib -D %s -icells +/intel_alm/common/abc9_model.v", family_opt.c_str())); - // Misc and common cells run("read_verilog -lib +/intel/common/altpll_bb.v"); run("read_verilog -lib +/intel_alm/common/megafunction_bb.v"); @@ -213,12 +234,12 @@ struct SynthIntelALMPass : public ScriptPass { if (help_mode) { run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)"); } else if (!nodsp) { - // Cyclone V supports 9x9 multiplication, Cyclone 10 GX does not. + // Cyclone V/Arria V supports 9x9 multiplication, Cyclone 10 GX does not. run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=19 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL27X27"); run("chtype -set $mul t:$__soft_mul"); run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=27 -D DSP_B_MAXWIDTH=27 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=19 -D DSP_NAME=__MUL27X27"); run("chtype -set $mul t:$__soft_mul"); - if (family_opt == "cyclonev") { + if (family_opt == "cyclonev" || family_opt == "arriav") { run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=4 -D DSP_NAME=__MUL18X18"); run("chtype -set $mul t:$__soft_mul"); run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=10 -D DSP_NAME=__MUL18X18"); @@ -231,6 +252,8 @@ struct SynthIntelALMPass : public ScriptPass { } } run("alumacc"); + if (!noiopad) + run("iopadmap -bits -outpad MISTRAL_OB I:PAD -inpad MISTRAL_IB O:PAD -toutpad MISTRAL_IO OE:O:PAD -tinoutpad MISTRAL_IO OE:O:I:PAD A:top", "(unless -noiopad)"); run("techmap -map +/intel_alm/common/arith_alm_map.v -map +/intel_alm/common/dsp_map.v"); run("opt"); run("memory -nomap"); @@ -258,6 +281,8 @@ struct SynthIntelALMPass : public ScriptPass { run("techmap -map +/intel_alm/common/dff_map.v"); run("opt -full -undriven -mux_undef"); run("clean -purge"); + if (!noclkbuf) + run("clkbufmap -buf MISTRAL_CLKBUF Q:A", "(unless -noclkbuf)"); } if (check_label("map_luts")) { @@ -274,6 +299,7 @@ struct SynthIntelALMPass : public ScriptPass { run("hierarchy -check"); run("stat"); run("check"); + run("blackbox =A:whitebox"); } if (check_label("quartus")) { |