intel_alm: preliminary Arria V support
authorLofty <dan.ravensloft@gmail.com>
Wed, 24 Nov 2021 21:20:40 +0000 (21:20 +0000)
committerMarcelina Koƛcielnicka <mwk@0x04.net>
Thu, 25 Nov 2021 16:20:36 +0000 (17:20 +0100)
techlibs/intel_alm/common/alm_sim.v
techlibs/intel_alm/common/dff_sim.v
techlibs/intel_alm/common/dsp_sim.v
techlibs/intel_alm/common/mem_sim.v
techlibs/intel_alm/common/quartus_rename.v
techlibs/intel_alm/synth_intel_alm.cc

index 6e70be86529b160eac2f8d03fbd91d12a8020fe2..242f1003f2ff19e5312c3970299ad731a1397b68 100644 (file)
 //   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;
@@ -255,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;
index 6bee994be50141428616acd73724567ebc7471c1..8d58bf614854130dde931898bba8cb97bd399231 100644 (file)
@@ -77,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.
index bdb6d18d561868c868501f1bb0c07818056d3d26..3d4b5590b66122206dfb6c56264ea5fff04fe991 100644 (file)
@@ -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_;
 
index dbdf69839413ad59c0f4f2574aa3896c0329085b..370e17f27314d75e12118aee385bfd261e6f6da8 100644 (file)
@@ -56,6 +56,33 @@ module MISTRAL_MLAB(input [4:0] A1ADDR, input A1DATA, A1EN,
 
 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);
@@ -68,6 +95,7 @@ specify
     (B1ADDR[3] => B1DATA) = 284;
     (B1ADDR[4] => B1DATA) = 96;
 endspecify
+`endif
 
 always @(posedge CLK1)
     if (A1EN) mem[A1ADDR] <= A1DATA;
@@ -93,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)
index 57321de778894ac0c42d5f0439f6da999a5a5e42..5850f6907eb9579b884a7ebc3918ca12e6783e53 100644 (file)
@@ -2,14 +2,25 @@
 `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
@@ -146,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),
index 385fc26b6b78a8f47d4eb87e93de559378755d26..34a5ffa5d9849ba00c2ee205ec70905febb3a374 100644 (file)
@@ -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");
@@ -169,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());
                }
@@ -229,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");