esp.sv 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. //
  2. // Communication interface with ESP32-S2
  3. //
  4. // This is a DIO (2-bit, including command) SPI slave interface which
  5. // allows direct access to content in SDRAM. Additionally, each
  6. // direction has three interrupt flags (3-1); the FPGA CPU additionally
  7. // has a fourth interrupt condition (0) which indicates DRAM timing
  8. // overrun/underrun.
  9. //
  10. // The SPI command byte is:
  11. // Bit [7:5] - reserved, must be 0
  12. // Bit 4 - read/write#
  13. // Bit [3:2] - clear upstream (FPGA->ESP) interrupt flag if nonzero
  14. // Bit [1:0] - set downstream (ESP->FPGA) interrupt flag if nonzero
  15. //
  16. // CPU downstream interrupts are set after the transaction completes
  17. // (CS# goes high.)
  18. //
  19. // A 32-bit address follows, and for a read, 32 dummy bits (16 cycles)
  20. // All data is processed as 32-bit words only.
  21. //
  22. module esp (
  23. input rst_n,
  24. input sys_clk,
  25. input sdram_clk,
  26. input cpu_valid,
  27. input [4:0] cpu_addr,
  28. input [3:0] cpu_wstrb,
  29. input [31:0] cpu_wdata,
  30. output [31:0] cpu_rdata,
  31. output reg irq,
  32. dram_bus.dstr dram,
  33. output reg esp_int,
  34. input spi_clk,
  35. inout [1:0] spi_io,
  36. input spi_cs_n
  37. );
  38. reg [24:2] mem_addr;
  39. reg mem_valid;
  40. reg [31:0] mem_wdata;
  41. wire mem_write;
  42. wire mem_ready;
  43. wire [31:0] mem_rdata;
  44. dram_port #(32) mem
  45. (
  46. .bus ( dram ),
  47. .prio ( 2'd2 ),
  48. .addr ( {mem_addr, 2'b00} ),
  49. .valid ( mem_valid ),
  50. .wd ( mem_wdata ),
  51. .wstrb ( {4{mem_wrq}} ),
  52. .ready ( mem_ready ),
  53. .rd ( mem_rdata )
  54. );
  55. reg [1:0] spi_clk_q;
  56. reg spi_cs_n_q;
  57. reg [1:0] spi_io_q;
  58. always @(posedge sdram_clk)
  59. begin
  60. spi_clk_q <= { spi_clk_q[0], spi_clk };
  61. spi_cs_n_q <= spi_cs_n;
  62. spi_io_q <= spi_io;
  63. end
  64. typedef enum logic [1:0] {
  65. st_cmd, // Reading command
  66. st_addr, // Reading address
  67. st_io // I/O (including read dummy bits)
  68. } state_t;
  69. state_t spi_state;
  70. reg [ 4:0] spi_cmd;
  71. reg [31:0] spi_shr;
  72. reg [ 3:0] spi_ctr;
  73. reg [ 3:0] cpu_irq;
  74. reg [ 3:1] spi_irq;
  75. reg [ 1:0] spi_out;
  76. reg spi_oe;
  77. assign spi_io = spi_oe ? spi_out : 2'bzz;
  78. assign mem_write = ~spi_cmd[4];
  79. wire [31:0] spi_indata = { spi_shr[29:0], spi_io_q };
  80. reg cpu_valid_q;
  81. always @(negedge rst_n or posedge sdram_clk)
  82. if (~rst_n)
  83. begin
  84. spi_state <= st_cmd;
  85. spi_cmd <= 'b0;
  86. spi_ctr <= 4'd3; // 8 bits needed for this state
  87. cpu_irq <= 'b0;
  88. spi_irq <= 'b0;
  89. spi_oe <= 1'b0;
  90. end
  91. else
  92. begin
  93. esp_int <= ~|spi_irq;
  94. if (spi_cs_n_q)
  95. begin
  96. spi_state <= st_cmd;
  97. spi_ctr <= 4'd3;
  98. spi_oe <= 1'b0;
  99. spi_cmd <= 'b0;
  100. for (int i = 1; i < 4; i++)
  101. if (spi_cmd[1:0] == i)
  102. cpu_irq[i] <= 1'b1;
  103. end
  104. else if (spi_clk_q == 2'b01)
  105. begin
  106. spi_ctr <= spi_ctr - 1'b1;
  107. if (|spi_ctr)
  108. begin
  109. spi_shr <= spi_indata;
  110. end
  111. else
  112. begin
  113. // Transfer data to/from memory controller, but
  114. // we have to shuffle endianness...
  115. spi_shr[31:24] <= mem_rdata[ 7: 0];
  116. spi_shr[23:16] <= mem_rdata[15: 8];
  117. spi_shr[15: 8] <= mem_rdata[23:16];
  118. spi_shr[ 7: 0] <= mem_rdata[31:24];
  119. mem_wdata[31:24] <= spi_indata[ 7: 0];
  120. mem_wdata[23:16] <= spi_indata[15: 8];
  121. mem_wdata[15: 8] <= spi_indata[23:16];
  122. mem_wdata[ 7: 0] <= spi_indata[31:24];
  123. if (mem_valid)
  124. cpu_irq[0] <= 1'b1; // Overrun/underrun
  125. case (spi_state)
  126. st_cmd: begin
  127. spi_cmd <= spi_indata[5:0];
  128. spi_state <= st_addr;
  129. for (int i = 1; i < 4; i++)
  130. if (spi_indata[3:2] == i)
  131. spi_irq[i] <= 1'b0;
  132. end
  133. st_addr: begin
  134. mem_addr <= spi_indata[25:2];
  135. spi_state <= st_io;
  136. mem_valid <= ~mem_write;
  137. end
  138. st_io: begin
  139. mem_valid <= 1'b1;
  140. end
  141. endcase
  142. end
  143. end
  144. else if (spi_clk_q == 2'b10)
  145. begin
  146. spi_out <= spi_shr[31:30];
  147. spi_oe <= (spi_state == st_io) & ~mem_write;
  148. end
  149. if (mem_valid & mem_ready)
  150. begin
  151. mem_valid <= 1'b0;
  152. mem_addr <= mem_addr + 1'b1;
  153. end
  154. cpu_valid_q <= cpu_valid;
  155. if (cpu_valid & ~cpu_valid_q & cpu_wstrb[0])
  156. case (cpu_addr[1:0])
  157. 2'b00:
  158. cpu_irq <= cpu_wdata[3:0];
  159. 2'b01:
  160. for (int i = 0; i < 4; i++)
  161. if (cpu_wdata[i])
  162. cpu_irq[i] <= 1'b0;
  163. 2'b10:
  164. spi_irq <= cpu_wdata[3:1];
  165. 2'b11:
  166. for (int i = 1; i < 4; i++)
  167. if (cpu_wdata[i])
  168. spi_irq[i] <= 1'b1;
  169. endcase // case (cpu_addr[1:0])
  170. end // else: !if(~rst_n)
  171. always @(posedge sys_clk)
  172. irq <= |cpu_irq;
  173. always @(*)
  174. casez (cpu_addr[1:0])
  175. 2'b0?:
  176. cpu_rdata = { 28'b0, cpu_irq };
  177. 2'b1?:
  178. cpu_rdata = { 28'b0, spi_irq, 1'b0 };
  179. endcase // casez (cpu_addr[1:0])
  180. endmodule // esp