`define ADDR_NR10 16'hFF10 `define ADDR_NR11 16'hFF11 `define ADDR_NR12 16'hFF12 `define ADDR_NR13 16'hFF13 `define ADDR_NR14 16'hFF14 module Sound1( input core_clk, input wr, input rd, input [15:0] addr, inout [7:0] data, input cntclk, input lenclk, input en, output [3:0] snd_data ); /* can be optimized as register file */ reg [7:0] nr10 = 0, nr11 = 0, nr12 = 0, nr13 = 0, nr14 = 0; reg [10:0] counter = 0; reg [4:0] lencnt = 0; reg [3:0] delta = 4'b1111; reg toggle = 0; reg [3:0] snd_out = 0; reg rdlatch; reg [15:0] addrlatch; assign snd_data = en ? snd_out : 0; assign data = rdlatch ? addrlatch == `ADDR_NR10 ? nr10 : addrlatch == `ADDR_NR11 ? nr11 : addrlatch == `ADDR_NR12 ? nr12 : addrlatch == `ADDR_NR13 ? nr13 : addrlatch == `ADDR_NR14 ? nr14 : 8'bzzzzzzzz : 8'bzzzzzzzz; always @ (posedge core_clk) begin rdlatch <= rd; addrlatch <= addr; if(en && wr) begin case(addr) `ADDR_NR10: nr10 <= data; `ADDR_NR11: nr11 <= data; `ADDR_NR12: nr12 <= data; `ADDR_NR13: nr13 <= data; `ADDR_NR14: nr14 <= data; endcase end else if(!en) begin nr10 <= 8'h80; nr11 <= 8'h3F; nr12 <= 8'h00; nr13 <= 8'hFF; nr14 <= 8'hBF; end end always @ (posedge cntclk) begin if(counter) counter <= counter - 1; else begin counter <= ~{nr14[2:0],nr13} + 1; /* possible A */ toggle <= ~toggle; end snd_out <= toggle ? delta : 0; /* Leave it to Dennis. */ end always @ (posedge lenclk) begin if(lencnt) lencnt <= lencnt - 1; /* possible A */ else lencnt <= ~nr11[4:0] + 1; end endmodule