blob: 069475341e532fa2f3c5dd68d42eabb2090572df [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
module uartdpi #(
parameter BAUD = 'x,
parameter FREQ = 'x,
parameter string NAME = "uart0"
)(
input logic clk_i,
input logic rst_ni,
output logic tx_o,
input logic rx_i
);
localparam CYCLES_PER_SYMBOL = FREQ/BAUD;
import "DPI-C" function
chandle uartdpi_create(input string name);
import "DPI-C" function
byte uartdpi_read(input chandle ctx);
import "DPI-C" function
int uartdpi_can_read(input chandle ctx);
import "DPI-C" function
void uartdpi_write(input chandle ctx, int data);
chandle ctx;
int file_handle;
string file_name;
initial begin
ctx = uartdpi_create(NAME);
$sformat(file_name, "%s.log", NAME);
file_handle = $fopen(file_name, "w");
end
// TX
reg txactive;
int txcount;
int txcyccount;
reg [9:0] txsymbol;
always_ff @(negedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
tx_o <= 1;
txactive <= 0;
end else begin
if (!txactive) begin
tx_o <= 1;
if (uartdpi_can_read(ctx)) begin
automatic int c = uartdpi_read(ctx);
txsymbol <= {1'b1, c[7:0], 1'b0};
txactive <= 1;
txcount <= 0;
txcyccount <= 0;
end
end else begin
txcyccount <= txcyccount + 1;
tx_o <= txsymbol[txcount];
if (txcyccount == CYCLES_PER_SYMBOL) begin
txcyccount <= 0;
if (txcount == 9)
txactive <= 0;
else
txcount <= txcount + 1;
end
end
end
end
// RX
reg rxactive;
int rxcount;
int rxcyccount;
reg [7:0] rxsymbol;
always_ff @(negedge clk_i or negedge rst_ni) begin
rxcyccount <= rxcyccount + 1;
if (~rst_ni) begin
rxactive <= 0;
end else begin
if (!rxactive) begin
if (!rx_i) begin
rxactive <= 1;
rxcount <= 0;
rxcyccount <= 0;
end
end else begin
if (rxcount == 0) begin
if (rxcyccount == CYCLES_PER_SYMBOL/2) begin
if (rx_i) begin
rxactive <= 0;
end else begin
rxcount <= rxcount + 1;
rxcyccount <= 0;
end
end
end else if (rxcount <= 8) begin
if (rxcyccount == CYCLES_PER_SYMBOL) begin
rxsymbol[rxcount-1] <= rx_i;
rxcount <= rxcount + 1;
rxcyccount <= 0;
end
end else begin
if (rxcyccount == CYCLES_PER_SYMBOL) begin
rxactive <= 0;
if (rx_i) begin
uartdpi_write(ctx, rxsymbol);
$fwrite(file_handle, "%c", rxsymbol);
end
end
end
end
end // else: !if(rst)
end
endmodule