../src/lowrisc_dv_dpi_uartdpi_0.1/uartdpi.sv Cov: 90.2%

   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 uartdpi #(
   6:   parameter BAUD = 'x,
   7:   parameter FREQ = 'x,
   8:   parameter string NAME = "uart0"
   9: )(
  10:   input  logic clk_i,
  11:   input  logic rst_ni,
  12: 
  13:   output logic tx_o,
  14:   input  logic rx_i
  15: );
  16: 
  17:   localparam CYCLES_PER_SYMBOL = FREQ/BAUD;
  18: 
  19:   import "DPI-C" function
  20:     chandle uartdpi_create(input string name);
  21: 
  22:   import "DPI-C" function
  23:     byte uartdpi_read(input chandle ctx);
  24: 
  25:   import "DPI-C" function
  26:     int uartdpi_can_read(input chandle ctx);
  27: 
  28:   import "DPI-C" function
  29:     void uartdpi_write(input chandle ctx, int data);
  30: 
  31:   chandle ctx;
  32:   int file_handle;
  33:   string file_name;
  34: 
  35:   initial begin
  36:     ctx = uartdpi_create(NAME);
  37:     $sformat(file_name, "%s.log", NAME);
  38:     file_handle = $fopen(file_name, "w");
  39:   end
  40: 
  41:   // TX
  42:   reg txactive;
  43:   int  txcount;
  44:   int  txcyccount;
  45:   reg [9:0] txsymbol;
  46: 
  47:   always_ff @(negedge clk_i or negedge rst_ni) begin
  48:     if (~rst_ni) begin
  49:       tx_o <= 1;
  50:       txactive <= 0;
  51:     end else begin
  52:       if (!txactive) begin
  53:         tx_o <= 1;
  54:         if (uartdpi_can_read(ctx)) begin
  55:           automatic int c = uartdpi_read(ctx);
  56:           txsymbol <= {1'b1, c[7:0], 1'b0};
  57:           txactive <= 1;
  58:           txcount <= 0;
  59:           txcyccount <= 0;
  60:         end
  61:       end else begin
  62:         txcyccount <= txcyccount + 1;
  63:         tx_o <= txsymbol[txcount];
  64:         if (txcyccount == CYCLES_PER_SYMBOL) begin
  65:           txcyccount <= 0;
  66:           if (txcount == 9)
  67:             txactive <= 0;
  68:           else
  69:             txcount <= txcount + 1;
  70:         end
  71:       end
  72:     end
  73:   end
  74: 
  75:   // RX
  76:   reg rxactive;
  77:   int rxcount;
  78:   int rxcyccount;
  79:   reg [7:0] rxsymbol;
  80: 
  81:   always_ff @(negedge clk_i or negedge rst_ni) begin
  82:     rxcyccount <= rxcyccount + 1;
  83: 
  84:     if (~rst_ni) begin
  85:       rxactive <= 0;
  86:     end else begin
  87:       if (!rxactive) begin
  88:         if (!rx_i) begin
  89:           rxactive <= 1;
  90:           rxcount <= 0;
  91:           rxcyccount <= 0;
  92:         end
  93:       end else begin
  94:         if (rxcount == 0) begin
  95:           if (rxcyccount == CYCLES_PER_SYMBOL/2) begin
  96:             if (rx_i) begin
  97:               rxactive <= 0;
  98:             end else begin
  99:               rxcount <= rxcount + 1;
 100:               rxcyccount <= 0;
 101:             end
 102:           end
 103:         end else if (rxcount <= 8) begin
 104:           if (rxcyccount == CYCLES_PER_SYMBOL) begin
 105:             rxsymbol[rxcount-1] <= rx_i;
 106:             rxcount <= rxcount + 1;
 107:             rxcyccount <= 0;
 108:           end
 109:         end else begin
 110:           if (rxcyccount == CYCLES_PER_SYMBOL) begin
 111:             rxactive <= 0;
 112:             if (rx_i) begin
 113:               uartdpi_write(ctx, rxsymbol);
 114:               $fwrite(file_handle, "%c", rxsymbol);
 115:             end
 116:           end
 117:         end
 118:       end
 119:     end // else: !if(rst)
 120:   end
 121: 
 122: endmodule
 123: