../src/lowrisc_dv_pins_if_0/pins_if.sv Cov: 94.4%

   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: // Interface: pins_if
   6: // Description: Pin interface for driving and sampling individual pins such as interrupts, alerts
   7: // and gpios.
   8: `ifndef SYNTHESIS
   9: 
  10: interface pins_if #(
  11:   parameter int Width = 1
  12: ) (
  13:   inout [Width-1:0] pins
  14: );
  15: 
  16: 
  17:   logic [Width-1:0] pins_o;       // value to be driven out
  18:   wire  [Width-1:0] pins_int;     // value of pin using internal pull-up / pull-down
  19:   bit   [Width-1:0] pins_oe = '0; // output enable
  20:   bit   [Width-1:0] pins_pd = '0; // pull down enable
  21:   bit   [Width-1:0] pins_pu = '0; // pull up enable
  22: 
  23:   // function to set pin output enable for specific pin (useful for single pin interface)
  24:   function automatic void drive_en_pin(int idx = 0, bit val);
  25:     pins_oe[idx] = val;
  26:   endfunction
  27: 
  28:   // function to set pin output enable for all pins
  29:   function automatic void drive_en(bit [Width-1:0] val);
  30:     pins_oe = val;
  31:   endfunction
  32: 
  33:   // function to drive a specific pin with a value (useful for single pin interface)
  34:   function automatic void drive_pin(int idx = 0, logic val);
  35:     pins_oe[idx] = 1'b1;
  36:     pins_o[idx] = val;
  37:   endfunction // drive_pin
  38: 
  39:   // function to drive all pins
  40:   function automatic void drive(logic [Width-1:0] val);
  41:     pins_oe = {Width{1'b1}};
  42:     pins_o = val;
  43:   endfunction // drive
  44: 
  45:   // function to drive all pull down values
  46:   function automatic void set_pulldown_en(bit [Width-1:0] val);
  47:     pins_pd = val;
  48:   endfunction // set_pulldown_en
  49: 
  50:   // function to drive all pull up values
  51:   function automatic void set_pullup_en(bit [Width-1:0] val);
  52:     pins_pu = val;
  53:   endfunction // set_pullup_en
  54: 
  55:   // function to drive the pull down value on a specific pin
  56:   function automatic void set_pulldown_en_pin(int idx = 0, bit val);
  57:     pins_pd[idx] = val;
  58:   endfunction // set_pulldown_en_pin
  59: 
  60:   // function to drive the pull up value on a specific pin
  61:   function automatic void set_pullup_en_pin(int idx = 0, bit val);
  62:     pins_pu[idx] = val;
  63:   endfunction // set_pullup_en_pin
  64: 
  65:   // function to sample a specific pin (useful for single pin interface)
  66:   function automatic logic sample_pin(int idx = 0);
  67:     return pins[idx];
  68:   endfunction
  69: 
  70:   // function to sample all pins
  71:   function automatic logic [Width-1:0] sample();
  72:     return pins;
  73:   endfunction
  74: 
  75:   // make connections
  76:   generate
  77:     for (genvar i = 0; i < Width; i++) begin : each_pin
  78:       assign pins_int[i] = pins_pd[i] ? 1'b0 :
  79:                            pins_pu[i] ? 1'b1 : 1'bz;
  80:       // If output enable is 1, strong driver assigns pin to 'value to be driven out';
  81:       // the external strong driver can still affect pin, if exists.
  82:       // Else if output enable is 0, weak pullup or pulldown is applied to pin.
  83:       // By doing this, we make sure that weak pullup or pulldown does not override
  84:       // any 'x' value on pin, that may result due to conflicting values
  85:       // between 'value to be driven out' and the external driver's value.
  86:       assign pins[i] = pins_oe[i] ? pins_o[i] : 1'bz;
  87: `ifdef VERILATOR
  88:       assign pins[i] = ~pins_oe[i] ? pins_int[i] : 1'bz;
  89: `else
  90:       assign (pull0, pull1) pins[i] = ~pins_oe[i] ? pins_int[i] : 1'bz;
  91: `endif
  92:     end
  93:   endgenerate
  94: 
  95: endinterface
  96: `endif
  97: