From aaec7bbc3ecefd6f7eef6d7f38e13077e5a96be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Th=C3=B6rnblad?= Date: Tue, 17 Dec 2024 17:18:45 +0100 Subject: [PATCH] Add incoming and outgoing CTS (Clear To Send) signals for the FPGA to let the CH552 and FPGA signal each other that it is OK to send UART data. The CTS signals indicate "OK to send" if high. If an incoming CTS signal goes low, the receiver of that signal should immediatly stop sending UART data. --- hw/application_fpga/core/uart/rtl/uart.v | 23 +++++++++++++++++-- hw/application_fpga/core/uart/rtl/uart_fifo.v | 15 +++++++++++- .../data/application_fpga_tk1.pcf | 4 ++-- hw/application_fpga/rtl/application_fpga.v | 6 +++++ hw/application_fpga/tb/application_fpga_sim.v | 6 +++++ .../tb/application_fpga_verilator.cc | 1 + .../tb/tb_application_fpga_sim.v | 4 ++++ 7 files changed, 54 insertions(+), 5 deletions(-) diff --git a/hw/application_fpga/core/uart/rtl/uart.v b/hw/application_fpga/core/uart/rtl/uart.v index 92405bf..314234e 100644 --- a/hw/application_fpga/core/uart/rtl/uart.v +++ b/hw/application_fpga/core/uart/rtl/uart.v @@ -55,6 +55,9 @@ module uart ( input wire rxd, output wire txd, + input wire ch552_cts, + output wire fpga_cts, + input wire cs, input wire we, input wire [ 7 : 0] address, @@ -110,6 +113,7 @@ module uart ( reg [31 : 0] tmp_read_data; reg tmp_ready; + reg [ 1 : 0] ch552_cts_reg; //---------------------------------------------------------------- // Concurrent connectivity for ports etc. @@ -158,9 +162,24 @@ module uart ( .out_syn (fifo_out_syn), .out_data(fifo_out_data), - .out_ack (fifo_out_ack) + .out_ack (fifo_out_ack), + + .fpga_cts(fpga_cts) ); + //---------------------------------------------------------------- + // reg_update + //---------------------------------------------------------------- + always @(posedge clk) begin : reg_update + if (!reset_n) begin + ch552_cts_reg <= 2'h0; + end + else begin + ch552_cts_reg[0] <= ch552_cts; + ch552_cts_reg[1] <= ch552_cts_reg[0]; + end + end // reg_update + //---------------------------------------------------------------- // api // @@ -208,7 +227,7 @@ module uart ( end ADDR_TX_STATUS: begin - tmp_read_data = {31'h0, core_txd_ready}; + tmp_read_data = {31'h0, core_txd_ready & ch552_cts_reg[1]}; end default: begin diff --git a/hw/application_fpga/core/uart/rtl/uart_fifo.v b/hw/application_fpga/core/uart/rtl/uart_fifo.v index 09558b0..3c2449a 100644 --- a/hw/application_fpga/core/uart/rtl/uart_fifo.v +++ b/hw/application_fpga/core/uart/rtl/uart_fifo.v @@ -48,7 +48,9 @@ module uart_fifo ( output wire out_syn, output wire [7 : 0] out_data, - input wire out_ack + input wire out_ack, + + output wire fpga_cts ); @@ -75,6 +77,7 @@ module uart_fifo ( reg in_ack_reg; reg in_ack_new; + reg fpga_cts_reg; //---------------------------------------------------------------- // Wires @@ -90,6 +93,7 @@ module uart_fifo ( assign out_syn = ~fifo_empty; assign out_data = fifo_mem[out_ptr_reg]; assign fifo_bytes = byte_ctr_reg; + assign fpga_cts = fpga_cts_reg; //---------------------------------------------------------------- @@ -101,6 +105,7 @@ module uart_fifo ( out_ptr_reg <= 9'h0; byte_ctr_reg <= 9'h0; in_ack_reg <= 1'h0; + fpga_cts_reg <= 1'h1; end else begin in_ack_reg <= in_ack_new; @@ -120,6 +125,14 @@ module uart_fifo ( if (byte_ctr_we) begin byte_ctr_reg <= byte_ctr_new; end + + if (byte_ctr_reg >= 9'd486) begin // FIFO is filled to ~95% or more + fpga_cts_reg <= 0; // Signal to not send more data + end + else begin + fpga_cts_reg <= 1; // Signal to send more data + end + end end // reg_update diff --git a/hw/application_fpga/data/application_fpga_tk1.pcf b/hw/application_fpga/data/application_fpga_tk1.pcf index df4541b..efc5387 100644 --- a/hw/application_fpga/data/application_fpga_tk1.pcf +++ b/hw/application_fpga/data/application_fpga_tk1.pcf @@ -14,8 +14,8 @@ # UART. set_io interface_rx 26 set_io interface_tx 25 -# set_io interface_cts 27 -# set_io interface_rts 28 +set_io interface_ch552_cts 27 +set_io interface_fpga_cts 28 # SPI master to flash memory. diff --git a/hw/application_fpga/rtl/application_fpga.v b/hw/application_fpga/rtl/application_fpga.v index 12781a8..59428e3 100644 --- a/hw/application_fpga/rtl/application_fpga.v +++ b/hw/application_fpga/rtl/application_fpga.v @@ -20,6 +20,9 @@ module application_fpga ( output wire interface_rx, input wire interface_tx, + input wire interface_ch552_cts, // CH552 clear to send, 1 = OK, 0 = NOK + output wire interface_fpga_cts, // FPGA clear to send, 1 = OK, 0 = NOK + output wire spi_ss, output wire spi_sck, output wire spi_mosi, @@ -293,6 +296,9 @@ module application_fpga ( .rxd(interface_tx), .txd(interface_rx), + .ch552_cts(interface_ch552_cts), + .fpga_cts(interface_fpga_cts), + .cs(uart_cs), .we(uart_we), .address(uart_address), diff --git a/hw/application_fpga/tb/application_fpga_sim.v b/hw/application_fpga/tb/application_fpga_sim.v index 0211ce1..047e624 100644 --- a/hw/application_fpga/tb/application_fpga_sim.v +++ b/hw/application_fpga/tb/application_fpga_sim.v @@ -33,6 +33,9 @@ module application_fpga_sim ( output wire interface_rx, input wire interface_tx, + input wire interface_ch552_cts, + output wire interface_fpga_cts, + output wire spi_ss, output wire spi_sck, output wire spi_mosi, @@ -304,6 +307,9 @@ module application_fpga_sim ( .rxd(interface_tx), .txd(interface_rx), + .ch552_cts(interface_ch552_cts), + .fpga_cts(interface_fpga_cts), + .cs(uart_cs), .we(uart_we), .address(uart_address), diff --git a/hw/application_fpga/tb/application_fpga_verilator.cc b/hw/application_fpga/tb/application_fpga_verilator.cc index e3d0d68..ce3a52a 100644 --- a/hw/application_fpga/tb/application_fpga_verilator.cc +++ b/hw/application_fpga/tb/application_fpga_verilator.cc @@ -315,6 +315,7 @@ int main(int argc, char **argv, char **env) uart_init(&u, &top.interface_tx, &top.interface_rx, BIT_DIV); top.clk = 0; + top.interface_ch552_cts = 1; while (!Verilated::gotFinish()) { uint8_t to_host = 0; diff --git a/hw/application_fpga/tb/tb_application_fpga_sim.v b/hw/application_fpga/tb/tb_application_fpga_sim.v index 32605fb..df3173d 100644 --- a/hw/application_fpga/tb/tb_application_fpga_sim.v +++ b/hw/application_fpga/tb/tb_application_fpga_sim.v @@ -29,6 +29,8 @@ module tb_application_fpga_sim (); reg tb_clk = 0; wire tb_interface_rx; reg tb_interface_tx = 1'h1; // Set to 1 to simulate inactive UART + reg tb_interface_ch552_cts = 1'h1; // Set to 1 to simulate OK to send + reg tb_interface_fpga_cts; wire tb_spi_ss; wire tb_spi_sck; wire tb_spi_mosi; @@ -49,6 +51,8 @@ module tb_application_fpga_sim (); .clk(tb_clk), .interface_rx(tb_interface_rx), .interface_tx(tb_interface_tx), + .interface_ch552_cts(tb_interface_ch552_cts), + .interface_fpga_cts(tb_interface_fpga_cts), .spi_ss(tb_spi_ss), .spi_sck(tb_spi_sck), .spi_mosi(tb_spi_mosi),