mcu_cmd.v 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  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. initial srtc_reset_buf = 0;
  127. reg [31:0] SNES_SYSCLK_FREQ_BUF;
  128. reg [7:0] MCU_DATA_OUT_BUF;
  129. reg [7:0] MCU_DATA_IN_BUF;
  130. reg [2:0] mcu_nextaddr_buf;
  131. wire mcu_nextaddr;
  132. reg DAC_STATUSr;
  133. reg SD_DMA_STATUSr;
  134. reg [6:0] MSU_STATUSr;
  135. always @(posedge clk) begin
  136. DAC_STATUSr <= DAC_STATUS;
  137. SD_DMA_STATUSr <= SD_DMA_STATUS;
  138. MSU_STATUSr <= MSU_STATUS;
  139. end
  140. reg SD_DMA_PARTIALr;
  141. assign SD_DMA_PARTIAL = SD_DMA_PARTIALr;
  142. reg SD_DMA_ENr;
  143. assign SD_DMA_EN = SD_DMA_ENr;
  144. reg [1:0] SD_DMA_TGTr;
  145. assign SD_DMA_TGT = SD_DMA_TGTr;
  146. reg [10:0] SD_DMA_PARTIAL_STARTr;
  147. reg [10:0] SD_DMA_PARTIAL_ENDr;
  148. assign SD_DMA_PARTIAL_START = SD_DMA_PARTIAL_STARTr;
  149. assign SD_DMA_PARTIAL_END = SD_DMA_PARTIAL_ENDr;
  150. reg [23:0] SAVERAM_MASK;
  151. reg [23:0] ROM_MASK;
  152. assign spi_data_out = MCU_DATA_IN_BUF;
  153. initial begin
  154. ADDR_OUT_BUF = 0;
  155. DAC_ADDR_OUT_BUF = 0;
  156. MSU_ADDR_OUT_BUF = 0;
  157. SD_DMA_ENr = 0;
  158. MAPPER_BUF = 1;
  159. SD_DMA_PARTIALr = 0;
  160. end
  161. // command interpretation
  162. always @(posedge clk) begin
  163. if (cmd_ready) begin
  164. case (cmd_data[7:4])
  165. 4'h3: // select mapper
  166. MAPPER_BUF <= cmd_data[2:0];
  167. 4'h4: begin// SD DMA
  168. SD_DMA_ENr <= 1;
  169. SD_DMA_TGTr <= cmd_data[1:0];
  170. SD_DMA_PARTIALr <= cmd_data[2];
  171. end
  172. 4'h8: SD_DMA_TGTr <= 2'b00;
  173. 4'h9: SD_DMA_TGTr <= 2'b00; // cmd_data[1:0]; // not implemented
  174. // 4'hE:
  175. // select memory unit
  176. endcase
  177. end else if (param_ready) begin
  178. casex (cmd_data[7:0])
  179. 8'h1x:
  180. case (spi_byte_cnt)
  181. 32'h2:
  182. ROM_MASK[23:16] <= param_data;
  183. 32'h3:
  184. ROM_MASK[15:8] <= param_data;
  185. 32'h4:
  186. ROM_MASK[7:0] <= param_data;
  187. endcase
  188. 8'h2x:
  189. case (spi_byte_cnt)
  190. 32'h2:
  191. SAVERAM_MASK[23:16] <= param_data;
  192. 32'h3:
  193. SAVERAM_MASK[15:8] <= param_data;
  194. 32'h4:
  195. SAVERAM_MASK[7:0] <= param_data;
  196. endcase
  197. 8'h4x:
  198. SD_DMA_ENr <= 1'b0;
  199. 8'h6x:
  200. case (spi_byte_cnt)
  201. 32'h2: begin
  202. SD_DMA_START_MID_BLOCK <= param_data[7];
  203. SD_DMA_PARTIAL_STARTr[10:9] <= param_data[1:0];
  204. end
  205. 32'h3:
  206. SD_DMA_PARTIAL_STARTr[8:0] <= {param_data, 1'b0};
  207. 32'h4: begin
  208. SD_DMA_END_MID_BLOCK <= param_data[7];
  209. SD_DMA_PARTIAL_ENDr[10:9] <= param_data[1:0];
  210. end
  211. 32'h5:
  212. SD_DMA_PARTIAL_ENDr[8:0] <= {param_data, 1'b0};
  213. endcase
  214. 8'h9x:
  215. MCU_DATA_OUT_BUF <= param_data;
  216. 8'he0:
  217. case (spi_byte_cnt)
  218. 32'h2: begin
  219. msu_status_set_out_buf <= param_data[5:0];
  220. end
  221. 32'h3: begin
  222. msu_status_reset_out_buf <= param_data[5:0];
  223. msu_status_reset_we_buf <= 1'b1;
  224. end
  225. 32'h4:
  226. msu_status_reset_we_buf <= 1'b0;
  227. endcase
  228. 8'he1: // pause DAC
  229. DAC_PLAY_OUT_BUF <= 1'b0;
  230. 8'he2: // resume DAC
  231. DAC_PLAY_OUT_BUF <= 1'b1;
  232. 8'he3: // reset DAC (set DAC playback address = 0)
  233. case (spi_byte_cnt)
  234. 32'h2:
  235. DAC_RESET_OUT_BUF <= 1'b1;
  236. 32'h3:
  237. DAC_RESET_OUT_BUF <= 1'b0;
  238. endcase
  239. 8'he4: // reset MSU read buffer pointer
  240. case (spi_byte_cnt)
  241. 32'h2: begin
  242. MSU_PTR_OUT_BUF[13:8] <= param_data[5:0];
  243. MSU_PTR_OUT_BUF[7:0] <= 8'h0;
  244. end
  245. 32'h3: begin
  246. MSU_PTR_OUT_BUF[7:0] <= param_data;
  247. MSU_RESET_OUT_BUF <= 1'b1;
  248. end
  249. 32'h4:
  250. MSU_RESET_OUT_BUF <= 1'b0;
  251. endcase
  252. 8'he5:
  253. case (spi_byte_cnt)
  254. 32'h2:
  255. rtc_data_out_buf[55:48] <= param_data;
  256. 32'h3:
  257. rtc_data_out_buf[47:40] <= param_data;
  258. 32'h4:
  259. rtc_data_out_buf[39:32] <= param_data;
  260. 32'h5:
  261. rtc_data_out_buf[31:24] <= param_data;
  262. 32'h6:
  263. rtc_data_out_buf[23:16] <= param_data;
  264. 32'h7:
  265. rtc_data_out_buf[15:8] <= param_data;
  266. 32'h8: begin
  267. rtc_data_out_buf[7:0] <= param_data;
  268. rtc_pgm_we_buf <= 1'b1;
  269. end
  270. 32'h9:
  271. rtc_pgm_we_buf <= 1'b0;
  272. endcase
  273. 8'he6:
  274. case (spi_byte_cnt)
  275. 32'h2: begin
  276. bsx_regs_set_out_buf <= param_data[7:0];
  277. end
  278. 32'h3: begin
  279. bsx_regs_reset_out_buf <= param_data[7:0];
  280. bsx_regs_reset_we_buf <= 1'b1;
  281. end
  282. 32'h4:
  283. bsx_regs_reset_we_buf <= 1'b0;
  284. endcase
  285. 8'he7:
  286. case (spi_byte_cnt)
  287. 32'h2: begin
  288. srtc_reset_buf <= 1'b1;
  289. end
  290. 32'h3: begin
  291. srtc_reset_buf <= 1'b0;
  292. end
  293. endcase
  294. 8'he8: begin// reset DSPx PGM+DAT address
  295. case (spi_byte_cnt)
  296. 32'h2: begin
  297. dspx_pgm_addr_out <= 11'b00000000000;
  298. dspx_dat_addr_out <= 10'b0000000000;
  299. end
  300. endcase
  301. end
  302. 8'he9:// write DSPx PGM w/ increment
  303. case (spi_byte_cnt)
  304. 32'h2: dspx_pgm_data_out[23:16] <= param_data[7:0];
  305. 32'h3: dspx_pgm_data_out[15:8] <= param_data[7:0];
  306. 32'h4: dspx_pgm_data_out[7:0] <= param_data[7:0];
  307. 32'h5: dspx_pgm_we_out <= 1'b1;
  308. 32'h6: begin
  309. dspx_pgm_we_out <= 1'b0;
  310. dspx_pgm_addr_out <= dspx_pgm_addr_out + 1;
  311. end
  312. endcase
  313. 8'hea:// write DSPx DAT w/ increment
  314. case (spi_byte_cnt)
  315. 32'h2: dspx_dat_data_out[15:8] <= param_data[7:0];
  316. 32'h3: dspx_dat_data_out[7:0] <= param_data[7:0];
  317. 32'h4: dspx_dat_we_out <= 1'b1;
  318. 32'h5: begin
  319. dspx_dat_we_out <= 1'b0;
  320. dspx_dat_addr_out <= dspx_dat_addr_out + 1;
  321. end
  322. endcase
  323. 8'heb: // put DSPx into reset
  324. dspx_reset_out <= 1'b1;
  325. 8'hec: // release DSPx reset
  326. dspx_reset_out <= 1'b0;
  327. 8'hed:
  328. featurebits_out <= param_data;
  329. 8'hee:
  330. region_out <= param_data[0];
  331. endcase
  332. end
  333. end
  334. always @(posedge clk) begin
  335. if(param_ready && cmd_data[7:4] == 4'h0) begin
  336. case (cmd_data[1:0])
  337. 2'b01: begin
  338. case (spi_byte_cnt)
  339. 32'h2: begin
  340. DAC_ADDR_OUT_BUF[10:8] <= param_data[2:0];
  341. DAC_ADDR_OUT_BUF[7:0] <= 8'b0;
  342. end
  343. 32'h3:
  344. DAC_ADDR_OUT_BUF[7:0] <= param_data;
  345. endcase
  346. end
  347. 2'b10: begin
  348. case (spi_byte_cnt)
  349. 32'h2: begin
  350. MSU_ADDR_OUT_BUF[13:8] <= param_data[5:0];
  351. MSU_ADDR_OUT_BUF[7:0] <= 8'b0;
  352. end
  353. 32'h3:
  354. MSU_ADDR_OUT_BUF[7:0] <= param_data;
  355. endcase
  356. end
  357. default:
  358. case (spi_byte_cnt)
  359. 32'h2: begin
  360. ADDR_OUT_BUF[23:16] <= param_data;
  361. ADDR_OUT_BUF[15:0] <= 16'b0;
  362. end
  363. 32'h3:
  364. ADDR_OUT_BUF[15:8] <= param_data;
  365. 32'h4:
  366. ADDR_OUT_BUF[7:0] <= param_data;
  367. endcase
  368. endcase
  369. end else if (SD_DMA_NEXTADDR | (mcu_nextaddr & (cmd_data[7:5] == 3'h4)
  370. && (cmd_data[3])
  371. && (spi_byte_cnt >= (32'h1+cmd_data[4])))
  372. )
  373. begin
  374. case (SD_DMA_TGTr)
  375. 2'b00: ADDR_OUT_BUF <= ADDR_OUT_BUF + 1;
  376. 2'b01: DAC_ADDR_OUT_BUF <= DAC_ADDR_OUT_BUF + 1;
  377. 2'b10: MSU_ADDR_OUT_BUF <= MSU_ADDR_OUT_BUF + 1;
  378. endcase
  379. end
  380. end
  381. // value fetch during last SPI bit
  382. always @(posedge clk) begin
  383. if (cmd_data[7:4] == 4'h8 && mcu_nextaddr)
  384. MCU_DATA_IN_BUF <= mcu_data_in;
  385. else if (cmd_ready | param_ready /* bit_cnt == 7 */) begin
  386. if (cmd_data[7:0] == 8'hF0)
  387. MCU_DATA_IN_BUF <= 8'hA5;
  388. else if (cmd_data[7:0] == 8'hF1)
  389. case (spi_byte_cnt[0])
  390. 1'b1: // buffer status (1st byte)
  391. MCU_DATA_IN_BUF <= {SD_DMA_STATUSr, DAC_STATUSr, MSU_STATUSr[6], 5'b0};
  392. 1'b0: // control status (2nd byte)
  393. MCU_DATA_IN_BUF <= {2'b0, MSU_STATUSr[5:0]};
  394. endcase
  395. else if (cmd_data[7:0] == 8'hF2)
  396. case (spi_byte_cnt)
  397. 32'h1:
  398. MCU_DATA_IN_BUF <= msu_addressrq[31:24];
  399. 32'h2:
  400. MCU_DATA_IN_BUF <= msu_addressrq[23:16];
  401. 32'h3:
  402. MCU_DATA_IN_BUF <= msu_addressrq[15:8];
  403. 32'h4:
  404. MCU_DATA_IN_BUF <= msu_addressrq[7:0];
  405. endcase
  406. else if (cmd_data[7:0] == 8'hF3)
  407. case (spi_byte_cnt)
  408. 32'h1:
  409. MCU_DATA_IN_BUF <= msu_trackrq[15:8];
  410. 32'h2:
  411. MCU_DATA_IN_BUF <= msu_trackrq[7:0];
  412. endcase
  413. else if (cmd_data[7:0] == 8'hF4)
  414. MCU_DATA_IN_BUF <= msu_volumerq;
  415. else if (cmd_data[7:0] == 8'hFE)
  416. case (spi_byte_cnt)
  417. 32'h1:
  418. SNES_SYSCLK_FREQ_BUF <= snes_sysclk_freq;
  419. 32'h2:
  420. MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[31:24];
  421. 32'h3:
  422. MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[23:16];
  423. 32'h4:
  424. MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[15:8];
  425. 32'h5:
  426. MCU_DATA_IN_BUF <= SNES_SYSCLK_FREQ_BUF[7:0];
  427. endcase
  428. else if (cmd_data[7:0] == 8'hFF)
  429. MCU_DATA_IN_BUF <= param_data;
  430. end
  431. end
  432. // nextaddr pulse generation
  433. always @(posedge clk) begin
  434. mcu_nextaddr_buf <= {mcu_nextaddr_buf[1:0], mcu_rq_rdy};
  435. end
  436. parameter ST_RQ = 2'b01;
  437. parameter ST_IDLE = 2'b10;
  438. reg [1:0] rrq_state;
  439. initial rrq_state = ST_IDLE;
  440. reg mcu_rrq_r;
  441. reg [1:0] wrq_state;
  442. initial wrq_state = ST_IDLE;
  443. reg mcu_wrq_r;
  444. always @(posedge clk) begin
  445. case(rrq_state)
  446. ST_IDLE: begin
  447. if((param_ready | cmd_ready) && cmd_data[7:4] == 4'h8) begin
  448. mcu_rrq_r <= 1'b1;
  449. rrq_state <= ST_RQ;
  450. end else
  451. rrq_state <= ST_IDLE;
  452. end
  453. ST_RQ: begin
  454. mcu_rrq_r <= 1'b0;
  455. rrq_state <= ST_IDLE;
  456. end
  457. endcase
  458. end
  459. always @(posedge clk) begin
  460. case(wrq_state)
  461. ST_IDLE: begin
  462. if(param_ready && cmd_data[7:4] == 4'h9) begin
  463. mcu_wrq_r <= 1'b1;
  464. wrq_state <= ST_RQ;
  465. end else
  466. wrq_state <= ST_IDLE;
  467. end
  468. ST_RQ: begin
  469. mcu_wrq_r <= 1'b0;
  470. wrq_state <= ST_IDLE;
  471. end
  472. endcase
  473. end
  474. // trigger for nextaddr
  475. assign mcu_nextaddr = mcu_nextaddr_buf == 2'b01;
  476. assign mcu_rrq = mcu_rrq_r;
  477. assign mcu_wrq = mcu_wrq_r;
  478. assign mcu_write = SD_DMA_STATUS
  479. ?(SD_DMA_TGTr == 2'b00
  480. ?SD_DMA_SRAM_WE
  481. :1'b1
  482. )
  483. : 1'b1;
  484. assign addr_out = ADDR_OUT_BUF;
  485. assign dac_addr_out = DAC_ADDR_OUT_BUF;
  486. assign msu_addr_out = MSU_ADDR_OUT_BUF;
  487. assign dac_play_out = DAC_PLAY_OUT_BUF;
  488. assign dac_reset_out = DAC_RESET_OUT_BUF;
  489. assign msu_status_reset_we = msu_status_reset_we_buf;
  490. assign msu_status_reset_out = msu_status_reset_out_buf;
  491. assign msu_status_set_out = msu_status_set_out_buf;
  492. assign msu_reset_out = MSU_RESET_OUT_BUF;
  493. assign msu_ptr_out = MSU_PTR_OUT_BUF;
  494. assign bsx_regs_reset_we = bsx_regs_reset_we_buf;
  495. assign bsx_regs_reset_out = bsx_regs_reset_out_buf;
  496. assign bsx_regs_set_out = bsx_regs_set_out_buf;
  497. assign rtc_data_out = rtc_data_out_buf;
  498. assign rtc_pgm_we = rtc_pgm_we_buf;
  499. assign srtc_reset = srtc_reset_buf;
  500. assign mcu_data_out = SD_DMA_STATUS ? SD_DMA_SRAM_DATA : MCU_DATA_OUT_BUF;
  501. assign mcu_mapper = MAPPER_BUF;
  502. assign rom_mask_out = ROM_MASK;
  503. assign saveram_mask_out = SAVERAM_MASK;
  504. assign DBG_mcu_nextaddr = mcu_nextaddr;
  505. endmodule