msu.v 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 14:55:04 12/14/2010
  7. // Design Name:
  8. // Module Name: msu
  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 msu(
  22. input clkin,
  23. input enable,
  24. input [13:0] pgm_address,
  25. input [7:0] pgm_data,
  26. input pgm_we,
  27. input [2:0] reg_addr,
  28. input [7:0] reg_data_in,
  29. output [7:0] reg_data_out,
  30. input reg_oe,
  31. input reg_we,
  32. output [6:0] status_out,
  33. output [7:0] volume_out,
  34. output volume_latch_out,
  35. output [31:0] addr_out,
  36. output [15:0] track_out,
  37. input [5:0] status_reset_bits,
  38. input [5:0] status_set_bits,
  39. input status_reset_we,
  40. input [13:0] msu_address_ext,
  41. input msu_address_ext_write
  42. );
  43. reg [2:0] reg_addr_r [3:0];
  44. always @(posedge clkin) begin
  45. reg_addr_r[3] <= reg_addr_r[2];
  46. reg_addr_r[2] <= reg_addr_r[1];
  47. reg_addr_r[1] <= reg_addr_r[0];
  48. reg_addr_r[0] <= reg_addr;
  49. end
  50. reg [1:0] status_reset_we_r;
  51. always @(posedge clkin) status_reset_we_r = {status_reset_we_r[0], status_reset_we};
  52. wire status_reset_en = (status_reset_we_r == 2'b01);
  53. reg [13:0] msu_address_r;
  54. wire [13:0] msu_address = msu_address_r;
  55. initial msu_address_r = 13'b0;
  56. wire [7:0] msu_data;
  57. reg [7:0] msu_data_r;
  58. reg [2:0] msu_address_ext_write_sreg;
  59. always @(posedge clkin)
  60. msu_address_ext_write_sreg <= {msu_address_ext_write_sreg[1:0], msu_address_ext_write};
  61. wire msu_address_ext_write_rising = (msu_address_ext_write_sreg[2:1] == 2'b01);
  62. reg [4:0] reg_enable_sreg;
  63. initial reg_enable_sreg = 5'b11111;
  64. always @(posedge clkin) reg_enable_sreg <= {reg_enable_sreg[3:0], enable};
  65. reg [5:0] reg_oe_sreg;
  66. always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[4:0], reg_oe};
  67. wire reg_oe_rising = reg_enable_sreg[4] && (reg_oe_sreg[5:1] == 5'b00001);
  68. wire reg_oe_falling = reg_enable_sreg[1] && (reg_oe_sreg[5:1] == 5'b11110);
  69. reg [5:0] reg_we_sreg;
  70. always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[4:0], reg_we};
  71. wire reg_we_rising = reg_enable_sreg[4] && (reg_we_sreg[5:1] == 5'b00001);
  72. reg [31:0] addr_out_r;
  73. assign addr_out = addr_out_r;
  74. reg [15:0] track_out_r;
  75. assign track_out = track_out_r;
  76. reg [7:0] volume_r;
  77. assign volume_out = volume_r;
  78. reg volume_start_r;
  79. assign volume_latch_out = volume_start_r;
  80. reg audio_start_r;
  81. reg audio_busy_r;
  82. reg data_start_r;
  83. reg data_busy_r;
  84. reg ctrl_start_r;
  85. reg [1:0] audio_ctrl_r;
  86. reg [1:0] audio_status_r;
  87. initial begin
  88. audio_busy_r <= 1'b1;
  89. data_busy_r <= 1'b1;
  90. end
  91. assign status_out = {msu_address_r[13], // 6
  92. audio_start_r, // 5
  93. data_start_r, // 4
  94. volume_start_r, // 3
  95. audio_ctrl_r, // 2:1
  96. ctrl_start_r}; // 0
  97. initial msu_address_r = 14'h1234;
  98. msu_databuf snes_msu_databuf (
  99. .clka(clkin),
  100. .wea(~pgm_we), // Bus [0 : 0]
  101. .addra(pgm_address), // Bus [13 : 0]
  102. .dina(pgm_data), // Bus [7 : 0]
  103. .clkb(clkin),
  104. .addrb(msu_address), // Bus [13 : 0]
  105. .doutb(msu_data)
  106. ); // Bus [7 : 0]
  107. reg [7:0] data_out_r;
  108. assign reg_data_out = data_out_r;
  109. always @(posedge clkin) begin
  110. case(reg_addr_r[3])
  111. 3'h0: data_out_r <= {data_busy_r, audio_busy_r, audio_status_r, 4'b0001};
  112. 3'h1: data_out_r <= msu_data;
  113. 3'h2: data_out_r <= 8'h53;
  114. 3'h3: data_out_r <= 8'h2d;
  115. 3'h4: data_out_r <= 8'h4d;
  116. 3'h5: data_out_r <= 8'h53;
  117. 3'h6: data_out_r <= 8'h55;
  118. 3'h7: data_out_r <= 8'h31;
  119. endcase
  120. end
  121. always @(posedge clkin) begin
  122. if(reg_we_rising) begin
  123. case(reg_addr_r[1])
  124. 3'h0: addr_out_r[7:0] <= reg_data_in;
  125. 3'h1: addr_out_r[15:8] <= reg_data_in;
  126. 3'h2: addr_out_r[23:16] <= reg_data_in;
  127. 3'h3: begin
  128. addr_out_r[31:24] <= reg_data_in;
  129. data_start_r <= 1'b1;
  130. data_busy_r <= 1'b1;
  131. end
  132. 3'h4: begin
  133. track_out_r[7:0] <= reg_data_in;
  134. end
  135. 3'h5: begin
  136. track_out_r[15:8] <= reg_data_in;
  137. audio_start_r <= 1'b1;
  138. audio_busy_r <= 1'b1;
  139. end
  140. 3'h6: begin
  141. volume_r <= reg_data_in;
  142. volume_start_r <= 1'b1;
  143. end
  144. 3'h7: begin
  145. if(!audio_busy_r) begin
  146. audio_ctrl_r <= reg_data_in[1:0];
  147. ctrl_start_r <= 1'b1;
  148. end
  149. end
  150. endcase
  151. end else if (status_reset_en) begin
  152. audio_busy_r <= (audio_busy_r | status_set_bits[5]) & ~status_reset_bits[5];
  153. if(status_reset_bits[5]) audio_start_r <= 1'b0;
  154. data_busy_r <= (data_busy_r | status_set_bits[4]) & ~status_reset_bits[4];
  155. if(status_reset_bits[4]) data_start_r <= 1'b0;
  156. // volume_start_r <= (volume_start_r | status_set_bits[3]) & ~status_reset_bits[3];
  157. audio_status_r <= (audio_status_r | status_set_bits[2:1]) & ~status_reset_bits[2:1];
  158. ctrl_start_r <= (ctrl_start_r | status_set_bits[0]) & ~status_reset_bits[0];
  159. end else begin
  160. volume_start_r <= 1'b0;
  161. end
  162. end
  163. always @(posedge clkin) begin
  164. if(msu_address_ext_write_rising)
  165. msu_address_r <= msu_address_ext;
  166. else if(reg_addr_r[3] == 3'h1 && reg_oe_rising) begin
  167. msu_address_r <= msu_address_r + 1;
  168. end
  169. end
  170. endmodule