../src/lowrisc_ip_rv_timer_0.1/rtl/rv_timer.sv Cov: 100%
1: // Copyright lowRISC contributors.
2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3: // SPDX-License-Identifier: Apache-2.0
4: //
5:
6:
7: `include "prim_assert.sv"
8:
9: module rv_timer (
10: input clk_i,
11: input rst_ni,
12:
13: input tlul_pkg::tl_h2d_t tl_i,
14: output tlul_pkg::tl_d2h_t tl_o,
15:
16: output logic intr_timer_expired_0_0_o
17: );
18:
19: localparam int N_HARTS = 1;
20: localparam int N_TIMERS = 1;
21:
22: import rv_timer_reg_pkg::*;
23:
24: rv_timer_reg2hw_t reg2hw;
25: rv_timer_hw2reg_t hw2reg;
26:
27: logic [N_HARTS-1:0] active;
28:
29: logic [11:0] prescaler [N_HARTS];
30: logic [7:0] step [N_HARTS];
31:
32: logic [N_HARTS-1:0] tick;
33:
34: logic [63:0] mtime_d [N_HARTS];
35: logic [63:0] mtime [N_HARTS];
36: logic [63:0] mtimecmp [N_HARTS][N_TIMERS]; // Only [harts][0] is connected to mtimecmp CSRs
37: logic mtimecmp_update [N_HARTS][N_TIMERS];
38:
39: logic [N_HARTS*N_TIMERS-1:0] intr_timer_set;
40: logic [N_HARTS*N_TIMERS-1:0] intr_timer_en;
41: logic [N_HARTS*N_TIMERS-1:0] intr_timer_test_q;
42: logic [N_HARTS-1:0] intr_timer_test_qe;
43: logic [N_HARTS*N_TIMERS-1:0] intr_timer_state_q;
44: logic [N_HARTS-1:0] intr_timer_state_de;
45: logic [N_HARTS*N_TIMERS-1:0] intr_timer_state_d;
46:
47: logic [N_HARTS*N_TIMERS-1:0] intr_out;
48:
49: /////////////////////////////////////////////////
50: // Connecting register interface to the signal //
51: /////////////////////////////////////////////////
52:
53: // Once reggen supports nested multireg, the following can be automated. For the moment, it must
54: // be connected manually.
55: assign active[0] = reg2hw.ctrl[0].q;
56: assign prescaler = '{reg2hw.cfg0.prescale.q};
57: assign step = '{reg2hw.cfg0.step.q};
58:
59: assign hw2reg.timer_v_upper0.de = tick[0];
60: assign hw2reg.timer_v_lower0.de = tick[0];
61: assign hw2reg.timer_v_upper0.d = mtime_d[0][63:32];
62: assign hw2reg.timer_v_lower0.d = mtime_d[0][31: 0];
63: assign mtime[0] = {reg2hw.timer_v_upper0.q, reg2hw.timer_v_lower0.q};
64: assign mtimecmp = '{'{{reg2hw.compare_upper0_0.q,reg2hw.compare_lower0_0.q}}};
65: assign mtimecmp_update[0][0] = reg2hw.compare_upper0_0.qe | reg2hw.compare_lower0_0.qe;
66:
67: assign intr_timer_expired_0_0_o = intr_out[0];
68: assign intr_timer_en = reg2hw.intr_enable0[0].q;
69: assign intr_timer_state_q = reg2hw.intr_state0[0].q;
70: assign intr_timer_test_q = reg2hw.intr_test0[0].q;
71: assign intr_timer_test_qe = reg2hw.intr_test0[0].qe;
72: assign hw2reg.intr_state0[0].de = intr_timer_state_de | mtimecmp_update[0][0];
73: assign hw2reg.intr_state0[0].d = intr_timer_state_d & ~mtimecmp_update[0][0];
74:
75:
76: for (genvar h = 0 ; h < N_HARTS ; h++) begin : gen_harts
77: prim_intr_hw #(
78: .Width(N_TIMERS)
79: ) u_intr_hw (
80: .event_intr_i (intr_timer_set),
81:
82: .reg2hw_intr_enable_q_i (intr_timer_en[h*N_TIMERS+:N_TIMERS]),
83: .reg2hw_intr_test_q_i (intr_timer_test_q[h*N_TIMERS+:N_TIMERS]),
84: .reg2hw_intr_test_qe_i (intr_timer_test_qe[h]),
85: .reg2hw_intr_state_q_i (intr_timer_state_q[h*N_TIMERS+:N_TIMERS]),
86: .hw2reg_intr_state_de_o (intr_timer_state_de),
87: .hw2reg_intr_state_d_o (intr_timer_state_d[h*N_TIMERS+:N_TIMERS]),
88:
89: .intr_o (intr_out[h*N_TIMERS+:N_TIMERS])
90: );
91:
92: timer_core #(
93: .N (N_TIMERS)
94: ) u_core (
95: .clk_i,
96: .rst_ni,
97:
98: .active (active[h]),
99: .prescaler (prescaler[h]),
100: .step (step[h]),
101:
102: .tick (tick[h]),
103:
104: .mtime_d (mtime_d[h]),
105: .mtime (mtime[h]),
106: .mtimecmp (mtimecmp[h]),
107:
108: .intr (intr_timer_set[h*N_TIMERS+:N_TIMERS])
109: );
110: end : gen_harts
111:
112: // Register module
113: rv_timer_reg_top u_reg (
114: .clk_i,
115: .rst_ni,
116:
117: .tl_i,
118: .tl_o,
119:
120: .reg2hw,
121: .hw2reg,
122:
123: .devmode_i (1'b1)
124: );
125:
126: ////////////////
127: // Assertions //
128: ////////////////
129: `ASSERT_KNOWN(TlODValidKnown, tl_o.d_valid)
130: `ASSERT_KNOWN(TlOAReadyKnown, tl_o.a_ready)
131: `ASSERT_KNOWN(IntrTimerExpired00Known, intr_timer_expired_0_0_o)
132:
133: endmodule
134: