Advertisement
Guest User

Untitled

a guest
Jun 20th, 2021
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.68 KB | None | 0 0
  1. class NitroUSB(Module):
  2.  
  3. def __init__(self, platform, pads, width=32, evt_fifo=False, irq=False, sync=False):
  4.  
  5. # Exposed signals
  6. self.bus = wishbone.Interface(width)
  7. self.o_irq = Signal()
  8. self.o_sof = Signal()
  9.  
  10. # Internal signals
  11. b_rdata_ep = Signal(width)
  12. b_rdata_core = Signal(width)
  13. b_cyc_ep = Signal()
  14. b_cyc_core = Signal()
  15. b_ack_ep = Signal()
  16. b_ack_core = Signal()
  17.  
  18. # Signals in the USB domains
  19. ub_addr = Signal(12)
  20. ub_rdata = Signal(16)
  21. ub_wdata = Signal(16)
  22. ub_we = Signal()
  23. ub_cyc = Signal()
  24. ub_ack = Signal()
  25.  
  26. u_irq = Signal()
  27. u_sof = Signal()
  28.  
  29. if sync:
  30. # Just wires
  31. self.comb += [
  32. # Bus
  33. ub_addr.eq(self.bus.adr[0:12]),
  34. ub_wdata.eq(self.bus.dat_w[0:16]),
  35. ub_we.eq(self.bus.we),
  36. ub_cyc.eq(b_cyc_core),
  37. b_rdata_core[0:16].eq(ub_rdata),
  38. b_ack_core.eq(ub_ack),
  39.  
  40. # Aux
  41. self.o_irq.eq(u_irq),
  42. self.o_sof.eq(u_sof),
  43. ]
  44.  
  45. else:
  46. # Cross-clock domain
  47. # Wishbone
  48. # Those are stable for some time until the handshake signal
  49. # cross the to the other domain so we can use them as-is in 'usb_48'
  50. self.comb += [
  51. ub_addr.eq(self.bus.adr[0:12]),
  52. ub_wdata.eq(self.bus.dat_w[0:16]),
  53. ub_we.eq(self.bus.we),
  54. ]
  55.  
  56. # Still need to capture during ack though but it'll be
  57. # stable long enough to be used in 'sys'
  58. self.sync.usb_48 += If(ub_ack, b_rdata_core[0:16].eq(ub_rdata))
  59.  
  60. # Handshake is more complex
  61. ps_req = PulseSynchronizer("sys", "usb_48")
  62. ps_ack = PulseSynchronizer("usb_48", "sys")
  63. self.submodules += [ ps_req, ps_ack ]
  64.  
  65. hs_cyc = Signal()
  66. hs_cyc_d = Signal()
  67. hs_ack = Signal()
  68. hs_ack_d = Signal()
  69.  
  70. self.sync.sys += [
  71. hs_cyc_d.eq(hs_cyc),
  72. hs_ack_d.eq(hs_ack),
  73. ]
  74.  
  75. self.sync.usb_48 += [
  76. ub_cyc.eq((ub_cyc | ps_req.o) & ~ub_ack),
  77. ]
  78.  
  79. self.comb += [
  80. hs_cyc.eq(b_cyc_core),
  81. ps_req.i.eq(hs_cyc & (~hs_cyc_d | hs_ack_d)),
  82. ps_ack.i.eq(ub_ack),
  83. hs_ack.eq(ps_ack.o),
  84. b_ack_core.eq(hs_ack),
  85. ]
  86.  
  87. # IRQ
  88. self.specials += MultiReg(u_irq, self.o_irq)
  89.  
  90. # SoF pulse
  91. ps_sof = PulseSynchronizer("usb_48", "sys")
  92. self.submodules += ps_sof
  93. self.comb += [
  94. ps_sof.i.eq(u_sof),
  95. self.o_sof.eq(ps_sof.o),
  96. ]
  97.  
  98. # EP interface
  99. EPAW = 11 - int(math.log2(width / 8))
  100.  
  101. ep_tx_addr_0 = Signal(EPAW)
  102. ep_tx_data_0 = Signal(width)
  103. ep_tx_we_0 = Signal()
  104. ep_rx_addr_0 = Signal(EPAW)
  105. ep_rx_data_1 = Signal(width)
  106.  
  107. self.comb += [
  108. ep_tx_addr_0.eq(self.bus.adr[0:EPAW]),
  109. ep_tx_data_0.eq(self.bus.dat_w),
  110. ep_tx_we_0.eq(b_ack_ep & self.bus.we),
  111. ep_rx_addr_0.eq(self.bus.adr[0:EPAW]),
  112. b_rdata_ep.eq(ep_rx_data_1),
  113. ]
  114.  
  115. self.sync.sys += [
  116. b_ack_ep.eq(b_cyc_ep & ~b_ack_ep),
  117. ]
  118.  
  119. # USB Core instance
  120. # Add required sources
  121. no2usb_path = '/home/tnt/projects/fpga/no2/no2usb/'
  122. platform.add_verilog_include_path(os.path.join(no2usb_path, 'rtl'))
  123. platform.add_sources(os.path.join(no2usb_path, 'rtl'),
  124. "usb_crc.v",
  125. "usb_ep_buf.v",
  126. "usb_ep_status.v",
  127. "usb_phy.v",
  128. "usb_rx_ll.v",
  129. "usb_rx_pkt.v",
  130. "usb_trans.v",
  131. "usb_tx_ll.v",
  132. "usb_tx_pkt.v",
  133. "usb.v",
  134. )
  135.  
  136. # Instanciate
  137. self.specials += Instance("usb",
  138. p_EPDW = width,
  139. p_EVT_DEPTH = 4 if (evt_fifo is True) else 0,
  140. p_IRQ = int(irq),
  141. io_pad_dp = pads.d_p,
  142. io_pad_dn = pads.d_n,
  143. o_pad_pu = pads.pullup,
  144. i_ep_tx_addr_0 = ep_tx_addr_0,
  145. i_ep_tx_data_0 = ep_tx_data_0,
  146. i_ep_tx_we_0 = ep_tx_we_0,
  147. i_ep_rx_addr_0 = ep_rx_addr_0,
  148. o_ep_rx_data_1 = ep_rx_data_1,
  149. i_ep_rx_re_0 = b_cyc_ep,
  150. i_ep_clk = ClockSignal("sys"),
  151. i_wb_addr = ub_addr,
  152. o_wb_rdata = ub_rdata,
  153. i_wb_wdata = ub_wdata,
  154. i_wb_we = ub_we,
  155. i_wb_cyc = ub_cyc,
  156. o_wb_ack = ub_ack,
  157. o_irq = u_irq,
  158. o_sof = u_sof,
  159. i_clk = ClockSignal("sys" if sync else "usb_48"),
  160. i_rst = ResetSignal("sys" if sync else "usb_48"),
  161. )
  162.  
  163. # Bus muxing
  164. self.comb += [
  165. b_cyc_ep.eq(self.bus.cyc & self.bus.stb & self.bus.adr[13]),
  166. b_cyc_core.eq(self.bus.cyc & self.bus.stb & ~self.bus.adr[13]),
  167. self.bus.ack.eq(b_ack_core | b_ack_ep),
  168. self.bus.dat_r.eq(Mux(b_ack_ep, b_rdata_ep, b_rdata_core)),
  169. ]
  170.  
  171. if width > 16:
  172. self.comb += b_rdata_core[16:width].eq(0)
  173.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement