🐛 [SDI] fix input synchronizer (#1227)

This commit is contained in:
stnolting 2025-04-08 17:23:19 +02:00 committed by GitHub
commit 9048ef42be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 23 additions and 21 deletions

View file

@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12
| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
| 07.04.2025 | 1.11.2.6 | :bug: fix SDI input synchronization | [#1227](https://github.com/stnolting/neorv32/pull/1227) |
| 05.04.2025 | 1.11.2.5 | minor rtl edits and optimizations | [#1225](https://github.com/stnolting/neorv32/pull/1225) |
| 01.04.2025 | 1.11.2.4 | :bug: fix bug in PWM clock prescaler | [#1222](https://github.com/stnolting/neorv32/pull/1222) |
| 29.03.2025 | 1.11.2.3 | :sparkles: add optional 32 hardware spinlocks (`HWSPINLOCK` module) | [#1220](https://github.com/stnolting/neorv32/pull/1220) |

View file

@ -66,7 +66,7 @@ yet. However, experiments have shown that the SDI module can also deal with both
All SDI operations are clocked by the external `sdi_clk_i` signal. This signal is synchronized to the processor's
clock domain to simplify timing behavior. This clock synchronization requires the external SDI clock
(`sdi_clk_i`) does **not exceed 1/4 of the processor's main clock**.
(`sdi_clk_i`) to not **not exceed 1/4 of the processor's main clock**.
**SDI Interrupt**

View file

@ -29,7 +29,7 @@ package neorv32_package is
-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01110205"; -- hardware version
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01110206"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width

View file

@ -17,7 +17,7 @@ use neorv32.neorv32_package.all;
entity neorv32_sdi is
generic (
RTX_FIFO : natural range 1 to 2**15 -- RTX fifo depth, has to be a power of two, min 1
RTX_FIFO : natural range 1 to 2**15 -- RTX FIFO depth, has to be a power of two, min 1
);
port (
clk_i : in std_ulogic; -- global clock line
@ -37,16 +37,16 @@ architecture neorv32_sdi_rtl of neorv32_sdi is
-- control register --
constant ctrl_en_c : natural := 0; -- r/w: SDI enable
--
constant ctrl_fifo_size0_c : natural := 4; -- r/-: log2(FIFO size), bit 0 (lsb)
constant ctrl_fifo_size0_c : natural := 4; -- r/-: log2(FIFO size), bit 0 (LSB)
constant ctrl_fifo_size1_c : natural := 5; -- r/-: log2(FIFO size), bit 1
constant ctrl_fifo_size2_c : natural := 6; -- r/-: log2(FIFO size), bit 2
constant ctrl_fifo_size3_c : natural := 7; -- r/-: log2(FIFO size), bit 3 (msb)
constant ctrl_fifo_size3_c : natural := 7; -- r/-: log2(FIFO size), bit 3 (MSB)
--
constant ctrl_irq_rx_avail_c : natural := 15; -- r/w: RX FIFO not empty
constant ctrl_irq_rx_half_c : natural := 16; -- r/w: RX FIFO at least half full
constant ctrl_irq_rx_full_c : natural := 17; -- r/w: RX FIFO full
constant ctrl_irq_tx_empty_c : natural := 18; -- r/w: TX FIFO empty
constant ctrl_irq_tx_nhalf_c : natural := 19; -- r/w: TX FIFO not at least half full
constant ctrl_irq_rx_avail_c : natural := 15; -- r/w: interrupt if RX FIFO not empty
constant ctrl_irq_rx_half_c : natural := 16; -- r/w: interrupt if RX FIFO at least half full
constant ctrl_irq_rx_full_c : natural := 17; -- r/w: interrupt if RX FIFO full
constant ctrl_irq_tx_empty_c : natural := 18; -- r/w: interrupt if TX FIFO empty
constant ctrl_irq_tx_nhalf_c : natural := 19; -- r/w: interrupt if TX FIFO not at least half full
--
constant ctrl_rx_avail_c : natural := 23; -- r/-: RX FIFO not empty
constant ctrl_rx_half_c : natural := 24; -- r/-: RX FIFO at least half full
@ -173,8 +173,8 @@ begin
-- TX --
tx_fifo_inst: entity neorv32.neorv32_fifo
generic map (
FIFO_DEPTH => RTX_FIFO, -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH => 8, -- size of data elements in fifo (32-bit only for simulation)
FIFO_DEPTH => RTX_FIFO, -- number of FIFO entries; has to be a power of two; min 1
FIFO_WIDTH => 8, -- size of data elements in FIFO (32-bit only for simulation)
FIFO_RSYNC => true, -- sync read
FIFO_SAFE => true, -- safe access
FULL_RESET => false -- no HW reset, try to infer BRAM
@ -208,8 +208,8 @@ begin
-- RX --
rx_fifo_inst: entity neorv32.neorv32_fifo
generic map (
FIFO_DEPTH => RTX_FIFO, -- number of fifo entries; has to be a power of two; min 1
FIFO_WIDTH => 8, -- size of data elements in fifo (32-bit only for simulation)
FIFO_DEPTH => RTX_FIFO, -- number of FIFO entries; has to be a power of two; min 1
FIFO_WIDTH => 8, -- size of data elements in FIFO (32-bit only for simulation)
FIFO_RSYNC => true, -- sync read
FIFO_SAFE => true, -- safe access
FULL_RESET => false -- no HW reset, try to infer BRAM
@ -311,7 +311,7 @@ begin
when "110" => -- bit phase A: sample
-- ------------------------------------------------------------
serial.sdi_ff <= sdi_dat_i;
serial.sdi_ff <= sync.sdi;
if (sync.csn = '1') then -- transmission aborted?
serial.state(1 downto 0) <= "00";
elsif (sync.sck = '1') then

View file

@ -336,12 +336,12 @@ begin
onewire <= 'H';
-- SPI/SDI --------------------------------------------------------------------------------
-- SPI/SDI Loop-Back ----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
sdi_clk <= spi_clk after 40 ns; -- echo with propagation delay
sdi_csn <= spi_csn(7) after 40 ns;
sdi_di <= spi_do after 40 ns;
spi_di <= sdi_do when (spi_csn(7) = '0') else spi_do after 40 ns;
sdi_clk <= spi_clk;
sdi_csn <= spi_csn(7);
sdi_di <= spi_do;
spi_di <= sdi_do when (spi_csn(7) = '0') else spi_do;
-- Stream-Link FIFO Buffer ----------------------------------------------------------------

View file

@ -1528,8 +1528,9 @@ int main() {
cnt_test++;
// configure and enable SDI + SPI
// SDI input clock (= SPI output clock) must be less than 1/4 of the processor clock
neorv32_sdi_setup(1 << SDI_CTRL_IRQ_RX_AVAIL);
neorv32_spi_setup(CLK_PRSC_8, 0, 0, 0, 0);
neorv32_spi_setup(CLK_PRSC_2, 1, 0, 0, 0);
// enable fast interrupt
neorv32_cpu_csr_write(CSR_MIE, 1 << SDI_FIRQ_ENABLE);