`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 14:55:04 12/14/2010 // Design Name: // Module Name: msu // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module msu( input clkin, input enable, input [13:0] pgm_address, input [7:0] pgm_data, input pgm_we, input [2:0] reg_addr, input [7:0] reg_data_in, output [7:0] reg_data_out, input reg_oe, input reg_we, output [6:0] status_out, output [7:0] volume_out, output volume_latch_out, output [31:0] addr_out, output [15:0] track_out, input [5:0] status_reset_bits, input [5:0] status_set_bits, input status_reset_we, input [13:0] msu_address_ext, input msu_address_ext_write ); reg [2:0] reg_addr_r [3:0]; always @(posedge clkin) begin reg_addr_r[3] <= reg_addr_r[2]; reg_addr_r[2] <= reg_addr_r[1]; reg_addr_r[1] <= reg_addr_r[0]; reg_addr_r[0] <= reg_addr; end reg [1:0] status_reset_we_r; always @(posedge clkin) status_reset_we_r = {status_reset_we_r[0], status_reset_we}; wire status_reset_en = (status_reset_we_r == 2'b01); reg [13:0] msu_address_r; wire [13:0] msu_address = msu_address_r; wire [7:0] msu_data; reg [1:0] msu_address_ext_write_sreg; always @(posedge clkin) msu_address_ext_write_sreg <= {msu_address_ext_write_sreg[0], msu_address_ext_write}; wire msu_address_ext_write_rising = (msu_address_ext_write_sreg[1:0] == 2'b01); reg [4:0] reg_enable_sreg; initial reg_enable_sreg = 5'b11111; always @(posedge clkin) reg_enable_sreg <= {reg_enable_sreg[3:0], enable}; reg [5:0] reg_oe_sreg; always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[4:0], reg_oe}; wire reg_oe_rising = reg_enable_sreg[4] && (reg_oe_sreg[5:0] == 6'b000001); reg [5:0] reg_we_sreg; always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[4:0], reg_we}; wire reg_we_rising = reg_enable_sreg[4] && (reg_we_sreg[5:0] == 6'b000001); reg [31:0] addr_out_r; assign addr_out = addr_out_r; reg [15:0] track_out_r; assign track_out = track_out_r; reg [7:0] volume_r; assign volume_out = volume_r; reg volume_start_r; assign volume_latch_out = volume_start_r; reg audio_start_r; reg audio_busy_r; reg data_start_r; reg data_busy_r; reg ctrl_start_r; reg [1:0] audio_ctrl_r; reg [1:0] audio_status_r; initial begin audio_busy_r <= 1'b1; data_busy_r <= 1'b1; end assign status_out = {msu_address_r[13], // 6 audio_start_r, // 5 data_start_r, // 4 volume_start_r, // 3 audio_ctrl_r, // 2:1 ctrl_start_r}; // 0 initial msu_address_r = 14'h1234; msu_databuf snes_msu_databuf ( .clka(clkin), .wea(~pgm_we), // Bus [0 : 0] .addra(pgm_address), // Bus [13 : 0] .dina(pgm_data), // Bus [7 : 0] .clkb(clkin), .addrb(msu_address), // Bus [13 : 0] .doutb(msu_data) ); // Bus [7 : 0] reg [7:0] data_out_r; assign reg_data_out = data_out_r; always @(posedge clkin) begin case(reg_addr_r[3]) 3'h0: data_out_r <= {data_busy_r, audio_busy_r, audio_status_r, 4'b0001}; 3'h1: data_out_r <= msu_data; 3'h2: data_out_r <= 8'h53; 3'h3: data_out_r <= 8'h2d; 3'h4: data_out_r <= 8'h4d; 3'h5: data_out_r <= 8'h53; 3'h6: data_out_r <= 8'h55; 3'h7: data_out_r <= 8'h31; endcase end always @(posedge clkin) begin if(reg_we_rising) begin case(reg_addr_r[3]) 3'h0: addr_out_r[7:0] <= reg_data_in; 3'h1: addr_out_r[15:8] <= reg_data_in; 3'h2: addr_out_r[23:16] <= reg_data_in; 3'h3: begin addr_out_r[31:24] <= reg_data_in; data_start_r <= 1'b1; data_busy_r <= 1'b1; end 3'h4: begin track_out_r[7:0] <= reg_data_in; end 3'h5: begin track_out_r[15:8] <= reg_data_in; audio_start_r <= 1'b1; audio_busy_r <= 1'b1; end 3'h6: begin volume_r <= reg_data_in; volume_start_r <= 1'b1; end 3'h7: begin if(!audio_busy_r) begin audio_ctrl_r <= reg_data_in[1:0]; ctrl_start_r <= 1'b1; end end endcase end else if (status_reset_en) begin audio_busy_r <= (audio_busy_r | status_set_bits[5]) & ~status_reset_bits[5]; if(status_reset_bits[5]) audio_start_r <= 1'b0; data_busy_r <= (data_busy_r | status_set_bits[4]) & ~status_reset_bits[4]; if(status_reset_bits[4]) data_start_r <= 1'b0; // volume_start_r <= (volume_start_r | status_set_bits[3]) & ~status_reset_bits[3]; audio_status_r <= (audio_status_r | status_set_bits[2:1]) & ~status_reset_bits[2:1]; ctrl_start_r <= (ctrl_start_r | status_set_bits[0]) & ~status_reset_bits[0]; end else begin volume_start_r <= 1'b0; end end always @(posedge clkin) begin if(msu_address_ext_write_rising) msu_address_r <= msu_address_ext; else if(reg_addr_r[3] == 3'h1 && reg_oe_rising) begin msu_address_r <= msu_address_r + 1; end end endmodule