2
0

esp.sv 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  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 7 interrupt condition flags (7-1); the FPGA CPU
  7. // additionally has an internal interrupt condition (0) which
  8. // indicates DRAM timing overrun/underrun, also visible in the status
  9. // word as bit 0.
  10. //
  11. // The SPI command byte is:
  12. // Bit 7 - save command timestamp
  13. // Bit 6 - read/write#
  14. // Bit [5:3] - clear upstream (FPGA->ESP) interrupt flag if nonzero
  15. // Bit [2:0] - set downstream (ESP->FPGA) interrupt flag if nonzero
  16. //
  17. // CPU downstream interrupts are set after the transaction completes
  18. // (CS# goes high.)
  19. //
  20. // A 32-bit address follows; for a read, the following 16 cycles
  21. // contains dummy/status data:
  22. //
  23. // Bit [31:16] = 16 LSB of 32 kHz RTC counter
  24. // Bit [15: 9] = upstream interrupts pending
  25. // Bit 8 = downstream writes enabled
  26. // Bit [ 7: 1] = downstream interrupts pending
  27. // Bit 0 = underrun error
  28. //
  29. // The following CPU registers are defined:
  30. //
  31. // 0 = status bits [7:0] (downstream)
  32. // 1 = write-1-clear of status bits [7:0]
  33. // 2 = status bits [15:8] (upstream)
  34. // 3 = write-1-set of status bits [15:8]
  35. // 4 = timestamp (16 LSB of 32 kHz RTC counter) saved by cmd bit 7
  36. //
  37. module esp #(
  38. parameter dram_bits = 25,
  39. parameter [31:0] dram_base = 32'h40000000
  40. ) (
  41. input rst_n,
  42. input sys_clk,
  43. input sdram_clk,
  44. input cpu_valid,
  45. input [4:0] cpu_addr,
  46. input [3:0] cpu_wstrb,
  47. input [31:0] cpu_wdata,
  48. output [31:0] cpu_rdata,
  49. output reg irq,
  50. dram_bus.dstr dram,
  51. output reg esp_int,
  52. input spi_clk,
  53. inout [1:0] spi_io,
  54. input spi_cs_n,
  55. input [15:0] rtc_ctr
  56. );
  57. reg [31:0] mem_addr = 'b0;
  58. wire [31:0] mem_addr_mask = (1'b1 << dram_bits) - 3'd4;
  59. wire [31:0] mem_addr_out = (mem_addr & mem_addr_mask)
  60. | dram_base;
  61. reg mem_valid;
  62. reg [31:0] mem_wdata;
  63. wire mem_write;
  64. reg [ 3:0] mem_wstrb;
  65. wire mem_ready;
  66. wire [31:0] mem_rdata;
  67. dram_port #(32) mem
  68. (
  69. .bus ( dram ),
  70. .prio ( 2'd2 ),
  71. .addr ( mem_addr[dram_bits-1:0] ),
  72. .valid ( mem_valid ),
  73. .wd ( mem_wdata ),
  74. .wstrb ( mem_wstrb ),
  75. .ready ( mem_ready ),
  76. .rd ( mem_rdata )
  77. );
  78. reg [1:0] spi_clk_q;
  79. reg spi_cs_n_q;
  80. reg [1:0] spi_io_q;
  81. always @(posedge sdram_clk)
  82. begin
  83. spi_clk_q <= { spi_clk_q[0], spi_clk };
  84. spi_cs_n_q <= spi_cs_n;
  85. spi_io_q <= spi_io;
  86. end
  87. typedef enum logic [1:0] {
  88. st_dead, // Do nothing until CS# deasserted
  89. st_cmd, // Reading command
  90. st_addr, // Reading address
  91. st_io // I/O (including read dummy bits)
  92. } state_t;
  93. state_t spi_state;
  94. reg [ 7:0] spi_cmd;
  95. reg [31:0] spi_shr;
  96. reg [ 3:0] spi_ctr;
  97. reg [ 7:0] cpu_irq;
  98. reg [ 7:0] cpu_set_irq; // CPU IRQs to set once idle
  99. reg cpu_send_irq; // Ready to set CPU IRQs
  100. reg [ 7:1] spi_irq;
  101. reg [ 7:1] latched_spi_irq; // SPI IRQ as of transition start
  102. reg [15:0] timestamp_q;
  103. reg [ 1:0] spi_out;
  104. reg spi_oe;
  105. reg [ 2:0] spi_wbe; // Partial word write byte enables
  106. reg [23:0] spi_wdata; // Partial word write data
  107. reg spi_wr_en; // SPI writes enabled by CPU
  108. reg spi_mem_en; // Read, or write enabled at start of trans
  109. assign spi_io = spi_oe ? spi_out : 2'bzz;
  110. assign mem_write = ~spi_cmd[6];
  111. wire [31:0] spi_indata = { spi_shr[29:0], spi_io_q };
  112. reg cpu_valid_q;
  113. always @(negedge rst_n or posedge sdram_clk)
  114. if (~rst_n)
  115. begin
  116. spi_state <= st_dead;
  117. spi_cmd <= 'b0;
  118. spi_ctr <= 4'd3; // 8 bits needed for this state
  119. cpu_irq <= 'b0;
  120. cpu_set_irq <= 'b0;
  121. cpu_send_irq <= 1'b0;
  122. spi_irq <= 'b0;
  123. latched_spi_irq <= 'b0;
  124. spi_oe <= 1'b0;
  125. spi_wbe <= 3'b0;
  126. mem_addr <= 'b0;
  127. mem_wstrb <= 4'b0;
  128. mem_valid <= 1'b0;
  129. spi_wr_en <= 1'b0;
  130. spi_mem_en <= 1'b0;
  131. end
  132. else
  133. begin
  134. esp_int <= ~|spi_irq;
  135. if (spi_cs_n_q)
  136. begin
  137. spi_state <= st_cmd;
  138. spi_ctr <= 4'd3;
  139. spi_oe <= 1'b0;
  140. cpu_send_irq <= |cpu_set_irq;
  141. end
  142. if (cpu_send_irq & ~mem_valid & ~|spi_wbe)
  143. begin
  144. cpu_irq <= cpu_irq | cpu_set_irq;
  145. cpu_set_irq <= 'b0;
  146. cpu_send_irq <= 1'b0;
  147. end
  148. if (~spi_cs_n_q && spi_clk_q == 2'b01)
  149. begin
  150. spi_ctr <= spi_ctr - 1'b1;
  151. spi_shr <= spi_indata;
  152. case (spi_ctr)
  153. 4'b1100:
  154. if (spi_state == st_io && mem_write)
  155. begin
  156. spi_wbe[0] <= 1'b1;
  157. spi_wdata[7:0] <= spi_indata[7:0];
  158. end
  159. 4'b1000:
  160. if (spi_state == st_io && mem_write)
  161. begin
  162. spi_wbe[1] <= 1'b1;
  163. spi_wdata[15:8] <= spi_indata[7:0];
  164. end
  165. 4'b0100:
  166. if (spi_state == st_io && mem_write)
  167. begin
  168. spi_wbe[2] <= 1'b1;
  169. spi_wdata[23:16] <= spi_indata[7:0];
  170. end
  171. 4'b0000: begin
  172. // Load spi_shr, but account for endianness here...
  173. if (spi_state == st_io)
  174. spi_shr <= bswap32(mem_rdata);
  175. else
  176. // Status output
  177. spi_shr <= bswap32({
  178. rtc_ctr,
  179. latched_spi_irq, spi_wr_en,
  180. cpu_irq
  181. });
  182. if (mem_valid && spi_state != st_cmd)
  183. begin
  184. cpu_irq[0] <= 1'b1; // Overrun/underrun
  185. spi_wr_en <= 1'b0; // Block further memory writes
  186. spi_mem_en <= ~mem_write;
  187. end
  188. case (spi_state)
  189. st_dead: begin
  190. // Do nothing
  191. end
  192. st_cmd: begin
  193. spi_cmd <= spi_indata[7:0];
  194. spi_state <= st_addr;
  195. latched_spi_irq <= spi_irq;
  196. for (int i = 1; i < 8; i++)
  197. begin
  198. if (spi_indata[5:3] == i)
  199. spi_irq[i] <= 1'b0;
  200. if (spi_indata[2:0] == i)
  201. cpu_set_irq[i] <= 1'b1;
  202. end
  203. if (spi_indata[7])
  204. timestamp_q <= rtc_ctr;
  205. end
  206. st_addr: begin
  207. mem_addr <= spi_indata & mem_addr_mask;
  208. spi_state <= st_io;
  209. mem_valid <= ~mem_write;
  210. spi_mem_en <= ~mem_write | spi_wr_en;
  211. mem_wstrb <= 4'b0;
  212. spi_wbe <= 3'b000;
  213. // If the first word is partial, skip ahead
  214. if (mem_write)
  215. spi_ctr[3:2] <= ~spi_indata[1:0];
  216. end
  217. st_io: begin
  218. if (mem_write)
  219. begin
  220. mem_wdata[23: 0] <= spi_wdata[23:0];
  221. mem_wdata[31:24] <= spi_indata[7:0];
  222. mem_wstrb <= { 1'b1, spi_wbe };
  223. end
  224. else
  225. begin
  226. mem_wstrb <= 4'b0000;
  227. end // else: !if(mem_write)
  228. mem_valid <= spi_mem_en;
  229. spi_wbe <= 3'b000;
  230. end
  231. endcase
  232. end // case: 4'b0000
  233. default: begin
  234. // Do nothing
  235. end
  236. endcase // case (spi_ctr)
  237. end // if (spi_clk_q == 2'b01)
  238. else if (~spi_cs_n_q && spi_clk_q == 2'b10)
  239. begin
  240. spi_out <= spi_shr[31:30];
  241. spi_oe <= (spi_state == st_io) & ~mem_write;
  242. end
  243. if (mem_valid & mem_ready)
  244. begin
  245. mem_addr <= mem_addr + 3'd4;
  246. mem_valid <= 1'b0;
  247. end
  248. if (spi_state != st_io & ~mem_valid & |spi_wbe)
  249. begin
  250. // Complete a partial write terminated by CS#
  251. mem_valid <= spi_mem_en;
  252. mem_wstrb <= { 1'b0, spi_wbe };
  253. mem_wdata[23:0] <= spi_wdata[23:0];
  254. mem_wdata[31:24] <= 8'hxx;
  255. spi_wbe <= 3'b000;
  256. end
  257. cpu_valid_q <= cpu_valid;
  258. if (cpu_valid & ~cpu_valid_q & cpu_wstrb[0])
  259. case (cpu_addr[2:0])
  260. 3'b000:
  261. cpu_irq <= cpu_wdata[7:0];
  262. 3'b001:
  263. for (int i = 0; i < 8; i++)
  264. if (cpu_wdata[i])
  265. cpu_irq[i] <= cpu_send_irq & cpu_set_irq[i];
  266. 3'b010:
  267. { spi_irq, spi_wr_en } <= cpu_wdata[7:0];
  268. 3'b011: begin
  269. if (cpu_wdata[0])
  270. spi_wr_en <= 1'b1;
  271. for (int i = 1; i < 8; i++)
  272. if (cpu_wdata[i])
  273. spi_irq[i] <= 1'b1;
  274. end
  275. default: begin
  276. // Do nothing
  277. end
  278. endcase // case (cpu_addr[2:0])
  279. end // else: !if(~rst_n)
  280. always @(posedge sys_clk)
  281. irq <= |cpu_irq;
  282. always @(*)
  283. casez (cpu_addr[2:0])
  284. 3'b000:
  285. cpu_rdata = { 28'b0, cpu_irq };
  286. 3'b010:
  287. cpu_rdata = { 28'b0, spi_irq, spi_wr_en };
  288. 3'b100:
  289. cpu_rdata = { 16'b0, timestamp_q };
  290. default:
  291. cpu_rdata = 32'bx;
  292. endcase // casez (cpu_addr[2:0])
  293. endmodule // esp