../src/lowrisc_dv_dpi_gpiodpi_0.1/gpiodpi.sv Cov: 75.6%

   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: module gpiodpi
   6: #(
   7:   parameter string NAME = "gpio0",
   8:   parameter        N_GPIO = 32
   9: )(
  10:   input  logic              clk_i,
  11:   input  logic              rst_ni,
  12: 
  13:   output logic [N_GPIO-1:0] gpio_p2d,
  14:   input  logic [N_GPIO-1:0] gpio_d2p,
  15:   input  logic [N_GPIO-1:0] gpio_en_d2p
  16: );
  17:    import "DPI-C" function
  18:      chandle gpiodpi_create(input string name, input int n_bits);
  19: 
  20:    import "DPI-C" function
  21:      void gpiodpi_device_to_host(input chandle ctx, input [N_GPIO-1:0] gpio_d2p,
  22:                                  input [N_GPIO-1:0] gpio_en_d2p);
  23: 
  24:    import "DPI-C" function
  25:      void gpiodpi_close(input chandle ctx);
  26: 
  27:    import "DPI-C" function
  28:      int gpiodpi_host_to_device_tick(input chandle ctx,
  29:                                      input [N_GPIO-1:0] gpio_en_d2p);
  30: 
  31:    chandle ctx;
  32: 
  33:    initial begin
  34:      ctx = gpiodpi_create(NAME, N_GPIO);
  35:    end
  36: 
  37:    final begin
  38:      gpiodpi_close(ctx);
  39:    end
  40: 
  41:    logic [N_GPIO-1:0] gpio_d2p_r;
  42:    always_ff @(posedge clk_i) begin
  43:      gpio_d2p_r <= gpio_d2p;
  44:      if (gpio_d2p_r != gpio_d2p) begin
  45:        gpiodpi_device_to_host(ctx, gpio_d2p, gpio_en_d2p);
  46:      end
  47:    end
  48: 
  49:    logic gpio_write_pulse;
  50: 
  51:    always_ff @(posedge clk_i or negedge rst_ni) begin
  52:      if (!rst_ni) begin
  53:        gpio_p2d <= '0; // default value
  54:      end else if (gpio_write_pulse) begin
  55:        gpio_p2d <= gpiodpi_host_to_device_tick(ctx, gpio_en_d2p);
  56:      end
  57:    end
  58: 
  59:    // gpiodpio_host_to_device_tick() will be called every MAX_COUNT
  60:    // clock posedges; this should be kept reasonably high, since each
  61:    // tick call will perform at least one syscall.
  62:    localparam MAX_COUNT = 2048;
  63:    logic [$clog2(MAX_COUNT)-1:0] counter;
  64: 
  65:    assign gpio_write_pulse = counter == MAX_COUNT -1;
  66: 
  67:    always_ff @(posedge clk_i or negedge rst_ni) begin
  68:      if (!rst_ni) begin
  69:        counter <= '0;
  70:      end else if (gpio_write_pulse) begin
  71:        counter <= '0;
  72:      end else begin
  73:        counter <= counter + 1'b1;
  74:      end
  75:    end
  76: 
  77: endmodule
  78: