From 0dcb394236e5dc710658f71c84c34f7f23ec2397 Mon Sep 17 00:00:00 2001 From: Ingo Froehlich Date: Fri, 25 Aug 2017 16:57:37 +0200 Subject: [PATCH] added 32-bit burst, IF --- machxo3/flash/generic_flash_ctrl.vhd | 82 +++++++++++++++++++++------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/machxo3/flash/generic_flash_ctrl.vhd b/machxo3/flash/generic_flash_ctrl.vhd index 7cfeeea..da219b8 100644 --- a/machxo3/flash/generic_flash_ctrl.vhd +++ b/machxo3/flash/generic_flash_ctrl.vhd @@ -16,7 +16,9 @@ -- 0x5C : control register -- Bit 0 : Enable cfg flash -- Bit 1 : Master start (starts unpacking = booting) --- 0x5D-5F : Debug registers +-- 0x5D : Flash memory return buswidth: +-- 00 : 8 Bit, 01 : 16 Bit, 11 : 32 Bit (if available) +-- 0x5E-5F : Debug registers library ieee; @@ -37,21 +39,23 @@ entity generic_flash_ctrl is CLK : in std_logic; RESET : in std_logic; - -- SPI in host direction + -- SPI/UART in host direction SPI_DATA_IN : in std_logic_vector(DATA_BUS_WIDTH-1 downto 0); SPI_DATA_OUT : out std_logic_vector(DATA_BUS_WIDTH-1 downto 0); SPI_ADDR_IN : in std_logic_vector(7 downto 0); SPI_WRITE_IN : in std_logic; SPI_READ_IN : in std_logic; SPI_READY_OUT : out std_logic; + SPI_BUSY_IN : in std_logic; - -- SPI in local direction + -- SPI/UART in local direction LOC_DATA_OUT : out std_logic_vector(DATA_BUS_WIDTH-1 downto 0); LOC_DATA_IN : in std_logic_vector(DATA_BUS_WIDTH-1 downto 0); LOC_ADDR_OUT : out std_logic_vector(7 downto 0); LOC_WRITE_OUT : out std_logic; LOC_READ_OUT : out std_logic; - LOC_READY_IN : in std_logic + LOC_READY_IN : in std_logic; + LOC_BUSY_OUT : out std_logic ); end entity; @@ -106,8 +110,10 @@ architecture arch of generic_flash_ctrl is signal enable_cfg_flash : std_logic; signal testreg : std_logic_vector(DATA_BUS_WIDTH-1 downto 0); + signal memreg : std_logic_vector(DATA_BUS_WIDTH-1 downto 0); + - signal out_delay : std_logic_vector(1 downto 0); + signal out_delay : std_logic_vector(2 downto 0); type state_type is (IDLE, EnableFLASH1, EnableFLASH2, EnableFLASH3, Start, ReadPage, WaitFlash1, WaitFlash2, ReadRAM, WaitRAM1, WaitRAM2, WaitRAM3, WaitRAM4, WaitRAM5, WriteSPI); @@ -170,7 +176,8 @@ begin LOC_READ_OUT <= reg_LOC_READ_OUT; SPI_DATA_OUT <= reg_SPI_DATA_OUT; SPI_READY_OUT <= reg_SPI_READY_OUT; - + + LOC_BUSY_OUT <= SPI_BUSY_IN; PROC_SELECTOR : process begin wait until rising_edge(CLK); @@ -201,9 +208,9 @@ PROC_SELECTOR : process begin reg_LOC_WRITE_OUT <= '0'; enable_cfg_flash <= SPI_DATA_IN(0); master_start_reg <= SPI_DATA_IN(1); - elsif (SPI_ADDR_IN(7 downto 0) = x"5f") then + elsif (SPI_ADDR_IN(7 downto 0) = x"5d") then reg_LOC_WRITE_OUT <= '0'; - testreg <= SPI_DATA_IN; + memreg <= SPI_DATA_IN; elsif (SPI_ADDR_IN(7 downto 0) = x"50") then reg_LOC_WRITE_OUT <= '0'; spi_flash_command <= SPI_DATA_IN(15 downto 13); @@ -223,31 +230,65 @@ PROC_SELECTOR : process begin reg_LOC_ADDR_OUT <= master_ADDR_OUT; end if; - if (DATA_BUS_WIDTH-1 > 15) then + if (DATA_BUS_WIDTH > 16) then reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 16) <= (others => '0'); end if; - if (out_delay = "01") then + if (out_delay = "001") then + reg_LOC_READ_OUT <= '0'; + reg_SPI_READY_OUT <= '0'; + if (memreg(0) = '1') then + -- at least 16 bit burst + spi_ram_addr_i <= std_logic_vector(unsigned(spi_ram_addr_i)+1); -- prepare nibble2 + end if; + out_delay <= "010"; + elsif (out_delay = "010") then + reg_LOC_READ_OUT <= '0'; + if (memreg(0) = '0') then + reg_SPI_DATA_OUT(15 downto 0) <= flash_busy & flash_err & "000000" & ram_data_o; -- write nibble1 + out_delay <= "000"; + reg_SPI_READY_OUT <= '1'; + else --continue + reg_SPI_READY_OUT <= '0'; + if (memreg(1) = '1') then + -- at least 32 bit burst + spi_ram_addr_i <= std_logic_vector(unsigned(spi_ram_addr_i)+1); --prepare nibble3 + end if; + reg_SPI_DATA_OUT(15 downto 0) <= x"00" & ram_data_o; -- write nibble1 + out_delay <= "011"; + end if; + elsif (out_delay = "011") then + reg_LOC_READ_OUT <= '0'; + reg_SPI_DATA_OUT(15 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(7 downto 0); + -- write nibble2 + if (memreg(1) = '0' or DATA_BUS_WIDTH < 32) then + out_delay <= "000"; + reg_SPI_READY_OUT <= '1'; + else + reg_SPI_READY_OUT <= '0'; + spi_ram_addr_i <= std_logic_vector(unsigned(spi_ram_addr_i)+1); + --prepare nibble4 + out_delay <= "100"; + end if; + elsif (out_delay = "100" and DATA_BUS_WIDTH > 16) then reg_LOC_READ_OUT <= '0'; reg_SPI_READY_OUT <= '0'; - out_delay <= "10"; - elsif (out_delay = "10") then + reg_SPI_DATA_OUT(23 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(15 downto 0); + out_delay <= "101"; + elsif (out_delay = "101" and DATA_BUS_WIDTH > 24) then reg_LOC_READ_OUT <= '0'; reg_SPI_READY_OUT <= '1'; - reg_SPI_DATA_OUT(15 downto 0) <= flash_busy & flash_err & "000000" & ram_data_o; - out_delay <= "00"; + reg_SPI_DATA_OUT(31 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(23 downto 0); else - out_delay <= "00"; + out_delay <= "000"; end if; if (SPI_READ_IN = '1') then if (SPI_ADDR_IN(7 downto 4) = x"4") then - out_delay <= "01"; + out_delay <= "001"; reg_LOC_READ_OUT <= '0'; reg_SPI_READY_OUT <= '0'; - spi_ram_addr_i <= SPI_ADDR_IN(3 downto 0); - --reg_SPI_READY_OUT <= '1'; - -- reg_SPI_DATA_OUT <= flash_busy & flash_err & "00" & ram_addr_i & ram_data_o; + spi_ram_addr_i <= SPI_ADDR_IN(3 downto 0); -- prepare nibble1 elsif (SPI_ADDR_IN(7 downto 0) = x"5C") then reg_LOC_READ_OUT <= '0'; reg_SPI_READY_OUT <= '1'; @@ -255,7 +296,8 @@ PROC_SELECTOR : process begin elsif (SPI_ADDR_IN(7 downto 0) = x"5d") then reg_LOC_READ_OUT <= '0'; reg_SPI_READY_OUT <= '1'; - reg_SPI_DATA_OUT(15 downto 0) <= auto_dbg & "00" & master_flash_page; + reg_SPI_DATA_OUT <= memreg; + -- reg_SPI_DATA_OUT(15 downto 0) <= auto_dbg & "00" & master_flash_page; elsif (SPI_ADDR_IN(7 downto 0) = x"5e") then reg_LOC_READ_OUT <= '0'; reg_SPI_READY_OUT <= '1'; -- 2.43.0