spi_fast.v 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * spi_fast.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * Copyright (C) 2019 Sylvain Munaut <tnt@246tNt.com>
  7. * All rights reserved.
  8. *
  9. * BSD 3-clause, see LICENSE.bsd
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are met:
  13. * * Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * * Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * * Neither the name of the <organization> nor the
  19. * names of its contributors may be used to endorse or promote products
  20. * derived from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  25. * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  26. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  29. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. `default_nettype none
  34. module spi_fast (
  35. // SPI pads
  36. input wire spi_mosi,
  37. output wire spi_miso,
  38. input wire spi_cs_n,
  39. input wire spi_clk,
  40. // Interface
  41. output reg [7:0] addr,
  42. output reg [7:0] data,
  43. output wire first,
  44. output wire last,
  45. output reg strobe,
  46. input wire [7:0] out,
  47. // Clock / Reset
  48. input wire clk,
  49. input wire rst
  50. );
  51. // Signals
  52. // -------
  53. // Core IF
  54. wire [7:0] core_out_data;
  55. wire core_out_stb;
  56. wire core_out_prestb;
  57. wire [7:0] core_in_data;
  58. wire core_in_ack;
  59. wire csn_state;
  60. wire csn_rise;
  61. wire csn_fall;
  62. // "Simple Bus"
  63. reg rx_first;
  64. reg rx_second;
  65. reg rx_third;
  66. reg tx_first;
  67. wire addr_ce;
  68. reg first_i;
  69. reg last_i;
  70. // Core
  71. // ----
  72. spi_fast_core core_I (
  73. .spi_miso(spi_miso),
  74. .spi_mosi(spi_mosi),
  75. .spi_clk(spi_clk),
  76. .spi_cs_n(spi_cs_n),
  77. .user_out(core_out_data),
  78. .user_out_stb(core_out_stb),
  79. .user_out_prestb(core_out_prestb),
  80. .user_in(core_in_data),
  81. .user_in_ack(core_in_ack),
  82. .csn_state(csn_state),
  83. .csn_rise(csn_rise),
  84. .csn_fall(csn_fall),
  85. .clk(clk),
  86. .rst(rst)
  87. );
  88. // Interface to "Simple Bus"
  89. // -------------------------
  90. // Track state
  91. always @(posedge clk)
  92. tx_first <= (tx_first | csn_state) & ~core_in_ack;
  93. always @(posedge clk)
  94. begin
  95. rx_first <= (rx_first | csn_state) & ~core_out_stb;
  96. rx_second <= (rx_second & ~core_out_stb & ~csn_state) | (rx_first & core_out_stb);
  97. rx_third <= (rx_third & ~core_out_stb & ~csn_state) | (rx_second & core_out_stb);
  98. end
  99. // Status sent as first word
  100. assign core_in_data = tx_first ? out : 8'h00;
  101. // Address register
  102. always @(posedge clk)
  103. if (addr_ce)
  104. addr <= core_out_data;
  105. assign addr_ce = core_out_stb & rx_first;
  106. // Data register
  107. // (this is needed because we need to be able to hold the data until
  108. // we know if it's the last or not ...)
  109. always @(posedge clk)
  110. if (core_out_prestb | csn_rise)
  111. data <= core_out_data;
  112. // External strobes
  113. always @(posedge clk)
  114. begin
  115. first_i <= (first_i & ~core_out_stb & ~csn_rise) | rx_third;
  116. last_i <= (last_i & ~core_out_stb) | csn_rise;
  117. strobe <= csn_rise | (core_out_stb & ~rx_first & ~rx_second);
  118. end
  119. assign first = first_i;
  120. assign last = last_i;
  121. endmodule // spi_fast