aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/intel_alm
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/intel_alm')
-rw-r--r--techlibs/intel_alm/Makefile.inc1
-rw-r--r--techlibs/intel_alm/common/alm_sim.v76
-rw-r--r--techlibs/intel_alm/common/arith_alm_map.v2
-rw-r--r--techlibs/intel_alm/common/bram_m10k.txt12
-rw-r--r--techlibs/intel_alm/common/bram_m20k_map.v62
-rw-r--r--techlibs/intel_alm/common/dff_sim.v19
-rw-r--r--techlibs/intel_alm/common/dsp_sim.v47
-rw-r--r--techlibs/intel_alm/common/megafunction_bb.v88
-rw-r--r--techlibs/intel_alm/common/mem_sim.v56
-rw-r--r--techlibs/intel_alm/common/misc_sim.v21
-rw-r--r--techlibs/intel_alm/common/quartus_rename.v73
-rw-r--r--techlibs/intel_alm/cyclonev/cells_sim.v30
-rw-r--r--techlibs/intel_alm/synth_intel_alm.cc38
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")) {