mcu_cmd.v 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 21:57:50 08/25/2009
  7. // Design Name:
  8. // Module Name: mcu_cmd
  9. // Project Name:
  10. // Target Devices:
  11. // Tool versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21. module mcu_cmd(
  22. input clk,
  23. input cmd_ready,
  24. input param_ready,
  25. input [7:0] cmd_data,
  26. input [7:0] param_data,
  27. output [2:0] mcu_mapper,
  28. output mcu_rrq,
  29. output mcu_write,
  30. output mcu_wrq,
  31. input mcu_rq_rdy,
  32. output [7:0] mcu_data_out,
  33. input [7:0] mcu_data_in,
  34. output [7:0] spi_data_out,
  35. input [31:0] spi_byte_cnt,
  36. input [2:0] spi_bit_cnt,
  37. output [23:0] addr_out,
  38. output [23:0] saveram_mask_out,
  39. output [23:0] rom_mask_out,
  40. // SD "DMA" extension
  41. output SD_DMA_EN,
  42. input SD_DMA_STATUS,
  43. input SD_DMA_NEXTADDR,
  44. input [7:0] SD_DMA_SRAM_DATA,
  45. input SD_DMA_SRAM_WE,
  46. output [1:0] SD_DMA_TGT,
  47. output SD_DMA_PARTIAL,
  48. output [10:0] SD_DMA_PARTIAL_START,
  49. output [10:0] SD_DMA_PARTIAL_END,
  50. output reg SD_DMA_START_MID_BLOCK,
  51. output reg SD_DMA_END_MID_BLOCK,
  52. // DAC
  53. output [10:0] dac_addr_out,
  54. input DAC_STATUS,
  55. output dac_play_out,
  56. output dac_reset_out,
  57. // MSU data
  58. output [13:0] msu_addr_out,
  59. input [6:0] MSU_STATUS,
  60. output [5:0] msu_status_reset_out,
  61. output [5:0] msu_status_set_out,
  62. output msu_status_reset_we,
  63. input [31:0] msu_addressrq,
  64. input [15:0] msu_trackrq,
  65. input [7:0] msu_volumerq,
  66. output [13:0] msu_ptr_out,
  67. output msu_reset_out,
  68. // BS-X
  69. output [7:0] bsx_regs_reset_out,
  70. output [7:0] bsx_regs_set_out,
  71. output bsx_regs_reset_we,
  72. // generic RTC
  73. output [55:0] rtc_data_out,
  74. output rtc_pgm_we,
  75. // S-RTC
  76. output srtc_reset,
  77. // uPD77C25
  78. output reg [23:0] dspx_pgm_data_out,
  79. output reg [10:0] dspx_pgm_addr_out,
  80. output reg dspx_pgm_we_out,
  81. output reg [15:0] dspx_dat_data_out,
  82. output reg [10:0] dspx_dat_addr_out,
  83. output reg dspx_dat_we_out,
  84. output reg dspx_reset_out,
  85. // feature enable
  86. output reg [7:0] featurebits_out,
  87. output reg region_out,
  88. // SNES sync/clk
  89. input snes_sysclk,
  90. // debug
  91. output DBG_mcu_nextaddr
  92. );
  93. initial begin
  94. dspx_pgm_addr_out = 11'b00000000000;
  95. dspx_dat_addr_out = 10'b0000000000;
  96. dspx_reset_out = 1'b1;
  97. region_out = 0;
  98. SD_DMA_START_MID_BLOCK = 0;
  99. SD_DMA_END_MID_BLOCK = 0;
  100. end
  101. wire [31:0] snes_sysclk_freq;
  102. clk_test snes_clk_test (
  103. .clk(clk),
  104. .sysclk(snes_sysclk),
  105. .snes_sysclk_freq(snes_sysclk_freq)
  106. );
  107. reg [2:0] MAPPER_BUF;
  108. reg [23:0] ADDR_OUT_BUF;
  109. reg [10:0] DAC_ADDR_OUT_BUF;
  110. reg [7:0] DAC_VOL_OUT_BUF;
  111. reg DAC_VOL_LATCH_BUF;
  112. reg DAC_PLAY_OUT_BUF;
  113. reg DAC_RESET_OUT_BUF;
  114. reg [13:0] MSU_ADDR_OUT_BUF;
  115. reg [13:0] MSU_PTR_OUT_BUF;
  116. reg [5:0] msu_status_set_out_buf;
  117. reg [5:0] msu_status_reset_out_buf;
  118. reg msu_status_reset_we_buf;
  119. reg MSU_RESET_OUT_BUF;
  120. reg [7:0] bsx_regs_set_out_buf;
  121. reg [7:0] bsx_regs_reset_out_buf;
  122. reg bsx_regs_reset_we_buf;
  123. reg [55:0] rtc_data_out_buf;
  124. reg rtc_pgm_we_buf;
  125. reg srtc_reset_buf;
  126. reg [31:0] SNES_SYSCLK_FREQ_BUF;
  127. reg [7:0] MCU_DATA_OUT_BUF;
  128. reg [7:0] MCU_DATA_IN_BUF;
  129. reg [1:0] mcu_nextaddr_buf;
  130. wire mcu_nextaddr;
  131. reg DAC_STATUSr;
  132. reg SD_DMA_STATUSr;
  133. reg [6:0] MSU_STATUSr;
  134. always @(posedge clk) begin
  135. DAC_STATUSr <= DAC_STATUS;
  136. SD_DMA_STATUSr <= SD_DMA_STATUS;
  137. MSU_STATUSr <= MSU_STATUS;
  138. end
  139. reg SD_DMA_PARTIALr;
  140. assign SD_DMA_PARTIAL = SD_DMA_PARTIALr;
  141. reg SD_DMA_ENr;
  142. assign SD_DMA_EN = SD_DMA_ENr;
  143. reg [1:0] SD_DMA_TGTr;
  144. assign SD_DMA_TGT = SD_DMA_TGTr;
  145. reg [10:0] SD_DMA_PARTIAL_STARTr;
  146. reg [10:0] SD_DMA_PARTIAL_ENDr;
  147. assign SD_DMA_PARTIAL_START = SD_DMA_PARTIAL_STARTr;
  148. assign SD_DMA_PARTIAL_END = SD_DMA_PARTIAL_ENDr;
  149. reg [23:0] SAVERAM_MASK;
  150. reg [23:0] ROM_MASK;
  151. assign spi_data_out = MCU_DATA_IN_BUF;
  152. initial begin
  153. ADDR_OUT_BUF = 0;
  154. DAC_ADDR_OUT_BUF = 0;
  155. MSU_ADDR_OUT_BUF = 0;
  156. SD_DMA_ENr = 0;
  157. MAPPER_BUF = 1;
  158. SD_DMA_PARTIALr = 0;
  159. end
  160. // command interpretation
  161. always @(posedge clk) begin
  162. if (cmd_ready) begin
  163. case (cmd_data[7:4])
  164. 4'h3: // select mapper
  165. MAPPER_BUF <= cmd_data[2:0];
  166. 4'h4: begin// SD DMA
  167. SD_DMA_ENr <= 1;
  168. SD_DMA_TGTr <= cmd_data[1:0];
  169. SD_DMA_PARTIALr <= cmd_data[2];
  170. end
  171. 4'h8: SD_DMA_TGTr <= 2'b00;
  172. 4'h9: SD_DMA_TGTr <= 2'b00; // cmd_data[1:0]; // not implemented
  173. // 4'hE:
  174. // select memory unit
  175. endcase
  176. end else if (param_ready) begin
  177. casex (cmd_data[7:0])
  178. 8'h1x:
  179. case (spi_byte_cnt)
  180. 32'h2:
  181. ROM_MASK[23:16] <= param_data;
  182. 32'h3:
  183. ROM_MASK[15:8] <= param_data;
  184. 32'h4:
  185. ROM_MASK[7:0] <= param_data;
  186. endcase
  187. 8'h2x:
  188. case (spi_byte_cnt)
  189. 32'h2:
  190. SAVERAM_MASK[23:16] <= param_data;
  191. 32'h3:
  192. SAVERAM_MASK[15:8] <= param_data;
  193. 32'h4:
  194. SAVERAM_MASK[7:0] <= param_data;
  195. endcase
  196. 8'h4x:
  197. SD_DMA_ENr <= 1'b0;
  198. 8'h6x:
  199. case (spi_byte_cnt)
  200. 32'h2: begin
  201. SD_DMA_START_MID_BLOCK <= param_data[7];
  202. SD_DMA_PARTIAL_STARTr[10:9] <= param_data[1:0];
  203. end
  204. 32'h3:
  205. SD_DMA_PARTIAL_STARTr[8:0] <= {param_data, 1'b0};
  206. 32'h4: begin
  207. SD_DMA_END_MID_BLOCK <= param_data[7];
  208. SD_DMA_PARTIAL_ENDr[10:9] <= param_data[1:0];
  209. end
  210. 32'h5:
  211. SD_DMA_PARTIAL_ENDr[8:0] <= {param_data, 1'b0};
  212. endcase
  213. 8'h9x:
  214. MCU_DATA_OUT_BUF <= param_data;
  215. 8'he0:
  216. case (spi_byte_cnt)
  217. 32'h2: begin
  218. msu_status_set_out_buf <= param_data[5:0];
  219. end
  220. 32'h3: begin
  221. msu_status_reset_out_buf <= param_data[5:0];
  222. msu_status_reset_we_buf <= 1'b1;
  223. end
  224. 32'h4:
  225. msu_status_reset_we_buf <= 1'b0;
  226. endcase
  227. 8'he1: // pause DAC
  228. DAC_PLAY_OUT_BUF <= 1'b0;
  229. 8'he2: // resume DAC
  230. DAC_PLAY_OUT_BUF <= 1'b1;
  231. 8'he3: // reset DAC (set DAC playback address = 0)
  232. case (spi_byte_cnt)
  233. 32'h2:
  234. DAC_RESET_OUT_BUF <= 1'b1;
  235. 32'h3:
  236. DAC_RESET_OUT_BUF <= 1'b0;
  237. endcase
  238. 8'he4: // reset MSU read buffer pointer
  239. case (spi_byte_cnt)
  240. 32'h2: begin
  241. MSU_PTR_OUT_BUF[13:8] <= param_data[5:0];
  242. MSU_PTR_OUT_BUF[7:0] <= 8'h0;
  243. end
  244. 32'h3: begin
  245. MSU_PTR_OUT_BUF[7:0] <= param_data;
  246. MSU_RESET_OUT_BUF <= 1'b1;
  247. end
  248. 32'h4:
  249. MSU_RESET_OUT_BUF <= 1'b0;
  250. endcase
  251. 8'he5:
  252. case (spi_byte_cnt)
  253. 32'h2:
  254. rtc_data_out_buf[55:48] <= param_data;
  255. 32'h3:
  256. rtc_data_out_buf[47:40] <= param_data;
  257. 32'h4:
  258. rtc_data_out_buf[39:32] <= param_data;
  259. 32'h5:
  260. rtc_data_out_buf[31:24] <= param_data;
  261. 32'h6:
  262. rtc_data_out_buf[23:16] <= param_data;
  263. 32'h7:
  264. rtc_data_out_buf[15:8] <= param_data;
  265. 32'h8: begin
  266. rtc_data_out_buf[7:0] <= param_data;
  267. rtc_pgm_we_buf <= 1'b1;
  268. end
  269. 32'h9:
  270. rtc_pgm_we_buf <= 1'b0;
  271. endcase
  272. 8'he6:
  273. case (spi_byte_cnt)
  274. 32'h2: begin
  275. bsx_regs_set_out_buf <= param_data[7:0];
  276. end
  277. 32'h3: begin
  278. bsx_regs_reset_out_buf <= param_data[7:0];
  279. bsx_regs_reset_we_buf <= 1'b1;
  280. end
  281. 32'h4:
  282. bsx_regs_reset_we_buf <= 1'b0;
  283. endcase
  284. 8'he7:
  285. case (spi_byte_cnt)
  286. 32'h2: begin
  287. srtc_reset_buf <= 1'b1;
  288. end
  289. 32'h3: begin
  290. srtc_reset_buf <= 1'b0;
  291. end
  292. endcase
  293. 8'he8: begin// reset DSPx PGM+DAT address
  294. case (spi_byte_cnt)
  295. 32'h2: begin
  296. dspx_pgm_addr_out <= 11'b00000000000;
  297. dspx_dat_addr_out <= 10'b0000000000;
  298. end
  299. endcase
  300. end
  301. 8'he9:// write DSPx PGM w/ increment
  302. case (spi_byte_cnt)
  303. 32'h2: dspx_pgm_data_out[23:16] <= param_data[7:0];
  304. 32'h3: dspx_pgm_data_out[15:8] <= param_data[7:0];
  305. 32'h4: dspx_pgm_data_out[7:0] <= param_data[7:0];
  306. 32'h5: dspx_pgm_we_out <= 1'b1;
  307. 32'h6: begin
  308. dspx_pgm_we_out <= 1'b0;
  309. dspx_pgm_addr_out <= dspx_pgm_addr_out + 1;
  310. end
  311. endcase
  312. 8'hea:// write DSPx DAT w/ increment
  313. case (spi_byte_cnt)
  314. 32'h2: dspx_dat_data_out[15:8] <= param_data[7:0];
  315. 32'h3: dspx_dat_data_out[7:0] <= param_data[7:0];
  316. 32'h4: dspx_dat_we_out <= 1'b1;
  317. 32'h5: begin
  318. dspx_dat_we_out <= 1'b0;
  319. dspx_dat_addr_out <= dspx_dat_addr_out + 1;
  320. end
  321. endcase
  322. 8'heb: // put DSPx into reset
  323. dspx_reset_out <= 1'b1;
  324. 8'hec: // release DSPx reset
  325. dspx_reset_out <= 1'b0;
  326. 8'hed:
  327. featurebits_out <= param_data;
  328. 8'hee:
  329. region_out <= param_data[0];
  330. endcase
  331. end
  332. end
  333. always @(posedge clk) begin
  334. if(param_ready && cmd_data[7:4] == 4'h0) begin
  335. case (cmd_data[1:0])
  336. 2'b01: begin
  337. case (spi_byte_cnt)
  338. 32'h2: begin
  339. DAC_ADDR_OUT_BUF[10:8] <= param_data[2:0];
  340. DAC_ADDR_OUT_BUF[7:0] <= 8'b0;
  341. end
  342. 32'h3:
  343. DAC_ADDR_OUT_BUF[7:0] <= param_data;
  344. endcase
  345. end
  346. 2'b10: begin
  347. case (spi_byte_cnt)
  348. 32'h2: begin
  349. MSU_ADDR_OUT_BUF[13:8] <= param_data[5:0];
  350. MSU_ADDR_OUT_BUF[7:0] <= 8'b0;
  351. end
  352. 32'h3:
  353. MSU_ADDR_OUT_BUF[7:0] <= param_data;
  354. endcase
  355. end
  356. default:
  357. case (spi_byte_cnt)
  358. 32'h2: begin
  359. ADDR_OUT_BUF[23:16] <= param_data;
  360. ADDR_OUT_BUF[15:0] <= 16'b0;
  361. end
  362. 32'h3:
  363. ADDR_OUT_BUF[15:8] <= param_data;
  364. 32'h4:
  365. ADDR_OUT_BUF[7:0] <= param_data;
  366. endcase
  367. endcase
  368. end else if (SD_DMA_NEXTADDR | (mcu_nextaddr & (cmd_data[7:5] == 3'h4)
  369. && (cmd_data[3])
  370. && (spi_byte_cnt >= (32'h1+cmd_data[4])))
  371. )
  372. begin
  373. case (SD_DMA_TGTr)
  374. 2'b00: ADDR_OUT_BUF <= ADDR_OUT_BUF + 1;
  375. 2'b01: DAC_ADDR_OUT_BUF <= DAC_ADDR_OUT_BUF + 1;
  376. 2'b10: MSU_ADDR_OUT_BUF <= MSU_ADDR_OUT_BUF + 1;
  377. endcase
  378. end
  379. end
  380. // value fetch during last SPI bit
  381. always @(posedge clk) begin
  382. if (cmd_data[7:4] == 4'h8 && mcu_nextaddr_buf == 2'b01)
  383. MCU_DATA_IN_BUF <= mcu_data_in;
  384. else if (spi_bit_cnt == 3'h7) begin
  385. if (cmd_data[7:0] == 8'hF0)
  386. MCU_DATA_IN_BUF <= 8'hA5;
  387. else if (cmd_data[7:0] == 8'hF1)
  388. case (spi_byte_cnt[0])
  389. 1'b1: // buffer status (1st byte)
  390. MCU_DATA_IN_BUF <= {SD_DMA_STATUSr, DAC_STATUSr, MSU_STATUSr[6], 5'b0};
  391. 1'b0: // control status (2nd byte)
  392. MCU_DATA_IN_BUF <= {2'b0, MSU_STATUSr[5:0]};
  393. endcase
  394. else if (cmd_data[7:0] == 8'hF2)
  395. case (spi_byte_cnt)
  396. 32'h1:
  397. MCU_DATA_IN_BUF <= msu_addressrq[31:24];
  398. 32'h2:
  399. MCU_DATA_IN_BUF <= msu_addressrq[23:16];
  400. 32'h3:
  401. MCU_DATA_IN_BUF <= msu_addressrq[15:8];
  402. 32'h4:
  403. MCU_DATA_IN_BUF <= msu_addressrq[7:0];
  404. endcase
  405. else if (cmd_data[7:0] == 8'hF3)
  406. case (spi_byte_cnt)
  407. 32'h1:
  408. MCU_DATA_IN_BUF <= msu_trackrq[15:8];
  409. 32'h2:
  410. MCU_DATA_IN_BUF <= msu_trackrq[7:0];
  411. endcase
  412. else if (cmd_data[7:0] == 8'hF4)
  413. MCU_DATA_IN_BUF <= msu_volumerq;
  414. else if (cmd_data[7:0] == 8'hFE)
  415. case (spi_byte_cnt)
  416. 32'h1:
  417. SNES_SYSCLK_FREQ_BUF <= snes_sysclk_freq;
  418. 32'h2:
  419. MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[31:24];
  420. 32'h3:
  421. MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[23:16];
  422. 32'h4:
  423. MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[15:8];
  424. 32'h5:
  425. MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[7:0];
  426. endcase
  427. else if (cmd_data[7:0] == 8'hFF)
  428. MCU_DATA_IN_BUF <= param_data;
  429. end
  430. end
  431. // nextaddr pulse generation
  432. always @(posedge clk) begin
  433. mcu_nextaddr_buf <= {mcu_nextaddr_buf[1:0], mcu_rq_rdy};
  434. end
  435. parameter ST_RQ = 2'b01;
  436. parameter ST_IDLE = 2'b10;
  437. reg [1:0] rrq_state;
  438. initial rrq_state = ST_IDLE;
  439. reg mcu_rrq_r;
  440. reg [1:0] wrq_state;
  441. initial wrq_state = ST_IDLE;
  442. reg mcu_wrq_r;
  443. always @(posedge clk) begin
  444. case(rrq_state)
  445. ST_IDLE: begin
  446. if((param_ready | cmd_ready) && cmd_data[7:4] == 4'h8) begin
  447. mcu_rrq_r <= 1'b1;
  448. rrq_state <= ST_RQ;
  449. end else
  450. rrq_state <= ST_IDLE;
  451. end
  452. ST_RQ: begin
  453. mcu_rrq_r <= 1'b0;
  454. rrq_state <= ST_IDLE;
  455. end
  456. endcase
  457. end
  458. always @(posedge clk) begin
  459. case(wrq_state)
  460. ST_IDLE: begin
  461. if(param_ready && cmd_data[7:4] == 4'h9) begin
  462. mcu_wrq_r <= 1'b1;
  463. wrq_state <= ST_RQ;
  464. end else
  465. wrq_state <= ST_IDLE;
  466. end
  467. ST_RQ: begin
  468. mcu_wrq_r <= 1'b0;
  469. wrq_state <= ST_IDLE;
  470. end
  471. endcase
  472. end
  473. // trigger for nextaddr
  474. assign mcu_nextaddr = mcu_nextaddr_buf == 2'b01;
  475. assign mcu_rrq = mcu_rrq_r;
  476. assign mcu_wrq = mcu_wrq_r;
  477. assign mcu_write = SD_DMA_STATUS
  478. ?(SD_DMA_TGTr == 2'b00
  479. ?SD_DMA_SRAM_WE
  480. :1'b1
  481. )
  482. : 1'b1;
  483. assign addr_out = ADDR_OUT_BUF;
  484. assign dac_addr_out = DAC_ADDR_OUT_BUF;
  485. assign msu_addr_out = MSU_ADDR_OUT_BUF;
  486. assign dac_play_out = DAC_PLAY_OUT_BUF;
  487. assign dac_reset_out = DAC_RESET_OUT_BUF;
  488. assign msu_status_reset_we = msu_status_reset_we_buf;
  489. assign msu_status_reset_out = msu_status_reset_out_buf;
  490. assign msu_status_set_out = msu_status_set_out_buf;
  491. assign msu_reset_out = MSU_RESET_OUT_BUF;
  492. assign msu_ptr_out = MSU_PTR_OUT_BUF;
  493. assign bsx_regs_reset_we = bsx_regs_reset_we_buf;
  494. assign bsx_regs_reset_out = bsx_regs_reset_out_buf;
  495. assign bsx_regs_set_out = bsx_regs_set_out_buf;
  496. assign rtc_data_out = rtc_data_out_buf;
  497. assign rtc_pgm_we = rtc_pgm_we_buf;
  498. assign srtc_reset = srtc_reset_buf;
  499. assign mcu_data_out = SD_DMA_STATUS ? SD_DMA_SRAM_DATA : MCU_DATA_OUT_BUF;
  500. assign mcu_mapper = MAPPER_BUF;
  501. assign rom_mask_out = ROM_MASK;
  502. assign saveram_mask_out = SAVERAM_MASK;
  503. assign DBG_mcu_nextaddr = mcu_nextaddr;
  504. endmodule