usb_trans.v 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. /*
  2. * usb_trans.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * Copyright (C) 2019 Sylvain Munaut
  7. * All rights reserved.
  8. *
  9. * LGPL v3+, see LICENSE.lgpl3
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation; either
  14. * version 3 of the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public License
  22. * along with this program; if not, write to the Free Software Foundation,
  23. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  24. */
  25. `default_nettype none
  26. module usb_trans (
  27. // TX Packet interface
  28. output wire txpkt_start,
  29. input wire txpkt_done,
  30. output reg [3:0] txpkt_pid,
  31. output wire [9:0] txpkt_len,
  32. output wire [7:0] txpkt_data,
  33. input wire txpkt_data_ack,
  34. // RX Packet interface
  35. input wire rxpkt_start,
  36. input wire rxpkt_done_ok,
  37. input wire rxpkt_done_err,
  38. input wire [ 3:0] rxpkt_pid,
  39. input wire rxpkt_is_sof,
  40. input wire rxpkt_is_token,
  41. input wire rxpkt_is_data,
  42. input wire rxpkt_is_handshake,
  43. input wire [10:0] rxpkt_frameno,
  44. input wire [ 6:0] rxpkt_addr,
  45. input wire [ 3:0] rxpkt_endp,
  46. input wire [ 7:0] rxpkt_data,
  47. input wire rxpkt_data_stb,
  48. // EP Data Buffers
  49. output wire [10:0] buf_tx_addr_0,
  50. input wire [ 7:0] buf_tx_data_1,
  51. output wire buf_tx_rden_0,
  52. output wire [10:0] buf_rx_addr_0,
  53. output wire [ 7:0] buf_rx_data_0,
  54. output wire buf_rx_wren_0,
  55. // EP Status RAM
  56. output wire eps_read_0,
  57. output wire eps_zero_0,
  58. output wire eps_write_0,
  59. output wire [ 7:0] eps_addr_0,
  60. output wire [15:0] eps_wrdata_0,
  61. input wire [15:0] eps_rddata_3,
  62. // Config
  63. input wire [ 6:0] cr_addr,
  64. output wire [15:0] sr_notify,
  65. output reg irq_stb,
  66. output wire irq_state,
  67. input wire irq_ack,
  68. output wire cel_state,
  69. input wire cel_rel,
  70. input wire cel_ena,
  71. // Common
  72. input wire clk,
  73. input wire rst
  74. );
  75. `include "usb_defs.vh"
  76. // Signals
  77. // -------
  78. // Micro-Code
  79. reg [ 3:0] mc_a_reg;
  80. reg mc_rst_n;
  81. (* keep="true" *) wire [ 3:0] mc_match_bits;
  82. wire mc_match;
  83. wire mc_jmp;
  84. wire [ 7:0] mc_pc;
  85. reg [ 7:0] mc_pc_nxt;
  86. wire [15:0] mc_opcode;
  87. (* keep="true" *) wire mc_op_ld;
  88. (* keep="true" *) wire mc_op_ep;
  89. (* keep="true" *) wire mc_op_zlen;
  90. (* keep="true" *) wire mc_op_tx;
  91. (* keep="true" *) wire mc_op_notify;
  92. (* keep="true" *) wire mc_op_evt_clr;
  93. (* keep="true" *) wire mc_op_evt_rto;
  94. // Events
  95. wire [3:0] evt_rst;
  96. wire [3:0] evt_set;
  97. reg [3:0] evt;
  98. wire rto_now;
  99. reg [9:0] rto_cnt;
  100. // Host notify
  101. reg irq_state_i;
  102. reg [3:0] irq_cnt;
  103. reg [10:0] sr_notify_i;
  104. // Transaction / EndPoint / Buffer infos
  105. reg [3:0] trans_pid;
  106. reg trans_is_setup;
  107. reg trans_addr_zero;
  108. reg trans_addr_match;
  109. reg [3:0] trans_endp;
  110. reg trans_dir;
  111. reg [2:0] ep_type;
  112. reg ep_bd_dual;
  113. reg ep_bd_ctrl;
  114. reg ep_bd_idx_cur;
  115. reg ep_bd_idx_nxt;
  116. reg ep_data_toggle;
  117. reg [2:0] bd_state;
  118. // EP & BD Infos fetch/writeback
  119. localparam
  120. EPFW_IDLE = 4'b0000,
  121. EPFW_RD_STATUS = 4'b0100,
  122. EPFW_RD_BD_W0 = 4'b0110,
  123. EPFW_RD_BD_W1 = 4'b0111,
  124. EPFW_WR_STATUS = 4'b1000,
  125. EPFW_WR_BD_W0 = 4'b1010;
  126. reg [3:0] epfw_state;
  127. reg [5:0] epfw_cap_dl;
  128. reg epfw_issue_wb;
  129. // Control Endpoint Lockout
  130. reg cel_state_i;
  131. // Packet TX
  132. reg txpkt_start_i;
  133. // Address
  134. reg [10:0] addr;
  135. wire addr_inc;
  136. wire addr_ld;
  137. // Length
  138. reg [10:0] bd_length;
  139. reg [ 9:0] xfer_length;
  140. wire len_ld;
  141. wire len_bd_dec;
  142. wire len_xf_inc;
  143. // Micro-Code execution engine
  144. // ---------------------------
  145. // Local reset to avoid being in the critical path
  146. always @(posedge clk or posedge rst)
  147. if (rst)
  148. mc_rst_n <= 1'b0;
  149. else
  150. mc_rst_n <= 1'b1;
  151. // Conditional Jump handling
  152. assign mc_match_bits = (mc_a_reg[3:0] & mc_opcode[7:4]) ^ mc_opcode[3:0];
  153. assign mc_match = ~|mc_match_bits;
  154. assign mc_jmp = mc_opcode[15] & mc_rst_n & (mc_match ^ mc_opcode[14]);
  155. assign mc_pc = mc_jmp ? {mc_opcode[13:8], 2'b00} : mc_pc_nxt;
  156. // Program counter
  157. always @(posedge clk or posedge rst)
  158. if (rst)
  159. mc_pc_nxt <= 8'h00;
  160. else
  161. mc_pc_nxt <= mc_pc + 1;
  162. // Microcode ROM
  163. SB_RAM40_4K #(
  164. .INIT_FILE("usb_trans_mc.hex"),
  165. .WRITE_MODE(0),
  166. .READ_MODE(0)
  167. ) mc_rom_I (
  168. .RDATA(mc_opcode),
  169. .RADDR({3'b000, mc_pc}),
  170. .RCLK(clk),
  171. .RCLKE(1'b1),
  172. .RE(1'b1),
  173. .WDATA(16'h0000),
  174. .WADDR(11'h000),
  175. .MASK(16'h0000),
  176. .WCLK(1'b0),
  177. .WCLKE(1'b0),
  178. .WE(1'b0)
  179. );
  180. // Decode opcodes
  181. assign mc_op_ld = mc_opcode[15:12] == 4'b0001;
  182. assign mc_op_ep = mc_opcode[15:12] == 4'b0010;
  183. assign mc_op_zlen = mc_opcode[15:12] == 4'b0011;
  184. assign mc_op_tx = mc_opcode[15:12] == 4'b0100;
  185. assign mc_op_notify = mc_opcode[15:12] == 4'b0101;
  186. assign mc_op_evt_clr = mc_opcode[15:12] == 4'b0110;
  187. assign mc_op_evt_rto = mc_opcode[15:12] == 4'b0111;
  188. // A-register
  189. always @(posedge clk)
  190. if (mc_op_ld)
  191. casez (mc_opcode[2:1])
  192. 2'b00: mc_a_reg <= evt;
  193. 2'b01: mc_a_reg <= rxpkt_pid ^ { ep_data_toggle & mc_opcode[0], 3'b000 };
  194. 2'b10: mc_a_reg <= { cel_state_i, ep_type };
  195. 2'b11: mc_a_reg <= { 1'b0, bd_state };
  196. default: mc_a_reg <= 4'hx;
  197. endcase
  198. // Events
  199. // ------
  200. // Latch events
  201. always @(posedge clk or posedge rst)
  202. if (rst)
  203. evt <= 4'h0;
  204. else
  205. evt <= (evt & ~evt_rst) | evt_set;
  206. assign evt_rst = {4{mc_op_evt_clr}} & mc_opcode[3:0];
  207. assign evt_set = { rto_now, txpkt_done, rxpkt_done_err, rxpkt_done_ok };
  208. // RX Timeout counter
  209. always @(posedge clk or posedge rst)
  210. if (rst)
  211. rto_cnt <= 0;
  212. else
  213. if (mc_op_evt_rto)
  214. rto_cnt <= { 2'b01, mc_opcode[7:0] };
  215. else
  216. rto_cnt <= {
  217. rto_cnt[9] & rto_cnt[8] & ~rxpkt_start,
  218. rto_cnt[8:0] - rto_cnt[9]
  219. };
  220. assign rto_now = rto_cnt[9] & ~rto_cnt[8];
  221. // Host NOTIFY
  222. // -----------
  223. always @(posedge clk)
  224. if (mc_op_notify)
  225. sr_notify_i <= {
  226. mc_opcode[3:0], // Micro-code return value
  227. trans_endp, // Endpoint #
  228. trans_dir, // Direction
  229. trans_is_setup,
  230. ep_bd_idx_cur // BD where it happenned
  231. };
  232. assign sr_notify = {
  233. irq_cnt,
  234. sr_notify_i,
  235. irq_state
  236. };
  237. always @(posedge clk)
  238. begin
  239. irq_stb <= mc_op_notify;
  240. irq_cnt <= irq_cnt + mc_op_notify;
  241. irq_state_i <= (irq_state_i & ~irq_ack) | mc_op_notify;
  242. end
  243. assign irq_state = irq_state_i;
  244. // EP infos
  245. // --------
  246. // Capture EP# and direction when we get a TOKEN packet
  247. always @(posedge clk)
  248. if (rxpkt_done_ok & rxpkt_is_token) begin
  249. trans_pid <= rxpkt_pid;
  250. trans_is_setup <= rxpkt_pid == PID_SETUP;
  251. trans_addr_zero <= rxpkt_addr == 6'h00;
  252. trans_addr_match <= rxpkt_addr == cr_addr;
  253. trans_endp <= rxpkt_endp;
  254. trans_dir <= rxpkt_pid == PID_IN;
  255. end
  256. // EP Status Fetch/WriteBack (epfw)
  257. // State
  258. always @(posedge clk or posedge rst)
  259. if (rst)
  260. epfw_state <= EPFW_IDLE;
  261. else
  262. case (epfw_state)
  263. EPFW_IDLE:
  264. if (epfw_issue_wb)
  265. epfw_state <= EPFW_WR_STATUS;
  266. else if (rxpkt_done_ok & rxpkt_is_token)
  267. epfw_state <= EPFW_RD_STATUS;
  268. else if (epfw_cap_dl[1:0] == 2'b01)
  269. epfw_state <= EPFW_RD_BD_W0;
  270. else
  271. epfw_state <= EPFW_IDLE;
  272. EPFW_RD_STATUS:
  273. epfw_state <= EPFW_IDLE;
  274. EPFW_RD_BD_W0:
  275. epfw_state <= EPFW_RD_BD_W1;
  276. EPFW_RD_BD_W1:
  277. epfw_state <= EPFW_IDLE;
  278. EPFW_WR_STATUS:
  279. epfw_state <= EPFW_WR_BD_W0;
  280. EPFW_WR_BD_W0:
  281. epfw_state <= EPFW_IDLE;
  282. default:
  283. epfw_state <= EPFW_IDLE;
  284. endcase
  285. // Issue command to RAM
  286. assign eps_zero_0 = 1'b0;
  287. assign eps_read_0 = epfw_state[2];
  288. assign eps_write_0 = epfw_state[3];
  289. assign eps_addr_0 = {
  290. trans_endp,
  291. trans_dir,
  292. epfw_state[1],
  293. epfw_state[1] & ep_bd_idx_cur,
  294. epfw_state[0]
  295. };
  296. assign eps_wrdata_0 = epfw_state[1] ?
  297. { bd_state, trans_is_setup, 2'b00, xfer_length[9:0] } :
  298. { 8'h00, ep_data_toggle, ep_bd_idx_nxt, ep_bd_ctrl, ep_bd_dual, 1'b0, ep_type };
  299. // Delay line for what to expect on read data
  300. always @(posedge clk or posedge rst)
  301. if (rst)
  302. epfw_cap_dl = 6'b000000;
  303. else
  304. epfw_cap_dl <= {
  305. epfw_state[1],
  306. epfw_state[2] & ~^epfw_state[1:0],
  307. epfw_cap_dl[5:2]
  308. };
  309. // Capture read data
  310. always @(posedge clk)
  311. begin
  312. // EP Status
  313. if (epfw_cap_dl[1:0] == 2'b01) begin
  314. ep_type <= eps_rddata_3[2:0];
  315. ep_bd_dual <= eps_rddata_3[4];
  316. ep_bd_ctrl <= eps_rddata_3[5];
  317. ep_bd_idx_cur <= eps_rddata_3[5] ? trans_is_setup : eps_rddata_3[6];
  318. ep_bd_idx_nxt <= eps_rddata_3[6];
  319. ep_data_toggle <= eps_rddata_3[7] & ~trans_is_setup; /* For SETUP, DT == 0 */
  320. end else begin
  321. ep_data_toggle <= ep_data_toggle ^ (mc_op_ep & mc_opcode[0]);
  322. ep_bd_idx_nxt <= ep_bd_idx_nxt ^ (mc_op_ep & mc_opcode[1] & ep_bd_dual );
  323. end
  324. // BD Word 0
  325. if (epfw_cap_dl[1:0] == 2'b10) begin
  326. bd_state <= eps_rddata_3[15:13];
  327. end else begin
  328. bd_state <= (mc_op_ep & mc_opcode[2]) ? mc_opcode[5:3]: bd_state;
  329. end
  330. end
  331. // When do to write backs
  332. always @(posedge clk)
  333. epfw_issue_wb <= mc_op_ep & mc_opcode[7];
  334. // Control Endpoint Lockout
  335. // ------------------------
  336. always @(posedge clk or posedge rst)
  337. if (rst)
  338. cel_state_i <= 1'b0;
  339. else
  340. cel_state_i <= cel_ena & ((cel_state_i & ~cel_rel) | (mc_op_ep & mc_opcode[8]));
  341. assign cel_state = cel_state_i;
  342. // Packet TX
  343. // ---------
  344. always @(posedge clk)
  345. if (mc_op_tx)
  346. txpkt_pid <= mc_opcode[3:0] ^ { mc_opcode[4] & ep_data_toggle, 3'b000 };
  347. always @(posedge clk)
  348. txpkt_start_i <= mc_op_tx;
  349. assign txpkt_start = txpkt_start_i;
  350. assign txpkt_len = bd_length[9:0];
  351. // Data Address/Length shared logic
  352. // --------------------------------
  353. // Address
  354. always @(posedge clk)
  355. addr <= addr_ld ? eps_rddata_3[10:0] : (addr + addr_inc);
  356. assign addr_ld = epfw_cap_dl[1:0] == 2'b11;
  357. assign addr_inc = txpkt_data_ack | txpkt_start_i | rxpkt_data_stb;
  358. // Buffer length (decrements)
  359. always @(posedge clk)
  360. if (mc_op_zlen)
  361. bd_length <= 0;
  362. else
  363. bd_length <= len_ld ? { 1'b1, eps_rddata_3[9:0] } : (bd_length - len_bd_dec);
  364. // Xfer length (increments)
  365. always @(posedge clk)
  366. xfer_length <= len_ld ? 10'h000 : (xfer_length + len_xf_inc);
  367. // Length control
  368. assign len_ld = epfw_cap_dl[1:0] == 2'b10;
  369. assign len_bd_dec = (rxpkt_data_stb | rxpkt_start) & bd_length[10];
  370. assign len_xf_inc = rxpkt_data_stb;
  371. // Data read logic
  372. // ---------------
  373. assign buf_tx_addr_0 = addr;
  374. assign buf_tx_rden_0 = txpkt_data_ack | txpkt_start_i;
  375. assign txpkt_data = buf_tx_data_1;
  376. // Data write logic
  377. // ----------------
  378. assign buf_rx_addr_0 = addr;
  379. assign buf_rx_data_0 = rxpkt_data;
  380. assign buf_rx_wren_0 = rxpkt_data_stb & bd_length[10];
  381. endmodule // usb_trans