Use BB instance for bidirectionnal IOs
[gram.git] / gram / phy / ecp5ddrphy.py
index 289c001d3a6a49b151152461fce506a4602dacca..a65f05350fc60a5a06680079ebf336ef7bf86a89 100644 (file)
@@ -95,7 +95,7 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
         self.pads = pads
         self._sys_clk_freq = sys_clk_freq
 
-        databits = len(self.pads.dq.o)
+        databits = len(self.pads.dq.io)
         assert databits % 8 == 0
 
         # CSR
@@ -119,15 +119,15 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
 
         addressbits = len(self.pads.a.o)
         bankbits = len(self.pads.ba.o)
-        nranks = 1 if not hasattr(self.pads, "cs_n") else len(self.pads.cs_n)
-        databits = len(self.pads.dq.oe)
+        nranks = 1 if not hasattr(self.pads, "cs_n") else len(self.pads.cs_n.o)
+        databits = len(self.pads.dq.io)
         self.dfi = Interface(addressbits, bankbits, nranks, 4*databits, 4)
 
         # PHY settings -----------------------------------------------------------------------------
         tck = 2/(2*2*self._sys_clk_freq)
         nphases = 2
-        databits = len(self.pads.dq.oe)
-        nranks = 1 if not hasattr(self.pads, "cs_n") else len(self.pads.cs_n)
+        databits = len(self.pads.dq.io)
+        nranks = 1 if not hasattr(self.pads, "cs_n") else len(self.pads.cs_n.o)
         addressbits = len(self.pads.a.o)
         bankbits = len(self.pads.ba.o)
         cl, cwl = get_cl_cw("DDR3", tck)
@@ -159,13 +159,13 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
 
         tck = 2/(2*2*self._sys_clk_freq)
         nphases = 2
-        databits = len(self.pads.dq.oe)
-        nranks = 1 if not hasattr(self.pads, "cs_n") else len(self.pads.cs_n)
+        databits = len(self.pads.dq.io)
+        nranks = 1 if not hasattr(self.pads, "cs_n") else len(self.pads.cs_n.o)
         addressbits = len(self.pads.a.o)
         bankbits = len(self.pads.ba.o)
 
         # Init -------------------------------------------------------------------------------------
-        m.submodules.init = DomainRenamer("init")(ECP5DDRPHYInit("sync2x"))
+        m.submodules.init = init = DomainRenamer("init")(ECP5DDRPHYInit("sync2x"))
 
         # Parameters -------------------------------------------------------------------------------
         cl, cwl = get_cl_cw("DDR3", tck)
@@ -233,7 +233,7 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
                                          i_D1=getattr(dfi.phases[0], name)[i],
                                          i_D2=getattr(dfi.phases[1], name)[i],
                                          i_D3=getattr(dfi.phases[1], name)[i],
-                                         o_Q=getattr(self.pads, name)[i]
+                                         o_Q=getattr(self.pads, name).o[i]
                                          )
 
         # DQ ---------------------------------------------------------------------------------------
@@ -250,25 +250,25 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
             rdpntr = Signal(3)
             wrpntr = Signal(3)
             rdly = Signal(7)
-            with m.If(self._dly_sel.storage[i]):
-                with m.If(self._rdly_dq_rst.re):
+            with m.If(self._dly_sel.w_data[i]):
+                with m.If(self._rdly_dq_rst.w_stb):
                     m.d.sync += rdly.eq(0)
-                with m.Elif(self._rdly_dq_inc.re):
+                with m.Elif(self._rdly_dq_inc.w_stb):
                     m.d.sync += rdly.eq(rdly + 1)
             datavalid = Signal()
             burstdet = Signal()
             dqs_read = Signal()
             dqs_bitslip = Signal(2)
-            with m.If(self._dly_sel.storage[i]):
-                with m.If(self._rdly_dq_bitslip_rst.re):
+            with m.If(self._dly_sel.w_data[i]):
+                with m.If(self._rdly_dq_bitslip_rst.w_stb):
                     m.d.sync += dqs_bitslip.eq(0)
-                with m.Elif(self._rdly_dq_bitslip.re):
+                with m.Elif(self._rdly_dq_bitslip.w_stb):
                     m.d.sync += dqs_bitslip.eq(dqs_bitslip + 1)
-            dqs_cases = {}
-            for j, b in enumerate(range(-2, 2)):
-                dqs_cases[j] = dqs_read.eq(
-                    rddata_en[cl_sys_latency + b:cl_sys_latency + b + 2] != 0)
-            m.d.sync += Case(dqs_bitslip, dqs_cases)
+            with m.Switch(dqs_bitslip):
+                for j, b in enumerate(range(-2, 2)):
+                    with m.Case(j):
+                        m.d.sync += dqs_read.eq(rddata_en[cl_sys_latency + b:cl_sys_latency + b + 2] != 0)
+
             m.submodules += Instance("DQSBUFM",
                                      p_DQS_LI_DEL_ADJ="MINUS",
                                      p_DQS_LI_DEL_VAL=1,
@@ -278,8 +278,8 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
                                      i_SCLK=ClockSignal("sync"),
                                      i_ECLK=ClockSignal("sync2x"),
                                      i_RST=ResetSignal("sync2x"),
-                                     i_DDRDEL=self.init.delay,
-                                     i_PAUSE=self.init.pause | self._dly_sel.storage[i],
+                                     i_DDRDEL=init.delay,
+                                     i_PAUSE=init.pause | self._dly_sel.w_data[i],
 
                                      # Control
                                      # Assert LOADNs to use DDRDEL control
@@ -313,10 +313,10 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
                                      )
             burstdet_d = Signal()
             m.d.sync += burstdet_d.eq(burstdet)
-            with m.If(self._burstdet_clr.re):
-                m.d.sync += self._burstdet_seen.status[i].eq(0)
+            with m.If(self._burstdet_clr.w_stb):
+                m.d.sync += self._burstdet_seen.r_data[i].eq(0)
             with m.If(burstdet & ~burstdet_d):
-                m.d.sync += self._burstdet_seen.status[i].eq(1)
+                m.d.sync += self._burstdet_seen.r_data[i].eq(1)
 
             # DQS and DM ---------------------------------------------------------------------------
             dm_o_data = Signal(8)
@@ -334,10 +334,11 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
                 dfi.phases[1].wrdata_mask[3*databits//8+i]),
             )
             m.d.sync += dm_o_data_d.eq(dm_o_data)
-            dm_bl8_cases = {}
-            dm_bl8_cases[0] = dm_o_data_muxed.eq(dm_o_data[:4])
-            dm_bl8_cases[1] = dm_o_data_muxed.eq(dm_o_data_d[4:])
-            m.d.sync += Case(bl8_chunk, dm_bl8_cases)  # FIXME: use self.comb?
+            with m.Switch(bl8_chunk):
+                with m.Case(0):
+                    m.d.sync += dm_o_data_muxed.eq(dm_o_data[:4])
+                with m.Case(1):
+                    m.d.sync += dm_o_data_muxed.eq(dm_o_data_d[4:])
             m.submodules += Instance("ODDRX2DQA",
                                      i_RST=ResetSignal("sync2x"),
                                      i_ECLK=ClockSignal("sync2x"),
@@ -347,7 +348,7 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
                                      i_D1=dm_o_data_muxed[1],
                                      i_D2=dm_o_data_muxed[2],
                                      i_D3=dm_o_data_muxed[3],
-                                     o_Q=pads.dm[i]
+                                     o_Q=self.pads.dm.o[i]
                                      )
 
             dqs = Signal()
@@ -375,7 +376,11 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
                                 dqs_pattern.postamble),
                          o_Q=dqs_oe_n
                          ),
-                Tristate(pads.dqs_p[i], dqs, ~dqs_oe_n, dqs_i)
+                Instance("BB",
+                        i_I=dqs,
+                        i_T=dqs_oe_n,
+                        o_O=dqs_i,
+                        io_B=self.pads.dqs.io[i]),
             ]
 
             for j in range(8*i, 8*(i+1)):
@@ -399,11 +404,12 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
                     dfi.phases[1].wrdata[3*databits+j])
                 )
                 m.d.sync += dq_o_data_d.eq(dq_o_data)
-                dq_bl8_cases = {}
-                dq_bl8_cases[0] = dq_o_data_muxed.eq(dq_o_data[:4])
-                dq_bl8_cases[1] = dq_o_data_muxed.eq(dq_o_data_d[4:])
                 # FIXME: use self.comb?
-                m.d.sync += Case(bl8_chunk, dq_bl8_cases)
+                with m.Switch(bl8_chunk):
+                    with m.Case(0):
+                        m.d.sync += dq_o_data_muxed.eq(dq_o_data[:4])
+                    with m.Case(1):
+                        m.d.sync += dq_o_data_muxed.eq(dq_o_data_d[4:])
                 _dq_i_data = Signal(4)
                 m.submodules += [
                     Instance("ODDRX2DQA",
@@ -467,7 +473,11 @@ class ECP5DDRPHY(Peripheral, Elaboratable):
                                     dqs_pattern.postamble),
                              o_Q=dq_oe_n,
                              ),
-                    Tristate(pads.dq[j], dq_o, ~dq_oe_n, dq_i)
+                    Instance("BB",
+                        i_I=dq_o,
+                        i_T=dq_oe_n,
+                        o_O=dq_i,
+                        io_B=self.pads.dq.io[j]),
                 ]
 
         # Read Control Path ------------------------------------------------------------------------