intel_alm: work around a Quartus ICE
authorDan Ravensloft <dan.ravensloft@gmail.com>
Wed, 22 Apr 2020 23:56:49 +0000 (00:56 +0100)
committerMarcelina Koƛcielnicka <mwk@0x04.net>
Thu, 23 Apr 2020 09:03:28 +0000 (11:03 +0200)
techlibs/intel_alm/synth_intel_alm.cc
tests/arch/intel_alm/quartus_ice.ys [new file with mode: 0644]

index 47aa11500f928e68b12e6db70fc4d4f218fcbf23..5d4c78d7499384a1e29ba2304ff6c50600eca61d 100644 (file)
@@ -200,6 +200,8 @@ struct SynthIntelALMPass : public ScriptPass {
 
                if (check_label("map_ffs")) {
                        run("dff2dffe -direct-match $_DFF_*");
+                       // As mentioned in common/dff_sim.v, Intel flops power up to zero,
+                       // so use `zinit` to add inverters where needed.
                        run("zinit");
                        run("techmap -map +/techmap.v -map +/intel_alm/common/dff_map.v");
                        run("opt -full -undriven -mux_undef");
@@ -223,8 +225,16 @@ struct SynthIntelALMPass : public ScriptPass {
 
                if (check_label("quartus")) {
                        if (quartus || help_mode) {
+                               // Quartus ICEs if you have a wire which has `[]` in its name,
+                               // which Yosys produces when building memories out of flops.
+                               run("rename -hide w:*[* w:*]*");
+                               // VQM mode does not support 'x, so replace those with zero.
                                run("setundef -zero");
+                               // VQM mode does not support multi-bit constant assignments
+                               // (e.g. 2'b00 is an error), so as a workaround use references
+                               // to constant driver cells, which Quartus accepts.
                                run("hilomap -singleton -hicell __MISTRAL_VCC Q -locell __MISTRAL_GND Q");
+                               // Rename from Yosys-internal MISTRAL_* cells to Quartus cells.
                                run("techmap -map +/intel_alm/common/quartus_rename.v");
                                run(stringf("techmap -map +/intel_alm/%s/quartus_rename.v", family_opt.c_str()));
                        }
diff --git a/tests/arch/intel_alm/quartus_ice.ys b/tests/arch/intel_alm/quartus_ice.ys
new file mode 100644 (file)
index 0000000..4b9b54d
--- /dev/null
@@ -0,0 +1,12 @@
+read_verilog <<EOT
+// Verilog has syntax for raw identifiers, where you start it with \ and end it with a space.
+// This test crashes Quartus due to it parsing \a[10] as a wire slice and not a raw identifier.
+module top();
+  (* keep *) wire [31:0] \a[10] ;
+  (* keep *) wire b;
+  assign b = \a[10] [31];
+endmodule
+EOT
+
+synth_intel_alm -family cyclonev -quartus
+select -assert-none w:*[* w:*]*