// part of NeoGS project (c) 2007-2008 NedoPC
//
// interrupt controller for Z80

module timer(

	input  wire clk_24mhz,
	input  wire clk_z80,

	input  wire [2:0] rate,     // z80 clocked
	// 3'b000 -- 37500/1
	// 3'b001 -- 37500/2
	// 3'b010 -- 37500/4
	// 3'b011 -- 37500/8
	// 3'b100 -- 37500/16
	// 3'b101 -- 37500/64
	// 3'b110 -- 37500/256
	// 3'b111 -- 37500/1024
	
	output reg  int_stb
);
	reg [ 2:0] ctr5;
	reg [16:0] ctr128k;

	reg ctrsel;



	reg int_sync1,int_sync2,int_sync3;



	always @(posedge clk_24mhz)
	begin
		if( !ctr5[2] )
			ctr5 <= ctr5 + 3'd1;
		else
			ctr5 <= 3'd0;
	end
	//
	initial
		ctr128k = 'd0;
	always @(posedge clk_24mhz)
	begin
		if( ctr5[2] )
			ctr128k <= ctr128k + 17'd1;
	end


	always @*
	case( rate )
		3'b000: ctrsel = ctr128k[6];
		3'b001: ctrsel = ctr128k[7];
		3'b010: ctrsel = ctr128k[8];
		3'b011: ctrsel = ctr128k[9];
		3'b100: ctrsel = ctr128k[10];
		3'b101: ctrsel = ctr128k[12];
		3'b110: ctrsel = ctr128k[14];
		3'b111: ctrsel = ctr128k[16];
	endcase





	// generate interrupt signal in clk_z80 domain
	always @(posedge clk_z80)
	begin
		int_sync3 <= int_sync2;
		int_sync2 <= int_sync1;
		int_sync1 <= ctrsel;
	end

	always @(posedge clk_z80)
	if( !int_sync2 && int_sync3 )
		int_stb <= 1'b1;
	else
		int_stb <= 1'b0;

endmodule

