hdl.mem: remove WritePort(priority=) argument.
authorwhitequark <whitequark@whitequark.org>
Sat, 28 Sep 2019 01:29:56 +0000 (01:29 +0000)
committerwhitequark <whitequark@whitequark.org>
Sat, 28 Sep 2019 01:29:56 +0000 (01:29 +0000)
The write port priority in Yosys is derived directly from the order
in which the ports are declared in the Verilog frontend. It is being
removed for several reasons:
  1. It is not clear if it works correctly for all cases (FFRAM,
     LUTRAM, BRAM).
  2. Although it is roundtripped via Verilog with correct simulation
     semantics, the resulting code has a high chance of being
     interpreted incorrectly by Xilinx tools.
  3. It cannot be roundtripped via FIRRTL, which is an alternative
     backend that is an interesting future option. (FIRRTL leaves
     write collision completely undefined.)
  3. It is a niche feature that, if it is needed, can be completely
     replaced using an explicit comparator, priority encoder, and
     write enable gating circuit. (This is what Xilinx recommends
     for handling this case.)

In the future we should extend nMigen's formal verification to assert
that a write collision does not happen.

nmigen/hdl/mem.py
nmigen/test/test_hdl_mem.py

index 47a4386b353b03d7230b2bf3e1c253ce5f6b123e..38ec383a82810afb64530f35c718360b7e723f00 100644 (file)
@@ -132,7 +132,7 @@ class ReadPort(Elaboratable):
 
 
 class WritePort(Elaboratable):
-    def __init__(self, memory, *, domain="sync", priority=0, granularity=None):
+    def __init__(self, memory, *, domain="sync", granularity=None):
         if granularity is None:
             granularity = memory.width
         if not isinstance(granularity, int) or granularity < 0:
@@ -147,7 +147,6 @@ class WritePort(Elaboratable):
 
         self.memory       = memory
         self.domain       = domain
-        self.priority     = priority
         self.granularity  = granularity
 
         self.addr = Signal.range(memory.depth,
@@ -164,7 +163,7 @@ class WritePort(Elaboratable):
             p_WIDTH=self.data.width,
             p_CLK_ENABLE=1,
             p_CLK_POLARITY=1,
-            p_PRIORITY=self.priority,
+            p_PRIORITY=0,
             i_CLK=ClockSignal(self.domain),
             i_EN=Cat(Repl(en_bit, self.granularity) for en_bit in self.en),
             i_ADDR=self.addr,
index 2e1ade5b155c48ad1bc04f90a39327e0d23c1ec4..8e6dac9d4389a16dc0cf1456b30ba23c3d8ac7ff 100644 (file)
@@ -83,7 +83,6 @@ class MemoryTestCase(FHDLTestCase):
         wrport = mem.write_port()
         self.assertEqual(wrport.memory, mem)
         self.assertEqual(wrport.domain, "sync")
-        self.assertEqual(wrport.priority, 0)
         self.assertEqual(wrport.granularity, 8)
         self.assertEqual(len(wrport.addr), 2)
         self.assertEqual(len(wrport.data), 8)
@@ -94,7 +93,6 @@ class MemoryTestCase(FHDLTestCase):
         wrport = mem.write_port(granularity=2)
         self.assertEqual(wrport.memory, mem)
         self.assertEqual(wrport.domain, "sync")
-        self.assertEqual(wrport.priority, 0)
         self.assertEqual(wrport.granularity, 2)
         self.assertEqual(len(wrport.addr), 2)
         self.assertEqual(len(wrport.data), 8)