hw/ip/rv_plic/rtl/rv_plic_gateway.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: // RISC-V Platform-Level Interrupt Gateways module
   6: 
   7: module rv_plic_gateway #(
   8:   parameter int N_SOURCE = 32
   9: ) (
  10:   input clk_i,
  11:   input rst_ni,
  12: 
  13:   input [N_SOURCE-1:0] src,
  14:   input [N_SOURCE-1:0] le,      // Level0 Edge1
  15: 
  16:   input [N_SOURCE-1:0] claim, // $onehot0(claim)
  17:   input [N_SOURCE-1:0] complete, // $onehot0(complete)
  18: 
  19:   output logic [N_SOURCE-1:0] ip
  20: );
  21: 
  22:   logic [N_SOURCE-1:0] ia;    // Interrupt Active
  23: 
  24:   logic [N_SOURCE-1:0] set;   // Set: (le) ? src & ~src_d : src ;
  25:   logic [N_SOURCE-1:0] src_d;
  26: 
  27:   always_ff @(posedge clk_i or negedge rst_ni) begin
  28:     if (!rst_ni) src_d <= '0;
  29:     else         src_d <= src;
  30:   end
  31: 
  32:   always_comb begin
  33:     for (int i = 0 ; i < N_SOURCE; i++) begin
  34:       set[i] = (le[i]) ? src[i] & ~src_d[i] : src[i] ;
  35:     end
  36:   end
  37: 
  38:   // Interrupt pending is set by source (depends on le), cleared by claim.
  39:   // Until interrupt is claimed, set doesn't affect ip.
  40:   // RISC-V PLIC spec mentioned it can have counter for edge triggered
  41:   // But skipped the feature as counter consumes substantial logic size.
  42:   always_ff @(posedge clk_i or negedge rst_ni) begin
  43:     if (!rst_ni) begin
  44:       ip <= '0;
  45:     end else begin
  46:       ip <= (ip | (set & ~ia & ~ip)) & (~(ip & claim));
  47:     end
  48:   end
  49: 
  50:   // Interrupt active is to control ip. If ip is set then until completed
  51:   // by target, ip shouldn't be set by source even claim can clear ip.
  52:   // ia can be cleared only when ia was set. If `set` and `complete` happen
  53:   // at the same time, always `set` wins.
  54:   always_ff @(posedge clk_i or negedge rst_ni) begin
  55:     if (!rst_ni) begin
  56:       ia <= '0;
  57:     end else begin
  58:       ia <= (ia | (set & ~ia)) & (~(ia & complete & ~ip));
  59:     end
  60:   end
  61: 
  62: endmodule
  63: