../src/lowrisc_prim_all_0.1/rtl/prim_subreg.sv Cov: 72.1%

   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: // Register slice conforming to Comportibility guide.
   6: 
   7: module prim_subreg #(
   8:   parameter int            DW       = 32  ,
   9:   parameter                SWACCESS = "RW",  // {RW, RO, WO, W1C, W1S, W0C, RC}
  10:   parameter logic [DW-1:0] RESVAL   = '0     // Reset value
  11: ) (
  12:   input clk_i,
  13:   input rst_ni,
  14: 
  15:   // From SW: valid for RW, WO, W1C, W1S, W0C, RC
  16:   // In case of RC, Top connects Read Pulse to we
  17:   input          we,
  18:   input [DW-1:0] wd,
  19: 
  20:   // From HW: valid for HRW, HWO
  21:   input          de,
  22:   input [DW-1:0] d,
  23: 
  24:   // output to HW and Reg Read
  25:   output logic          qe,
  26:   output logic [DW-1:0] q,
  27:   output logic [DW-1:0] qs
  28: );
  29: 
  30:   logic          wr_en ;
  31:   logic [DW-1:0] wr_data;
  32: 
  33:   if ((SWACCESS == "RW") || (SWACCESS == "WO")) begin : gen_w
  34:     assign wr_en   = we | de ;
  35:     assign wr_data = (we == 1'b1) ? wd : d ; // SW higher priority
  36:   end else if (SWACCESS == "RO") begin : gen_ro
  37:     // Unused we, wd
  38:     assign wr_en   = de ;
  39:     assign wr_data = d  ;
  40:   end else if (SWACCESS == "W1S") begin : gen_w1s
  41:     // If SWACCESS is W1S, then assume hw tries to clear.
  42:     // So, give a chance HW to clear when SW tries to set.
  43:     // If both try to set/clr at the same bit pos, SW wins.
  44:     assign wr_en   = we | de ;
  45:     assign wr_data = (de ? d : q) | (we ? wd : '0);
  46:   end else if (SWACCESS == "W1C") begin : gen_w1c
  47:     // If SWACCESS is W1C, then assume hw tries to set.
  48:     // So, give a chance HW to set when SW tries to clear.
  49:     // If both try to set/clr at the same bit pos, SW wins.
  50:     assign wr_en   = we | de ;
  51:     assign wr_data = (de ? d : q) & (we ? ~wd : '1);
  52:   end else if (SWACCESS == "W0C") begin : gen_w0c
  53:     assign wr_en   = we | de ;
  54:     assign wr_data = (de ? d : q) & (we ? wd : '1);
  55:   end else if (SWACCESS == "RC") begin : gen_rc
  56:     // This swtype is not recommended but exists for compatibility.
  57:     // WARN: we signal is actually read signal not write enable.
  58:     assign wr_en  = we | de ;
  59:     assign wr_data = (de ? d : q) & (we ? '0 : '1);
  60:   end else begin : gen_hw
  61:     assign wr_en   = de ;
  62:     assign wr_data = d  ;
  63:   end
  64: 
  65:   always_ff @(posedge clk_i or negedge rst_ni) begin
  66:     if (!rst_ni) qe <= 1'b0;
  67:     else        qe <= we  ;
  68:   end
  69: 
  70:   always_ff @(posedge clk_i or negedge rst_ni) begin
  71:     if (!rst_ni)     q <= RESVAL ;
  72:     else if (wr_en) q <= wr_data;
  73:   end
  74:   assign qs = q;
  75: 
  76: endmodule
  77: