usb_tx_tb.v 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * usb_tx_tb.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. `timescale 1ns/100ps
  27. module usb_tx_tb;
  28. // Signals
  29. reg rst = 1;
  30. reg clk_48m = 0; // USB clock
  31. wire phy_tx_dp;
  32. wire phy_tx_dn;
  33. wire phy_tx_en;
  34. wire ll_start;
  35. wire ll_bit;
  36. wire ll_last;
  37. wire ll_ack;
  38. wire pkt_start;
  39. wire pkt_done;
  40. wire [3:0] pkt_pid;
  41. wire [9:0] pkt_len;
  42. reg [7:0] pkt_data;
  43. wire pkt_data_ack;
  44. // Setup recording
  45. initial begin
  46. $dumpfile("usb_tx_tb.vcd");
  47. $dumpvars(0,usb_tx_tb);
  48. end
  49. // Reset pulse
  50. initial begin
  51. # 200 rst = 0;
  52. # 1000000 $finish;
  53. end
  54. // Clocks
  55. always #10.416 clk_48m = !clk_48m;
  56. // DUT
  57. usb_tx_ll tx_ll_I (
  58. .phy_tx_dp(phy_tx_dp),
  59. .phy_tx_dn(phy_tx_dn),
  60. .phy_tx_en(phy_tx_en),
  61. .ll_start(ll_start),
  62. .ll_bit(ll_bit),
  63. .ll_last(ll_last),
  64. .ll_ack(ll_ack),
  65. .clk(clk_48m),
  66. .rst(rst)
  67. );
  68. usb_tx_pkt tx_pkt_I (
  69. .ll_start(ll_start),
  70. .ll_bit(ll_bit),
  71. .ll_last(ll_last),
  72. .ll_ack(ll_ack),
  73. .pkt_start(pkt_start),
  74. .pkt_done(pkt_done),
  75. .pkt_pid(pkt_pid),
  76. .pkt_len(pkt_len),
  77. .pkt_data(pkt_data),
  78. .pkt_data_ack(pkt_data_ack),
  79. .clk(clk_48m),
  80. .rst(rst)
  81. );
  82. // Start signal
  83. reg [7:0] cnt;
  84. reg ready;
  85. always @(posedge clk_48m)
  86. if (rst)
  87. ready <= 1'b1;
  88. else
  89. if (pkt_start)
  90. ready <= 1'b0;
  91. else if (pkt_done)
  92. ready <= 1'b1;
  93. always @(posedge clk_48m)
  94. if (rst)
  95. cnt <= 0;
  96. else
  97. cnt <= cnt + 1;
  98. assign pkt_start = (cnt == 8'hff) & ready;
  99. // Packet
  100. assign pkt_len = 10'h000; // 16 bytes payload
  101. // assign pkt_pid = 4'b0011; // DATA0
  102. assign pkt_pid = 4'b0010; // ACK
  103. // Fake data source
  104. always @(posedge clk_48m)
  105. if (rst)
  106. pkt_data <= 8'h5a;
  107. else
  108. pkt_data <= pkt_data + pkt_data_ack;
  109. `ifdef NO_PKT
  110. wire [31:0] bit_seq = 32'b00000001_10100101_11111111_11100000;
  111. reg [7:0] cnt;
  112. reg started;
  113. always @(posedge clk_48m)
  114. if (rst)
  115. cnt <= 0;
  116. else if (ll_ack | ~started)
  117. cnt <= cnt + 1;
  118. always @(posedge clk_48m)
  119. if (rst)
  120. started <= 1'b0;
  121. else
  122. if (ll_start)
  123. started <= 1'b1;
  124. else if (ll_last & ll_ack)
  125. started <= 1'b0;
  126. assign ll_start = (cnt == 8'h1f);
  127. assign ll_bit = bit_seq[31 - cnt[4:0]];
  128. assign ll_last = cnt[4:0] == 31;
  129. `endif
  130. endmodule // usb_tx_tb