From 4cd29497808958e01d0adcfdbfae1868218c533a Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Fri, 14 Apr 2023 13:13:09 +0200 Subject: [PATCH 1/4] [rtl] add FIFO config to DATA register --- rtl/core/neorv32_package.vhd | 4 ++-- rtl/core/neorv32_uart.vhd | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd index 66d7a613d..cb723ba34 100644 --- a/rtl/core/neorv32_package.vhd +++ b/rtl/core/neorv32_package.vhd @@ -58,9 +58,9 @@ package neorv32_package is -- log2 of co-processor timeout cycles -- constant cp_timeout_c : natural := 7; -- default = 7 (= 128 cycles) - -- Architecture Constants -------------------------------------------------------------- + -- Architecture Constants ----------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- - constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01080305"; -- hardware version + constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01080306"; -- hardware version constant archid_c : natural := 19; -- official RISC-V architecture ID constant XLEN : natural := 32; -- native data path width, do not change! diff --git a/rtl/core/neorv32_uart.vhd b/rtl/core/neorv32_uart.vhd index e0410e75f..9da9b0cce 100644 --- a/rtl/core/neorv32_uart.vhd +++ b/rtl/core/neorv32_uart.vhd @@ -148,6 +148,14 @@ architecture neorv32_uart_rtl of neorv32_uart is constant ctrl_rx_over_c : natural := 30; -- r/-: RX FIFO overflow constant ctrl_tx_busy_c : natural := 31; -- r/-: UART transmitter is busy and TX FIFO not empty + -- data register bits -- + constant data_rtx_lsb_c : natural := 0; -- r/w: RX/TX data LSB + constant data_rtx_msb_c : natural := 7; -- r/w: RX/TX data MSB + constant data_rx_fifo_size_lsb : natural := 8; -- r/-: log2(RX fifo size) LSB + constant data_rx_fifo_size_msb : natural := 11; -- r/-: log2(RX fifo size) MSB + constant data_tx_fifo_size_lsb : natural := 12; -- r/-: log2(TX fifo size) LSB + constant data_tx_fifo_size_msb : natural := 15; -- r/-: log2(TX fifo size) MSB + -- access control -- signal acc_en : std_ulogic; -- module access enable signal addr : std_ulogic_vector(31 downto 0); -- access address @@ -291,7 +299,9 @@ begin data_o(ctrl_rx_over_c) <= rx_engine.over; data_o(ctrl_tx_busy_c) <= tx_engine.busy or tx_fifo.avail; else -- data register - data_o(7 downto 0) <= rx_fifo.rdata; + data_o(data_rtx_msb_c downto data_rtx_lsb_c) <= rx_fifo.rdata; + data_o(data_rx_fifo_size_msb downto data_rx_fifo_size_lsb) <= std_ulogic_vector(to_unsigned(index_size_f(UART_RX_FIFO), 4)); + data_o(data_tx_fifo_size_msb downto data_tx_fifo_size_lsb) <= std_ulogic_vector(to_unsigned(index_size_f(UART_TX_FIFO), 4)); end if; end if; end if; @@ -330,7 +340,7 @@ begin ); tx_fifo.clear <= '1' when (ctrl.enable = '0') or (ctrl.sim_mode = '1') else '0'; - tx_fifo.wdata <= data_i(7 downto 0); + tx_fifo.wdata <= data_i(data_rtx_msb_c downto data_rtx_lsb_c); tx_fifo.we <= '1' when (wren = '1') and (addr = uart_id_rtx_addr_c) else '0'; tx_fifo.re <= '1' when (tx_engine.state = "100") else '0'; From 1a8922e60236a0b0e3412669af123af0aaaa324b Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Fri, 14 Apr 2023 13:13:38 +0200 Subject: [PATCH 2/4] [sw/lib] add UART FIFO size definitions/functions --- sw/lib/include/legacy.h | 4 ++++ sw/lib/include/neorv32_uart.h | 16 +++++++++++++++- sw/lib/source/neorv32_uart.c | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/sw/lib/include/legacy.h b/sw/lib/include/legacy.h index ab4b6d9b4..cb5bd35f0 100644 --- a/sw/lib/include/legacy.h +++ b/sw/lib/include/legacy.h @@ -53,6 +53,8 @@ **************************************************************************/ /**@{*/ #define neorv32_uart0_available() neorv32_uart_available(NEORV32_UART0) +#define neorv32_uart0_get_rx_fifo_depth() neorv32_uart_get_rx_fifo_depth(NEORV32_UART0) +#define neorv32_uart0_get_tx_fifo_depth() neorv32_uart_get_tx_fifo_depth(NEORV32_UART0) #define neorv32_uart0_setup(baudrate, irq_mask) neorv32_uart_setup(NEORV32_UART0, baudrate, irq_mask) #define neorv32_uart0_disable() neorv32_uart_disable(NEORV32_UART0) #define neorv32_uart0_enable() neorv32_uart_enable(NEORV32_UART0) @@ -73,6 +75,8 @@ **************************************************************************/ /**@{*/ #define neorv32_uart1_available() neorv32_uart_available(NEORV32_UART1) +#define neorv32_uart1_get_rx_fifo_depth() neorv32_uart_get_rx_fifo_depth(NEORV32_UART1) +#define neorv32_uart1_get_tx_fifo_depth() neorv32_uart_get_tx_fifo_depth(NEORV32_UART1) #define neorv32_uart1_setup(baudrate, irq_mask) neorv32_uart_setup(NEORV32_UART1, baudrate, irq_mask) #define neorv32_uart1_disable() neorv32_uart_disable(NEORV32_UART1) #define neorv32_uart1_enable() neorv32_uart_enable(NEORV32_UART1) diff --git a/sw/lib/include/neorv32_uart.h b/sw/lib/include/neorv32_uart.h index 62b1b17af..166512082 100644 --- a/sw/lib/include/neorv32_uart.h +++ b/sw/lib/include/neorv32_uart.h @@ -51,7 +51,7 @@ /** UART module prototype */ typedef volatile struct __attribute__((packed,aligned(4))) { uint32_t CTRL; /**< offset 0: control register (#NEORV32_UART_CTRL_enum) */ - uint32_t DATA; /**< offset 4: data register */ + uint32_t DATA; /**< offset 4: data register (#NEORV32_UART_DATA_enum) */ } neorv32_uart_t; /** UART0 module hardware access (#neorv32_uart_t) */ @@ -95,6 +95,18 @@ enum NEORV32_UART_CTRL_enum { UART_CTRL_RX_OVER = 30, /**< UART control register(30) (r/-): RX FIFO overflow */ UART_CTRL_TX_BUSY = 31 /**< UART control register(31) (r/-): Transmitter busy or TX FIFO not empty */ }; + +/** UART data register bits */ +enum NEORV32_UART_DATA_enum { + UART_DATA_RTX_LSB = 0, /**< UART data register(0) (r/w): UART receive/transmit data, LSB */ + UART_DATA_RTX_MSB = 7, /**< UART data register(7) (r/w): UART receive/transmit data, MSB */ + + UART_DATA_RX_FIFO_SIZE_LSB = 8, /**< UART data register(8) (r/-): log2(RX FIFO size), LSB */ + UART_DATA_RX_FIFO_SIZE_MSB = 11, /**< UART data register(11) (r/-): log2(RX FIFO size), MSB */ + + UART_DATA_TX_FIFO_SIZE_LSB = 12, /**< UART data register(12) (r/-): log2(RX FIFO size), LSB */ + UART_DATA_TX_FIFO_SIZE_MSB = 15, /**< UART data register(15) (r/-): log2(RX FIFO size), MSB */ +}; /**@}*/ @@ -103,6 +115,8 @@ enum NEORV32_UART_CTRL_enum { **************************************************************************/ /**@{*/ int neorv32_uart_available(neorv32_uart_t *UARTx); +int neorv32_uart_get_rx_fifo_depth(neorv32_uart_t *UARTx); +int neorv32_uart_get_tx_fifo_depth(neorv32_uart_t *UARTx); void neorv32_uart_setup(neorv32_uart_t *UARTx, uint32_t baudrate, uint32_t irq_mask); void neorv32_uart_enable(neorv32_uart_t *UARTx); void neorv32_uart_disable(neorv32_uart_t *UARTx); diff --git a/sw/lib/source/neorv32_uart.c b/sw/lib/source/neorv32_uart.c index 15ae353ea..e46179841 100644 --- a/sw/lib/source/neorv32_uart.c +++ b/sw/lib/source/neorv32_uart.c @@ -130,6 +130,34 @@ void neorv32_uart_setup(neorv32_uart_t *UARTx, uint32_t baudrate, uint32_t irq_m } +/**********************************************************************//** + * Get UART RX FIFO depth. + * + * @param[in,out] UARTx Hardware handle to UART register struct, #neorv32_uart_t. + * + * @return FIFO depth (number of entries) + **************************************************************************/ +int neorv32_uart_get_rx_fifo_depth(neorv32_uart_t *UARTx) { + + uint32_t tmp = (UARTx->DATA >> UART_DATA_RX_FIFO_SIZE_LSB) & 0x0f; + return (int)(1 << tmp); +} + + +/**********************************************************************//** + * Get UART TX FIFO depth. + * + * @param[in,out] UARTx Hardware handle to UART register struct, #neorv32_uart_t. + * + * @return FIFO depth (number of entries) + **************************************************************************/ +int neorv32_uart_get_tx_fifo_depth(neorv32_uart_t *UARTx) { + + uint32_t tmp = (UARTx->DATA >> UART_DATA_TX_FIFO_SIZE_LSB) & 0x0f; + return (int)(1 << tmp); +} + + /**********************************************************************//** * Enable UART. * @@ -184,7 +212,7 @@ void neorv32_uart_putc(neorv32_uart_t *UARTx, char c) { // wait for previous transfer to finish while ((UARTx->CTRL & (1<DATA = (uint32_t)c; + UARTx->DATA = (uint32_t)c << UART_DATA_RTX_LSB; } @@ -217,7 +245,7 @@ char neorv32_uart_getc(neorv32_uart_t *UARTx) { while (1) { if (UARTx->CTRL & (1<DATA; + return (char)(UARTx->DATA >> UART_DATA_RTX_LSB); } } } @@ -254,7 +282,7 @@ int neorv32_uart_char_received(neorv32_uart_t *UARTx) { **************************************************************************/ char neorv32_uart_char_received_get(neorv32_uart_t *UARTx) { - return (char)(UARTx->DATA); + return (char)(UARTx->DATA >> UART_DATA_RTX_LSB); } From 75af05e170ae544104a50306e9d7720397966741 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Fri, 14 Apr 2023 13:18:17 +0200 Subject: [PATCH 3/4] [docs] UART: add new DATA register bits --- docs/datasheet/soc_uart.adoc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/datasheet/soc_uart.adoc b/docs/datasheet/soc_uart.adoc index 0d670ce88..b5fd727e6 100644 --- a/docs/datasheet/soc_uart.adoc +++ b/docs/datasheet/soc_uart.adoc @@ -77,6 +77,10 @@ Once an UART interrupt has fired it remains pending until the actual cause of th example if just the `UART_CTRL_IRQ_RX_NEMPTY` bit is set, the RX interrupt will keep firing until the RX FIFO is empty again. Furthermore, a pending UART interrupt has to be explicitly cleared again by writing zero to the according <<_mip>> CSR bit. +.RX/TX FIFO Size +[TIP] +Software can retrieve the configured sizes of the RX and TX FIFO via the according `UART_DATA_RX_FIFO_SIZE` and +`UART_DATA_TX_FIFO_SIZE` bits from the `DATA` register. **RTS/CTS Hardware Flow Control** @@ -137,9 +141,11 @@ Both file are created in the simulation's home folder. <|`29:27` - ^| r/- <| _reserved_ read as zero <|`30` `UART_CTRL_RX_OVER` ^| r/- <| RX FIFO overflow <|`31` `UART_CTRL_TX_BUSY` ^| r/- <| TX busy or TX FIFO not empty -.3+<| `0xffffffa4` .3+<| `DATA` <|`7:0` ^| r/w <| receive/transmit data - <|`31:8` ^| r/- <| _reserved_, read as zero - <|`31:0` ^| -/w <| **simulation data output** +.5+<| `0xffffffa4` .3+<| `DATA` <|`7:0` `UART_DATA_RTX_MSB : UART_DATA_RTX_LSB` ^| r/w <| receive/transmit data + <|`11:8` `UART_DATA_RX_FIFO_SIZE_MSB : UART_DATA_RX_FIFO_SIZE_LSB` ^| r/- <| log2(RX FIFO size) + <|`15:12` `UART_DATA_TX_FIFO_SIZE_MSB : UART_DATA_TX_FIFO_SIZE_LSB` ^| r/- <| log2(RX FIFO size) + <|`31:16` ^| r/- <| _reserved_, read as zero + <|`31:0` ^| -/w <| **simulation data output** |======================= From f40a3775db41b4941621c3b86d550abf000f458e Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Fri, 14 Apr 2023 13:19:46 +0200 Subject: [PATCH 4/4] [CHANGELOG] add v1.8.3.6 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 220ae7827..b72839ed4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ mimpid = 0x01040312 => Version 01.04.03.12 => v1.4.3.12 | Date (*dd.mm.yyyy*) | Version | Comment | |:-------------------:|:-------:|:--------| +| 14.04.2023 | 1.8.3.6 | [UARTs] software can now retrieve the configured RX/TX FIFO sizes from the `DATA` register; [#581](https://github.com/stnolting/neorv32/pull/581) | | 13.04.2023 | 1.8.3.5 | :bug: fixed bug in FPU control logic (introduced in some earlier clean-up commit); minor code edits and optimizations; [#578](https://github.com/stnolting/neorv32/pull/578) | | 07.04.2023 | 1.8.3.4 | rtl edits and cleanups; [#571](https://github.com/stnolting/neorv32/pull/571) | | 05.04.2023 | 1.8.3.3 | update **external interrupt controller (XIRQ)**; [#570](https://github.com/stnolting/neorv32/pull/570) |