Add interrupt based timer and test code
This commit is contained in:
@@ -6,8 +6,8 @@ module timer
|
||||
output logic [7:0] o_data,
|
||||
input cs,
|
||||
input rwb,
|
||||
input [2:0] addr,
|
||||
output logic irq
|
||||
input [1:0] addr,
|
||||
output logic irqb
|
||||
);
|
||||
|
||||
//new idea for timer:
|
||||
@@ -15,43 +15,88 @@ module timer
|
||||
//it can either cause an interrupt or not.
|
||||
//if you want it to do both, add another timer.
|
||||
|
||||
/*
|
||||
Addr Read Write
|
||||
0 Counter Low Latch Low
|
||||
1 Counter High Latch High
|
||||
2 Divisor Divisor
|
||||
3 Status Control
|
||||
*/
|
||||
|
||||
logic [15:0] timer_latch, timer_counter;
|
||||
|
||||
//control register
|
||||
// bit 0: Enable interrupts
|
||||
// bit 1: Enable 1 shot mode
|
||||
|
||||
//by default it just starts counting up
|
||||
//writing to latch low starts the timer
|
||||
|
||||
logic [7:0] divisor, status, control;
|
||||
|
||||
logic count_en;
|
||||
|
||||
assign status[0] = count_en;
|
||||
|
||||
logic [15:0] pulsecount;
|
||||
|
||||
//I think this should be negedge so that writes go through
|
||||
always @(negedge clk) begin
|
||||
if (reset) begin
|
||||
count_en = '0;
|
||||
timer_counter <= '0;
|
||||
pulsecount <= '0;
|
||||
timer_latch <= '0;
|
||||
timer_latch <= '1;
|
||||
divisor <= '0;
|
||||
status <= '0;
|
||||
control <= '0;
|
||||
irq <= '1;
|
||||
irqb <= '1;
|
||||
end else begin
|
||||
|
||||
if (pulsecount[15:8] == divisor) begin
|
||||
timer_counter <= timer_counter + 16'b1;
|
||||
pulsecount <= '0;
|
||||
end else begin
|
||||
pulsecount <= pulsecount + 16'b1;
|
||||
if (count_en) begin
|
||||
if (pulsecount[15:8] == divisor) begin
|
||||
timer_counter <= timer_counter + 16'b1;
|
||||
pulsecount <= '0;
|
||||
end else begin
|
||||
pulsecount <= pulsecount + 16'b1;
|
||||
end
|
||||
end
|
||||
|
||||
if (timer_counter == timer_latch) begin
|
||||
// if interrupts are enabled
|
||||
if (control[0]) begin
|
||||
irqb <= '0;
|
||||
end
|
||||
|
||||
// if oneshot mode is enabled
|
||||
if (control[1]) begin
|
||||
count_en <= '0;
|
||||
end else begin
|
||||
timer_counter <= '0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if (cs & rwb) begin
|
||||
irqb <= '1;
|
||||
end
|
||||
|
||||
if (cs & ~rwb) begin
|
||||
case (addr)
|
||||
3'h5: begin
|
||||
2'h0: begin
|
||||
count_en <= '1;
|
||||
timer_latch[7:0] <= i_data;
|
||||
end
|
||||
|
||||
2'h1: begin
|
||||
timer_latch[15:8] <= i_data;
|
||||
end
|
||||
|
||||
2'h2: begin
|
||||
divisor <= i_data;
|
||||
end
|
||||
end
|
||||
|
||||
2'h3: begin
|
||||
control <= i_data;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
@@ -62,36 +107,20 @@ always_comb begin
|
||||
o_data = '0;
|
||||
|
||||
unique case (addr)
|
||||
3'h0: begin
|
||||
2'h0: begin
|
||||
o_data = timer_counter[7:0];
|
||||
end
|
||||
|
||||
3'h1: begin
|
||||
2'h1: begin
|
||||
o_data = timer_counter[15:8];
|
||||
end
|
||||
|
||||
3'h2: begin
|
||||
|
||||
2'h2: begin
|
||||
o_data = divisor;
|
||||
end
|
||||
|
||||
3'h3: begin
|
||||
|
||||
end
|
||||
|
||||
3'h4: begin
|
||||
|
||||
end
|
||||
|
||||
3'h5: begin
|
||||
|
||||
end
|
||||
|
||||
3'h6: begin
|
||||
|
||||
end
|
||||
|
||||
3'h7: begin
|
||||
|
||||
2'h3: begin
|
||||
o_data = status;
|
||||
end
|
||||
|
||||
endcase
|
||||
|
||||
Reference in New Issue
Block a user