From 6292c1101121bc8ba2db752cab3cbe41469b29d0 Mon Sep 17 00:00:00 2001 From: lonkaars Date: Thu, 30 Mar 2023 15:10:17 +0200 Subject: new spi system --- basys3/basys3.srcs/io.xdc | 4 +- basys3/basys3.srcs/ppu_addr_dec.vhd | 13 ++--- basys3/basys3.srcs/spi.vhd | 39 +++++++++------ basys3/basys3.srcs/spi_tb.vhd | 78 ++++++++++++++--------------- basys3/basys3.srcs/top.vhd | 22 ++++---- basys3/basys3.xpr | 10 +++- docs/hardware/pinout.md | 3 +- src/main.c | 12 +++-- src/ppu/consts.h | 6 +++ src/ppu/internals.c | 29 ++++++++++- src/ppu/internals.h | 10 +++- src/ppu/stm.c | 15 ++---- src/ppusim/mem.c | 14 ++++-- src/stm32/main.c | 6 ++- test/ppu-stm-integration-demo/data2test.awk | 15 ++++++ test/ppu-stm-integration-demo/makefile | 8 +-- 16 files changed, 178 insertions(+), 106 deletions(-) create mode 100755 test/ppu-stm-integration-demo/data2test.awk diff --git a/basys3/basys3.srcs/io.xdc b/basys3/basys3.srcs/io.xdc index 8243f1e..419e4cd 100644 --- a/basys3/basys3.srcs/io.xdc +++ b/basys3/basys3.srcs/io.xdc @@ -41,10 +41,10 @@ set_property PACKAGE_PIN L18 [get_ports {B[1]}] set_property PACKAGE_PIN N18 [get_ports {B[0]}] set_property IOSTANDARD LVCMOS33 [get_ports VBLANK] -set_property IOSTANDARD LVCMOS33 [get_ports WEN] +set_property IOSTANDARD LVCMOS33 [get_ports SPI_RESET] set_property PACKAGE_PIN C16 [get_ports VBLANK] -set_property PACKAGE_PIN J1 [get_ports WEN] +set_property PACKAGE_PIN J1 [get_ports SPI_RESET] diff --git a/basys3/basys3.srcs/ppu_addr_dec.vhd b/basys3/basys3.srcs/ppu_addr_dec.vhd index 33f247c..649d582 100644 --- a/basys3/basys3.srcs/ppu_addr_dec.vhd +++ b/basys3/basys3.srcs/ppu_addr_dec.vhd @@ -20,7 +20,7 @@ entity ppu_addr_dec is port( -- address decoder end ppu_addr_dec; architecture Behavioral of ppu_addr_dec is - signal TMM_RANGE, BAM_RANGE, FAM_RANGE, PAL_RANGE, AUX_RANGE : std_logic := '0'; -- ADDR in range of memory area + signal NUL_RANGE, TMM_RANGE, BAM_RANGE, FAM_RANGE, PAL_RANGE, AUX_RANGE : std_logic := '0'; -- ADDR in range of memory area begin -- address MUX TMM_ADDR <= ADDR(PPU_TMM_ADDR_WIDTH-1 downto 0); @@ -29,12 +29,13 @@ begin PAL_ADDR <= ADDR(PPU_PAL_ADDR_WIDTH-1 downto 0); AUX_ADDR <= ADDR(PPU_AUX_ADDR_WIDTH-1 downto 0); + NUL_RANGE <= '1' when (and ADDR) else '0'; -- address is 0xffff -- WEN MUX - TMM_WEN <= TMM_RANGE and WEN; - BAM_WEN <= BAM_RANGE and WEN; - FAM_WEN <= FAM_RANGE and WEN; - PAL_WEN <= PAL_RANGE and WEN; - AUX_WEN <= AUX_RANGE and WEN; + TMM_WEN <= TMM_RANGE and WEN and (not NUL_RANGE); + BAM_WEN <= BAM_RANGE and WEN and (not NUL_RANGE); + FAM_WEN <= FAM_RANGE and WEN and (not NUL_RANGE); + PAL_WEN <= PAL_RANGE and WEN and (not NUL_RANGE); + AUX_WEN <= AUX_RANGE and WEN and (not NUL_RANGE); -- address ranges TMM_RANGE <= '1' when not ((ADDR(15) and ADDR(14) and ADDR(13)) or (ADDR(15) and ADDR(14) and ADDR(12))) else '0'; diff --git a/basys3/basys3.srcs/spi.vhd b/basys3/basys3.srcs/spi.vhd index a09d5df..d0e918e 100644 --- a/basys3/basys3.srcs/spi.vhd +++ b/basys3/basys3.srcs/spi.vhd @@ -6,10 +6,11 @@ use work.ppu_consts.all; entity spi is port ( SYSCLK : in std_logic; -- clock basys3 100MHz - SPI_CLK : in std_logic; -- incoming clock of SPI - SPI_MOSI : in std_logic; -- incoming data of SPI RESET : in std_logic; -- async reset - DATA : out std_logic_vector(PPU_RAM_BUS_ADDR_WIDTH+PPU_RAM_BUS_DATA_WIDTH-1 downto 0) := (others => '0')); -- data read + DCK : in std_logic; -- data clock (spi format) + DI : in std_logic; -- data in (spi format) + DO : out std_logic_vector(PPU_RAM_BUS_ADDR_WIDTH+PPU_RAM_BUS_DATA_WIDTH-1 downto 0) := (others => '1'); -- data out (parallel) + WEN : out std_logic := '0'); -- write enable (triggers during each word to propagate previous word) end spi; architecture Behavioral of spi is @@ -17,37 +18,45 @@ architecture Behavioral of spi is signal dataFF0,dataFF1,dataFF2,dataFF3 : std_logic := '0'; -- signal for metastability synchronizer of data SPI constant COUNTER_RESET_VALUE : integer := PPU_RAM_BUS_ADDR_WIDTH + PPU_RAM_BUS_DATA_WIDTH - 1; + signal DBG_I : integer range 0 to COUNTER_RESET_VALUE := COUNTER_RESET_VALUE; -- counter for data position begin process (SYSCLK) - variable bit_idx : integer range 0 to COUNTER_RESET_VALUE := COUNTER_RESET_VALUE; -- counter for data position - variable spi_reg : std_logic_vector(PPU_RAM_BUS_ADDR_WIDTH+PPU_RAM_BUS_DATA_WIDTH-1 downto 0) := (others => '0'); + variable i : integer range 0 to COUNTER_RESET_VALUE := COUNTER_RESET_VALUE; -- counter for data position + variable data_r : std_logic_vector(PPU_RAM_BUS_ADDR_WIDTH+PPU_RAM_BUS_DATA_WIDTH-1 downto 0) := (others => '1'); -- data register begin if RESET = '1' then - spi_reg := (others => '0'); - bit_idx := COUNTER_RESET_VALUE; - DATA <= (others => '0'); + data_r := (others => '1'); + i := COUNTER_RESET_VALUE; + DBG_I <= i; + DO <= (others => '1'); + WEN <= '0'; elsif rising_edge(SYSCLK) then -- flip flop for clk SPI to synchronise a - clkFF0 <= SPI_CLK; + clkFF0 <= DCK; clkFF1 <= clkFF0; clkFF2 <= clkFF1; clkFF3 <= clkFF2; -- flip flop for data SPI to synchronise - dataFF0 <= SPI_MOSI; + dataFF0 <= DI; dataFF1 <= dataFF0; dataFF2 <= dataFF1; dataFF3 <= dataFF2; if (clkFF3 = '0' and clkFF2 = '1') then -- check for rising edge of clk SPI - spi_reg(bit_idx) := dataFF3; -- load new data into temporary register + data_r(i) := dataFF3; -- load new data into temporary register - if bit_idx = 0 then - bit_idx := COUNTER_RESET_VALUE; -- reset bit index - DATA <= spi_reg; -- flush temporary register to data outpu + if i = 0 then + i := COUNTER_RESET_VALUE; -- reset bit index + DO <= data_r; -- flush temporary register to data outpu else - bit_idx := bit_idx - 1; -- decrement bit index + i := i - 1; -- decrement bit index end if; + + -- propagate previous command to ppu during second byte of current command + if i = 23 then WEN <= '1'; end if; + if i = 15 then WEN <= '0'; end if; end if; + DBG_I <= i; end if; end process; end Behavioral; diff --git a/basys3/basys3.srcs/spi_tb.vhd b/basys3/basys3.srcs/spi_tb.vhd index f6e2d21..8e4b8aa 100644 --- a/basys3/basys3.srcs/spi_tb.vhd +++ b/basys3/basys3.srcs/spi_tb.vhd @@ -12,18 +12,18 @@ end spi_tb; architecture behavioral of spi_tb is signal SYSCLK : std_logic := '0'; signal SPI_CLK : std_logic := '0'; - signal SPI_MOSI : std_logic := '0'; + signal SPI_DATA : std_logic := '0'; signal RESET : std_logic := '0'; - signal DATA : std_logic_vector(PPU_RAM_BUS_ADDR_WIDTH+PPU_RAM_BUS_DATA_WIDTH-1 downto 0) := (others => '0'); begin uut : entity work.spi port map( SYSCLK => SYSCLK, RESET => RESET, - DATA => DATA, - SPI_CLK => SPI_CLK, - SPI_MOSI => SPI_MOSI); + DO => open, + DI => SPI_DATA, + DCK => SPI_CLK, + WEN => open); - sysclkgen: process + process begin for i in 0 to 10000 loop wait for 5 ns; @@ -34,197 +34,197 @@ begin wait; -- stop for simulator end process; - spi_data: process + process begin for i in 0 to 2 loop -- data = 0b01010110010100001001110011111111 (0x56509cff) - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '0'; + SPI_DATA <= '0'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; SPI_CLK <= '0'; - SPI_MOSI <= '1'; + SPI_DATA <= '1'; wait for 50 ns; SPI_CLK <= '1'; wait for 50 ns; diff --git a/basys3/basys3.srcs/top.vhd b/basys3/basys3.srcs/top.vhd index ed1c3b0..1c58b60 100644 --- a/basys3/basys3.srcs/top.vhd +++ b/basys3/basys3.srcs/top.vhd @@ -8,7 +8,7 @@ entity top is port ( RESET : in std_logic; -- global (async) system reset SPI_CLK : in std_logic; -- incoming clock of SPI SPI_MOSI : in std_logic; -- incoming data of SPI - WEN : in std_logic; -- PPU VRAM write enable + SPI_RESET : in std_logic; -- PPU VRAM write enable DBG_DISP_ADDR : in std_logic; -- display address/data switch (debug) DBG_LEDS_OUT : out std_logic_vector(15 downto 0); -- debug address/data output leds R,G,B : out std_logic_vector(PPU_COLOR_OUTPUT_DEPTH-1 downto 0); @@ -29,29 +29,33 @@ architecture Behavioral of top is end component; component spi port ( SYSCLK : in std_logic; -- clock basys3 100MHz - SPI_CLK : in std_logic; -- incoming clock of SPI - SPI_MOSI : in std_logic; -- incoming data of SPI RESET : in std_logic; -- async reset - DATA : out std_logic_vector(PPU_RAM_BUS_ADDR_WIDTH+PPU_RAM_BUS_DATA_WIDTH-1 downto 0)); -- data read + DCK : in std_logic; -- data clock (spi format) + DI : in std_logic; -- data in (spi format) + DO : out std_logic_vector(PPU_RAM_BUS_ADDR_WIDTH+PPU_RAM_BUS_DATA_WIDTH-1 downto 0) := (others => '0'); -- data out (parallel) + WEN : out std_logic); -- write enable (triggers during each word to propagate previous word) end component; + signal SPI_RST, PPU_WEN : std_logic; signal SPI_DATA : std_logic_vector(PPU_RAM_BUS_ADDR_WIDTH+PPU_RAM_BUS_DATA_WIDTH-1 downto 0); alias SPI_DATA_ADDR is SPI_DATA(31 downto 16); alias SPI_DATA_DATA is SPI_DATA(15 downto 0); begin + SPI_RST <= RESET or SPI_RESET; serial_peripheral_interface: component spi port map( SYSCLK => SYSCLK, - RESET => RESET, - SPI_CLK => SPI_CLK, - SPI_MOSI => SPI_MOSI, - DATA => SPI_DATA); + RESET => SPI_RST, + DCK => SPI_CLK, + DI => SPI_MOSI, + DO => SPI_DATA, + WEN => PPU_WEN); DBG_LEDS_OUT <= SPI_DATA_ADDR when DBG_DISP_ADDR = '1' else SPI_DATA_DATA; picture_processing_unit: component ppu port map( CLK100 => SYSCLK, RESET => RESET, - WEN => WEN, + WEN => PPU_WEN, ADDR => SPI_DATA_ADDR, DATA => SPI_DATA_DATA, R => R, diff --git a/basys3/basys3.xpr b/basys3/basys3.xpr index 8645fca..19bbeec 100644 --- a/basys3/basys3.xpr +++ b/basys3/basys3.xpr @@ -60,7 +60,7 @@