blob: 5da2b6886c322c2b8b480c1527c538caa367d217 [file] [log] [blame]
module timer (
input i_clk,
input i_rst,
output reg irq,
input [23:0] wb_adr,
input wb_cyc,
input wb_stb,
output wb_ack,
input wb_we,
input [15:0] wb_i_dat,
output [15:0] wb_o_dat
);
reg [15:0] timer_cnt;
reg [15:0] pre_div_cnt;
reg [3:0] clk_div;
reg [15:0] reset_val;
always @(posedge i_clk) begin
if(i_rst) begin
timer_cnt <= 16'b0;
pre_div_cnt <= 16'b0;
end else if(wb_cyc & wb_stb & wb_we & (wb_adr == 2'b0)) begin
timer_cnt <= wb_i_dat;
end else begin
pre_div_cnt <= pre_div_cnt + 16'b1;
if(pre_div_cnt >= (1<<clk_div) - 16'b1) begin
timer_cnt <= timer_cnt + 16'b1;
pre_div_cnt <= 16'b0;
if(timer_cnt == 16'hffff)
timer_cnt <= reset_val;
end
end
end
always @(posedge i_clk) begin
irq <= (timer_cnt == 16'hffff);
end
always @(posedge i_clk) begin
if(i_rst) begin
reset_val <= 16'b0;
clk_div <= 4'b0;
end else if(wb_cyc & wb_stb & wb_we & (wb_adr == 2'b1)) begin
clk_div <= wb_i_dat[3:0];
end else if(wb_cyc & wb_stb & wb_we & (wb_adr == 2'b10)) begin
reset_val <= wb_i_dat;
end
end
assign wb_o_dat = timer_cnt;
assign wb_ack = (wb_cyc & wb_stb);
endmodule