Sound: Leave it to Dennis.
[fpgaboy.git] / Sound2.v
1 `define ADDR_NR21 16'hFF16
2 `define ADDR_NR22 16'hFF17
3 `define ADDR_NR23 16'hFF18
4 `define ADDR_NR24 16'hFF19
5
6 module Sound2(
7         input core_clk,
8         input wr,
9         input rd,
10         input [15:0] addr,
11         inout [7:0] data,
12         input cntclk,
13         input lenclk,
14         input en,
15         output [3:0] snd_data
16         );
17
18         /* can be optimized as register file */
19         reg [7:0] nr21 = 0, nr22 = 0, nr23 = 0, nr24 = 0;
20         reg [10:0] counter = 0;
21         reg [4:0] lencnt = 0;
22         reg [3:0] delta = 4'b1111;
23         reg [2:0] dutycnt;
24         reg [3:0] snd_out = 0;
25
26         assign snd_data = en ? snd_out : 0;
27
28         assign data = rd ?
29                          addr == `ADDR_NR21 ? nr21 :
30                          addr == `ADDR_NR22 ? nr22 :
31                          addr == `ADDR_NR23 ? nr23 :
32                          addr == `ADDR_NR24 ? nr24 : 8'bzzzzzzzz
33                       : 8'bzzzzzzzz;
34
35         always @ (negedge core_clk) begin
36                 if(en && wr) begin
37                         case(addr)
38                         `ADDR_NR21: nr21 <= data;
39                         `ADDR_NR22: nr22 <= data;
40                         `ADDR_NR23: nr23 <= data;
41                         `ADDR_NR24: nr24 <= data;
42                         endcase
43                 end
44                 else if(!en) begin
45                         nr21 <= 8'h3F;
46                         nr22 <= 8'h00;
47                         nr23 <= 8'hFF;
48                         nr24 <= 8'hBF;
49                 end
50         end
51
52         always @ (posedge cntclk) begin
53                 if(counter)
54                         counter <= counter - 1;
55                 else begin
56                         counter <= ~{nr24[2:0],nr23} + 1;  /* possible A */
57                         dutycnt <= dutycnt + 1;
58                 end
59
60                 case (nr21[7:6])
61                 2'b00: snd_out <= dutycnt ? 0 : delta;   /* probable A */
62                 2'b01: snd_out <= (dutycnt[2:1] == 2'b0) ? delta : 0;
63                 2'b10: snd_out <= dutycnt[2] ? delta : 0;
64                 2'b11: snd_out <= (dutycnt[2:1] == 2'b0) ? 0 : delta;
65                 endcase
66         end
67
68         always @ (posedge lenclk) begin
69                 if(lencnt)
70                         lencnt <= lencnt - 1;            /* possible A */
71                 else
72                         lencnt <= ~nr21[4:0] + 1;
73         end
74
75 endmodule
This page took 0.021866 seconds and 4 git commands to generate.