From ca4511b6dc57ca0ba0858f0bf36cdc22cf19e5f7 Mon Sep 17 00:00:00 2001 From: slmnemo Date: Fri, 22 Jul 2022 17:13:19 -0700 Subject: [PATCH] Fixed UART FIFO bugs and added FIFO tests --- pipelined/src/uncore/uartPC16550D.sv | 11 +++++++--- .../references/WALLY-uart-01.reference_output | 13 +++++++++++- .../rv32i_m/privilege/src/WALLY-uart-01.S | 20 +++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/pipelined/src/uncore/uartPC16550D.sv b/pipelined/src/uncore/uartPC16550D.sv index 5eabe60c7..dcb04883f 100644 --- a/pipelined/src/uncore/uartPC16550D.sv +++ b/pipelined/src/uncore/uartPC16550D.sv @@ -324,7 +324,9 @@ module uartPC16550D( if (~PRESETn) begin rxfifohead <= #1 0; rxfifotail <= #1 0; rxdataready <= #1 0; RXBR <= #1 0; end else begin - if (rxstate == UART_DONE) begin + if (~MEMWb & (A == 3'b010) & Din[1]) begin + rxfifohead <= #1 0; rxfifotail <= #1 0; rxdataready <= #1 0; + end else if (rxstate == UART_DONE) begin RXBR <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register if (rxoverrunerr) $warning("UART RX Overrun Error\n"); if (rxparityerr) $warning("UART RX Parity Error\n"); @@ -337,7 +339,8 @@ module uartPC16550D( end else if (~MEMRb & A == 3'b000 & ~DLAB) begin // reading RBR updates ready / pops fifo if (fifoenabled) begin if (~rxfifoempty) rxfifotail <= #1 rxfifotail + 1; - if (rxfifoempty) rxdataready <= #1 0; + // if (rxfifoempty) rxdataready <= #1 0; + if (rxfifoentries == 1) rxdataready <= #1 0; // When reading the last entry, data ready becomes zero end else begin rxdataready <= #1 0; RXBR <= #1 {1'b0, RXBR[9:0]}; // Ben 31 March 2022: I added this so that rxoverrunerr permanently goes away upon reading RBR (when not in FIFO mode) @@ -448,6 +451,8 @@ module uartPC16550D( always_ff @(posedge PCLK, negedge PRESETn) if (~PRESETn) begin txfifohead <= #1 0; txfifotail <= #1 0; txhrfull <= #1 0; txsrfull <= #1 0; TXHR <= #1 0; txsr <= #1 12'hfff; + end else if (~MEMWb & (A == 3'b010) & Din[2]) begin + txfifohead <= #1 0; txfifotail <= #1 0; end else begin if (~MEMWb & A == 3'b000 & ~DLAB) begin // writing transmit holding register or fifo if (fifoenabled) begin @@ -461,7 +466,7 @@ module uartPC16550D( end if (txstate == UART_IDLE) begin // move data into tx shift register if available if (fifoenabled) begin - if (~txfifoempty) begin + if (~txfifoempty & ~txsrfull) begin txsr <= #1 txdata; txfifotail <= #1 txfifotail+1; txsrfull <= #1 1; diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-uart-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-uart-01.reference_output index 899884395..cfe54cb1c 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-uart-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-uart-01.reference_output @@ -39,6 +39,17 @@ ffffffB8 ffffffC2 # FIFO interrupt 0000C101 00000000 - +ffffffC1 +0000C401 +ffffffA5 +ffffffC1 +00000001 +00000002 +00000061 +00000003 +00000060 +0000C101 +ffffffC1 +00000060 0000000b # ecall from test termination diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-uart-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-uart-01.S index 82aca9867..6d8f70660 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-uart-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-uart-01.S @@ -160,5 +160,25 @@ test_cases: .4byte UART_THR, 0x00, write08_test # write 0 to transmit register .4byte 0x0, 0xC101, uart_data_wait # no interrupts pending (transmitter interrupt squashed by early read) .4byte UART_RBR, 0x00, read08_test # read 0 from buffer register +.4byte UART_THR, 0xA5, write08_test # Write A5 to transmit register +.4byte UART_THR, 0x01, write08_test # Write 1 to transmit register +.4byte UART_IIR, 0xC1, read08_test # no interrupts pending +.4byte UART_THR, 0x02, write08_test # Write 2 to transmit register +.4byte UART_THR, 0x03, write08_test # Write 3 to transmit register +.4byte 0x0, 0xC401, uart_data_wait # Interrupt due to data ready +.4byte UART_RBR, 0xA5, read08_test # Read A5 from buffer register +.4byte UART_IIR, 0xC2, read08_test # Data ready interrupt cleared +.4byte UART_RBR, 0x01, read08_test # Read 1 from buffer register +.4byte UART_RBR, 0x02, read08_test # Read 2 from buffer register +.4byte UART_LSR, 0x61, read08_test # Data ready, 1 item left in FIFO +.4byte UART_RBR, 0x03, read08_test # Read 3 from buffer register +.4byte UART_LSR, 0x60, read08_test # No data ready, FIFO is empty +.4byte UART_THR, 0xFF, write08_test # Write FF to transmit register +.4byte UART_THR, 0xFE, write08_test # Write FE to transmit register +.4byte 0x0, 0xC101, uart_data_wait # Interrupt due to data ready +.4byte UART_FCR, 0xC7, write08_test # Clear all bytes in FIFO +.4byte UART_FCR, 0xC1, read08_test # Check that FCR clears bits 1 and 2 when written to 1 +.4byte UART_LSR, 0x60, read08_test # No data ready, FIFO cleared by writing to FCR + .4byte 0x0, 0x0, terminate_test \ No newline at end of file