X-Git-Url: http://git.joshuawise.com/fpgaboy.git/blobdiff_plain/dadf7990cbca24581bbb3c036df717dd59bdea41..06ad3a30038ac8ca45dd7b0c34213c0c8335c17c:/Timer.v diff --git a/Timer.v b/Timer.v new file mode 100644 index 0000000..0481614 --- /dev/null +++ b/Timer.v @@ -0,0 +1,65 @@ +`define ADDR_DIV 16'hFF04 +`define ADDR_TIMA 16'hFF05 +`define ADDR_TMA 16'hFF06 +`define ADDR_TAC 16'hFF07 + +module Timer( + input clk, + input wr, + input rd, + input [15:0] addr, + inout [7:0] data, + output reg irq); + + reg [7:0] tima = 0, tma = 0, tac = 0, div = 0; + reg ovf = 0; + reg [9:0] clkdv; + + wire is_tima = addr == `ADDR_TIMA; + wire is_tma = addr == `ADDR_TMA; + wire is_tac = addr == `ADDR_TAC; + + assign data = rd ? + is_tima ? tima : + is_tma ? tma : + is_tac ? tac : + 8'bzzzzzzzz : + 8'bzzzzzzzz; + + wire cksel = tac[2] ? + (tac[1:0] == 2'b00) ? (clkdv == 10'b0) : + (tac[1:0] == 2'b01) ? (clkdv[3:0] == 4'b0) : + (tac[1:0] == 2'b10) ? (clkdv[5:0] == 6'b0) : + (clkdv[7:0] == 8'b0) : + 0; + + always @ (negedge clk) + begin + if(wr) begin + case(addr) + `ADDR_DIV: div <= 8'b0; + `ADDR_TIMA: tima <= data; + `ADDR_TMA: tma <= data; + `ADDR_TAC: tac <= data; + endcase + end + else begin + if(ovf) begin + tima <= tma; + ovf <= 0; + irq <= 1; + end + else begin + if(cksel) + {ovf,tima} <= {1'b0,tima} + 1; + if(irq) + irq <= 0; + end + + if(clkdv[7:0] == 8'b0) + div <= div + 1; + end + clkdv <= clkdv + 1; + end + +endmodule