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