`define ADDR_NR50 16'hFF24 `define ADDR_NR51 16'hFF25 `define ADDR_NR52 16'hFF26 module Soundcore( input core_clk, input wr, input rd, input [15:0] addr, inout [7:0] data, output reg snd_data_l, output reg snd_data_r ); reg [7:0] nr50 = 8'h00, nr51 = 8'h00, nr52 = 8'hF0; reg [3:0] pwmcnt = 4'b0000; reg [4:0] cntclk = 5'b00000; reg [13:0] lenclk; wire [3:0] sndout1,sndout2,sndout3,sndout4; wire [3:0] right_snd = (nr51[0] ? sndout1 : 4'b0) + (nr51[1] ? sndout2 : 4'b0) + (nr51[2] ? sndout3 : 4'b0) + (nr51[3] ? sndout4 : 4'b0); wire [3:0] left_snd = (nr51[4] ? sndout1 : 4'b0) + (nr51[5] ? sndout2 : 4'b0) + (nr51[6] ? sndout3 : 4'b0) + (nr51[7] ? sndout4 : 4'b0); assign sndout3 = 0; assign sndout4 = 0; reg rdlatch; reg [15:0] addrlatch; assign data = rdlatch ? addrlatch == `ADDR_NR50 ? nr50 : addrlatch == `ADDR_NR51 ? nr51 : addrlatch == `ADDR_NR52 ? nr52 : 8'bzzzzzzzz : 8'bzzzzzzzz; always @ (posedge core_clk) begin rdlatch <= rd; addrlatch <= addr; if(wr) begin case(addr) `ADDR_NR50: nr50 <= data; `ADDR_NR51: nr51 <= data; `ADDR_NR52: nr52 <= {data[7],7'b1111111}; endcase end cntclk <= cntclk + 1; lenclk <= lenclk + 1; pwmcnt <= pwmcnt + 1; snd_data_l <= (pwmcnt <= left_snd) ? 1 : 0; snd_data_r <= (pwmcnt <= right_snd) ? 1 : 0; end Sound1 s1( .core_clk(core_clk), .wr(wr), .rd(rd), .addr(addr), .data(data), .cntclk(cntclk[4]), .lenclk(lenclk[13]), .en(nr52[7]), .snd_data(sndout1) ); Sound2 s2( .core_clk(core_clk), .wr(wr), .rd(rd), .addr(addr), .data(data), .cntclk(cntclk[4]), .lenclk(lenclk[13]), .en(nr52[7]), .snd_data(sndout2) ); endmodule