-
Notifications
You must be signed in to change notification settings - Fork 4
/
timer.sv
73 lines (65 loc) · 1.6 KB
/
timer.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// timer
`timescale 1ns / 1ps
// Programmable timer peripheral
module timer
import config_pkg::*;
import decoder_pkg::*;
(
input logic clk,
input logic reset,
input logic csr_enable,
input CsrAddrT csr_addr,
input csr_op_t csr_op,
input r rs1_zimm,
input word rs1_data,
input TimerT ext_data,
input logic ext_write_enable,
input logic interrupt_clear,
input vcsr_width_t vcsr_width,
input vcsr_offset_t vcsr_offset,
input CsrAddrT vcsr_addr,
output logic interrupt_set,
output word csr_direct_out,
output word csr_out
);
TimerCounterT counter;
TimerT timer;
csr #(
.CsrWidth(TimerTWidth),
.Addr(TimerAddr)
) csr_timer (
// in
.clk,
.reset,
.csr_enable,
.csr_addr,
.csr_op,
.rs1_zimm,
.rs1_data,
.vcsr_width,
.vcsr_offset,
.vcsr_addr,
// external access for side effects
.ext_data,
.ext_write_enable,
// out
.direct_out(csr_direct_out),
.out(csr_out)
);
assign timer = csr_timer.data;
always_ff @(posedge clk) begin
if (reset) begin
counter <= 0;
interrupt_set <= 0;
end else begin
if ((TimerCounterT'(timer.counter_top) << timer.prescaler) == counter) begin
$display("counter top: counter = %d", counter);
counter <= 0;
interrupt_set <= 1;
end else begin
if (interrupt_clear) interrupt_set <= 0;
counter <= counter + 1;
end
end
end
endmodule