--- Generic flash controller\r
--- Should be placed between spi_slave and the local logic\r
--- (see e.g. dirich/thresholds/thresholds.vhd)\r
---\r
--- Data in the user flash will be unpacked during boot, the data has the\r
--- following format:\r
--- Version : 1 Byte (must be 0x01 or 0x02, otherwise the unpacking will be cancelled)\r
--- Version = 0x01 : 16 Bit version\r
--- SPI address : 1 Byte\r
--- SPI data : 2 Bytes in big-endian\r
--- Version = 0x02 : 32 Bit version\r
--- SPI address : 1 Byte\r
--- SPI data : 4 Bytes in big-endian\r
--- 2 paddings bytes\r
---\r
--- SPI registers:\r
--- 0x4x : Mapped flash page (16 Bytes)\r
--- 0x50 : Flash command (see Padiwa manual)\r
--- Bits 15-13 : Flash command\r
--- Bits 12-0 : Flash page\r
--- 0x5C : control register\r
--- Bit 0 : Enable cfg flash\r
--- Bit 1 : Flash error (read-only)\r
--- Bit 2 : Flash busy (read-only)\r
--- Bit 4 : Master start (starts unpacking = booting)\r
--- Bit 5 : Master running (read-only)\r
--- 0x5D : Bits 0/1: Flash memory read buswidth:\r
--- 00 : 8 Bit, 01 : 16 Bit, 11 : 32 Bit (if available)\r
--- Bit 4: 0: Little Endian; 1: Big Endian\r
--- Bit 11-8 : Burst counter\r
--- 0x5E-5F : Debug registers\r
-\r
-\r
-library ieee;\r
-use ieee.std_logic_1164.all;\r
-use ieee.numeric_std.all;\r
-\r
-library machxo3lf;\r
-use machxo3lf.all;\r
-\r
-library work;\r
-use work.trb_net_std.all;\r
-\r
-entity generic_flash_ctrl is\r
- generic (MASTER_STARTPAGE : std_logic_vector(12 downto 0) := "1" & x"C00";\r
- DATA_BUS_WIDTH : integer := 16\r
- );\r
- port(\r
- CLK_l : in std_logic; --local clock\r
- CLK_f : in std_logic; --flash clock\r
- RESET : in std_logic;\r
-\r
- -- SPI/UART in host direction\r
- SPI_DATA_IN : in std_logic_vector(DATA_BUS_WIDTH-1 downto 0);\r
- SPI_DATA_OUT : out std_logic_vector(DATA_BUS_WIDTH-1 downto 0);\r
- SPI_ADDR_IN : in std_logic_vector(7 downto 0);\r
- SPI_WRITE_IN : in std_logic;\r
- SPI_READ_IN : in std_logic;\r
- SPI_READY_OUT : out std_logic;\r
- SPI_BUSY_IN : in std_logic;\r
- \r
- -- SPI/UART in local direction\r
- LOC_DATA_OUT : out std_logic_vector(DATA_BUS_WIDTH-1 downto 0);\r
- LOC_DATA_IN : in std_logic_vector(DATA_BUS_WIDTH-1 downto 0);\r
- LOC_ADDR_OUT : out std_logic_vector(7 downto 0);\r
- LOC_WRITE_OUT : out std_logic;\r
- LOC_READ_OUT : out std_logic;\r
- LOC_READY_IN : in std_logic;\r
- LOC_BUSY_OUT : out std_logic\r
- );\r
-end entity;\r
-\r
-architecture arch of generic_flash_ctrl is\r
-\r
- component UFM_WB\r
- port(\r
- clk_i : in std_logic;\r
- rst_n : in std_logic;\r
- cmd : in std_logic_vector(2 downto 0);\r
- ufm_page : in std_logic_vector(12 downto 0);\r
- GO : in std_logic;\r
- BUSY : out std_logic;\r
- ERR : out std_logic;\r
- mem_clk : out std_logic;\r
- mem_we : out std_logic;\r
- mem_ce : out std_logic;\r
- mem_addr : out std_logic_vector(3 downto 0);\r
- mem_wr_data : out std_logic_vector(7 downto 0);\r
- mem_rd_data : in std_logic_vector(7 downto 0)\r
- );\r
- end component;\r
-\r
- signal reg_SPI_DATA_OUT : std_logic_vector(DATA_BUS_WIDTH-1 downto 0);\r
- signal reg_SPI_READY_OUT : std_logic;\r
- signal reg_LOC_DATA_OUT : std_logic_vector(DATA_BUS_WIDTH-1 downto 0);\r
- signal reg_LOC_ADDR_OUT : std_logic_vector(7 downto 0);\r
- signal reg_LOC_WRITE_OUT : std_logic;\r
- signal reg_LOC_READ_OUT : std_logic;\r
- \r
- signal flashram_addr_i : std_logic_vector(3 downto 0);\r
- signal flashram_cen_i : std_logic;\r
- signal flashram_reset : std_logic;\r
- signal flashram_write_i: std_logic;\r
- signal flashram_data_i : std_logic_vector(7 downto 0);\r
- signal flashram_data_o : std_logic_vector(7 downto 0);\r
-\r
- signal flash_command : std_logic_vector(2 downto 0);\r
- signal spi_flash_command : std_logic_vector(2 downto 0);\r
- signal flash_page : std_logic_vector(12 downto 0);\r
- signal spi_flash_page : std_logic_vector(12 downto 0);\r
- signal flash_go : std_logic;\r
- signal spi_flash_go : std_logic;\r
- signal flash_busy : std_logic;\r
- signal flash_err : std_logic;\r
- \r
- signal ram_write_i : std_logic;\r
- signal ram_data_i : std_logic_vector(7 downto 0);\r
- signal ram_data_o : std_logic_vector(7 downto 0);\r
- signal ram_addr_i : std_logic_vector(3 downto 0);\r
- signal spi_ram_addr_i : std_logic_vector(3 downto 0);\r
- \r
- signal enable_cfg_flash : std_logic;\r
- signal testreg : std_logic_vector(DATA_BUS_WIDTH-1 downto 0);\r
- signal memreg : std_logic_vector(DATA_BUS_WIDTH-1 downto 0);\r
- signal burst_counter : std_logic_vector(3 downto 0);\r
-\r
- signal out_delay : std_logic_vector(2 downto 0);\r
- \r
-\r
- type state_type is (IDLE, EnableFLASH1, EnableFLASH2, EnableFLASH3, Start, ReadPage, WaitFlash1, WaitFlash2, ReadRAM, WaitRAM1, WaitRAM2, WaitRAM3, WaitRAM4,\r
- WaitRAM2_32, WaitRAM3_32, WaitRAM4_32, WaitRAM5_32, WaitRAM6_32, WriteSPI, DisableFLASH1, DisableFLASH2, DisableFLASH3);\r
- signal state : state_type := IDLE;\r
- signal master_running : std_logic;\r
- signal master_word_counter : std_logic_vector(3 downto 0);\r
- signal master_flash_page : std_logic_vector(12 downto 0) := "0000000000000";\r
- signal master_flash_command : std_logic_vector(2 downto 0);\r
- signal master_flash_go : std_logic;\r
- signal master_start_reg : std_logic := '0';\r
- signal clean_master_start_reg : std_logic := '0';\r
- signal master_DATA_OUT : std_logic_vector(DATA_BUS_WIDTH-1 downto 0);\r
- signal master_ADDR_OUT : std_logic_vector(7 downto 0);\r
- signal master_WRITE_OUT : std_logic;\r
- \r
- signal auto_reset : std_logic := '1';\r
- signal auto_dbg : std_logic := '0';\r
- signal auto_cnt : std_logic_vector(19 downto 0) := x"00000";\r
- \r
-begin\r
- \r
- THE_FLASH_RAM : entity work.flashram\r
- port map(\r
- DataInA => ram_data_i,\r
- DataInB => flashram_data_i,\r
- AddressA => ram_addr_i,\r
- AddressB => flashram_addr_i,\r
- ClockA => CLK_l,\r
- ClockB => CLK_f,\r
- ClockEnA => '1',\r
- ClockEnB => flashram_cen_i,\r
- WrA => ram_write_i,\r
- WrB => flashram_write_i,\r
- ResetA => RESET,\r
- ResetB => RESET,\r
- QA => ram_data_o,\r
- QB => flashram_data_o\r
- );\r
-\r
- THE_FLASH : UFM_WB\r
- port map(\r
- clk_i => CLK_f,\r
- rst_n => not RESET,\r
- cmd => flash_command,\r
- ufm_page => flash_page,\r
- GO => flash_go,\r
- BUSY => flash_busy,\r
- ERR => flash_err,\r
- mem_clk => open,\r
- mem_we => flashram_write_i,\r
- mem_ce => flashram_cen_i,\r
- mem_addr => flashram_addr_i,\r
- mem_wr_data => flashram_data_i,\r
- mem_rd_data => flashram_data_o\r
- );\r
-\r
- LOC_DATA_OUT <= reg_LOC_DATA_OUT;\r
- LOC_ADDR_OUT <= reg_LOC_ADDR_OUT;\r
- LOC_WRITE_OUT <= reg_LOC_WRITE_OUT;\r
- LOC_READ_OUT <= reg_LOC_READ_OUT;\r
- SPI_DATA_OUT <= reg_SPI_DATA_OUT;\r
- SPI_READY_OUT <= reg_SPI_READY_OUT;\r
-\r
- LOC_BUSY_OUT <= SPI_BUSY_IN;\r
- \r
-PROC_SELECTOR : process begin\r
- wait until rising_edge(clk_l);\r
-\r
- reg_LOC_DATA_OUT <= SPI_DATA_IN;\r
- reg_LOC_ADDR_OUT <= SPI_ADDR_IN;\r
- reg_LOC_WRITE_OUT <= SPI_WRITE_IN;\r
- reg_LOC_READ_OUT <= SPI_READ_IN;\r
- if (out_delay = "000") then\r
- reg_SPI_DATA_OUT <= LOC_DATA_IN;\r
- reg_SPI_READY_OUT <= LOC_READY_IN;\r
- end if;\r
- \r
- ram_write_i <= '0';\r
- ram_data_i <= x"00";\r
- if (burst_counter = "0000" and out_delay = "000") then\r
- spi_ram_addr_i <= x"0";\r
- else\r
- spi_ram_addr_i <= spi_ram_addr_i;\r
- end if;\r
-\r
- if (flash_busy = '1') then\r
- spi_flash_go <= '0';\r
- end if;\r
- \r
- \r
- if (clean_master_start_reg = '1') then\r
- master_start_reg <= '0';\r
- end if;\r
- \r
- if (SPI_WRITE_IN = '1') then\r
- if (SPI_ADDR_IN(7 downto 4) = x"4") then\r
- reg_LOC_WRITE_OUT <= '0';\r
- ram_write_i <= '1';\r
- ram_data_i <= SPI_DATA_IN(7 downto 0);\r
- spi_ram_addr_i <= SPI_ADDR_IN(3 downto 0);\r
- elsif (SPI_ADDR_IN(7 downto 0) = x"5C") then\r
- reg_LOC_WRITE_OUT <= '0';\r
- enable_cfg_flash <= SPI_DATA_IN(0);\r
- master_start_reg <= SPI_DATA_IN(4);\r
- elsif (SPI_ADDR_IN(7 downto 0) = x"5d") then\r
- reg_LOC_WRITE_OUT <= '0';\r
- memreg <= SPI_DATA_IN;\r
- elsif (SPI_ADDR_IN(7 downto 0) = x"5f") then\r
- reg_LOC_WRITE_OUT <= '0';\r
- testreg <= SPI_DATA_IN;\r
- elsif (SPI_ADDR_IN(7 downto 0) = x"50") then\r
- reg_LOC_WRITE_OUT <= '0';\r
- spi_flash_command <= SPI_DATA_IN(15 downto 13);\r
- if (enable_cfg_flash = '1') then\r
- spi_flash_page <= SPI_DATA_IN(12 downto 0);\r
- else\r
- spi_flash_page <= "111" & SPI_DATA_IN(9 downto 0);\r
- end if;\r
- spi_flash_go <= '1';\r
- end if;\r
- end if;\r
-\r
- if (master_running = '1') then\r
- reg_LOC_WRITE_OUT <= master_WRITE_OUT;\r
- reg_LOC_READ_OUT <= '0';\r
- reg_LOC_DATA_OUT <= master_DATA_OUT;\r
- reg_LOC_ADDR_OUT <= master_ADDR_OUT;\r
- end if;\r
-\r
- if (out_delay = "001") then\r
- reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');\r
- reg_LOC_READ_OUT <= '0';\r
- reg_SPI_READY_OUT <= '0';\r
- if (memreg(0) = '1') then\r
- -- at least 16 bit burst\r
- spi_ram_addr_i <= std_logic_vector(unsigned(spi_ram_addr_i)+1); -- prepare nibble2\r
- end if;\r
- if (SPI_BUSY_IN = '0') then\r
- out_delay <= "010";\r
- end if;\r
- elsif (out_delay = "010") then\r
- reg_LOC_READ_OUT <= '0'; \r
- if (memreg(0) = '0') then\r
- reg_SPI_DATA_OUT(15 downto 0) <= flash_busy & flash_err & "000000" & ram_data_o; -- write nibble1\r
- out_delay <= "000";\r
- reg_SPI_READY_OUT <= '1';\r
- else --continue\r
- reg_SPI_READY_OUT <= '0';\r
- if (memreg(1) = '1') then\r
- -- at least 24 bit burst\r
- spi_ram_addr_i <= std_logic_vector(unsigned(spi_ram_addr_i)+1); --prepare nibble3\r
- end if;\r
- if (memreg(4) = '1') then\r
- reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto DATA_BUS_WIDTH-8) <= ram_data_o;\r
- else\r
- reg_SPI_DATA_OUT(15 downto 0) <= x"00" & ram_data_o; -- write nibble1\r
- end if;\r
- out_delay <= "011";\r
- end if;\r
- elsif (out_delay = "011") then\r
- reg_LOC_READ_OUT <= '0';\r
- if (memreg(4) = '1') then\r
- reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto DATA_BUS_WIDTH-16) <= reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto DATA_BUS_WIDTH-8) & ram_data_o;\r
- else\r
- reg_SPI_DATA_OUT(15 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(7 downto 0);\r
- -- write nibble2\r
- end if;\r
- if (memreg(1) = '0' or DATA_BUS_WIDTH < 32) then\r
- out_delay <= "000";\r
- reg_SPI_READY_OUT <= '1';\r
- else\r
- reg_SPI_READY_OUT <= '0';\r
- spi_ram_addr_i <= std_logic_vector(unsigned(spi_ram_addr_i)+1);\r
- --prepare nibble4\r
- out_delay <= "100"; \r
- end if;\r
- elsif (out_delay = "100" and DATA_BUS_WIDTH > 16) then\r
- reg_LOC_READ_OUT <= '0';\r
- reg_SPI_READY_OUT <= '0';\r
- if (memreg(4) = '1') then\r
- reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto DATA_BUS_WIDTH-24) <= reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto DATA_BUS_WIDTH-16) & ram_data_o;\r
- else\r
- reg_SPI_DATA_OUT(23 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(15 downto 0);\r
- end if;\r
- out_delay <= "101";\r
- elsif (out_delay = "101" and DATA_BUS_WIDTH > 24) then\r
- reg_LOC_READ_OUT <= '0';\r
- reg_SPI_READY_OUT <= '1';\r
- if (memreg(4) = '1') then\r
- reg_SPI_DATA_OUT(31 downto 0) <= reg_SPI_DATA_OUT(31 downto 8) & ram_data_o;\r
- else\r
- reg_SPI_DATA_OUT(31 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(23 downto 0);\r
- end if;\r
- out_delay <= "000";\r
- else\r
- out_delay <= "000";\r
- end if;\r
-\r
- if (out_delay = "000" and burst_counter /= "0000" and SPI_BUSY_IN = '0' and reg_SPI_READY_OUT = '0') then\r
- out_delay <= "001";\r
- reg_LOC_READ_OUT <= '0';\r
- reg_SPI_READY_OUT <= '0';\r
- spi_ram_addr_i <= std_logic_vector(unsigned(spi_ram_addr_i)+1);\r
- burst_counter <= std_logic_vector(unsigned(burst_counter)-1);\r
- end if;\r
- \r
- if (SPI_READ_IN = '1') then \r
- if (SPI_ADDR_IN(7 downto 4) = x"4" and burst_counter = "0000") then\r
- reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');\r
- out_delay <= "001";\r
- reg_LOC_READ_OUT <= '0';\r
- reg_SPI_READY_OUT <= '0';\r
- spi_ram_addr_i <= SPI_ADDR_IN(3 downto 0); -- prepare nibble1\r
- burst_counter <= memreg(11 downto 8);\r
- elsif (SPI_ADDR_IN(7 downto 0) = x"5C") then\r
- reg_LOC_READ_OUT <= '0';\r
- reg_SPI_READY_OUT <= '1';\r
- reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');\r
- reg_SPI_DATA_OUT(15 downto 0) <= x"00" & "00" & master_running & master_start_reg & '0' & flash_busy & flash_err & enable_cfg_flash;\r
- elsif (SPI_ADDR_IN(7 downto 0) = x"5d") then\r
- reg_LOC_READ_OUT <= '0';\r
- reg_SPI_READY_OUT <= '1';\r
- reg_SPI_DATA_OUT <= memreg;\r
- reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');\r
- reg_SPI_DATA_OUT(11 downto 8) <= burst_counter;\r
- -- reg_SPI_DATA_OUT(15 downto 0) <= auto_dbg & "00" & master_flash_page;\r
- elsif (SPI_ADDR_IN(7 downto 0) = x"5e") then\r
- reg_LOC_READ_OUT <= '0';\r
- reg_SPI_READY_OUT <= '1';\r
- reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');\r
- reg_SPI_DATA_OUT <= master_DATA_OUT;\r
- elsif (SPI_ADDR_IN(7 downto 0) = x"5f") then\r
- reg_LOC_READ_OUT <= '0';\r
- reg_SPI_READY_OUT <= '1';\r
- reg_SPI_DATA_OUT <= testreg;\r
- --reg_SPI_DATA_OUT(15 downto 0) <= x"000" & master_word_counter;\r
- end if;\r
- end if;\r
- \r
-end process;\r
-\r
-master_running <= '0' when state = IDLE else '1';\r
-ram_addr_i <= master_word_counter when master_running = '1' else spi_ram_addr_i;\r
-flash_go <= master_flash_go when master_running = '1' else spi_flash_go;\r
-flash_page <= master_flash_page when master_running = '1' else spi_flash_page;\r
-flash_command <= master_flash_command when master_running = '1' else spi_flash_command;\r
-\r
-state_machine : process (clk_f)\r
-begin\r
- if rising_edge(clk_f) then\r
- master_flash_go <= '0';\r
- master_WRITE_OUT <= '0';\r
- clean_master_start_reg <= '0';\r
-\r
- if (DATA_BUS_WIDTH-1 > 15) then\r
- master_DATA_OUT(DATA_BUS_WIDTH-1 downto 16) <= (others => '0');\r
- end if;\r
- \r
- case state is\r
- when IDLE =>\r
- if (master_start_reg = '1' or auto_reset = '1') then\r
- state <= Start;\r
- clean_master_start_reg <= '1';\r
- master_DATA_OUT <= (others => '0');\r
- master_ADDR_OUT <= x"00";\r
- if (auto_reset = '1') then\r
- auto_cnt <= std_logic_vector(unsigned(auto_cnt) + 1);\r
- state <= IDLE;\r
- if (auto_cnt = x"FFFFF") then\r
- auto_reset <= '0';\r
- state <= EnableFLASH1;\r
- master_flash_command <= "100";\r
- master_flash_go <= '1';\r
- end if;\r
- else\r
- master_flash_command <= "000";\r
- end if;\r
- end if;\r
- when EnableFLASH1 =>\r
- auto_dbg <= '1';\r
- state <= EnableFLASH2;\r
- when EnableFLASH2 =>\r
- state <= EnableFLASH3;\r
- when EnableFLASH3 =>\r
- state <= EnableFLASH3;\r
- if (flash_busy = '0') then\r
- state <= Start;\r
- master_flash_command <= "000";\r
- end if; \r
- when Start =>\r
- master_flash_page <= MASTER_STARTPAGE;\r
- master_word_counter <= "0000";\r
- state <= ReadPage;\r
- when ReadPage =>\r
- master_flash_go <= '1';\r
- state <= WaitFlash1;\r
- when WaitFlash1 =>\r
- state <= WaitFlash2;\r
- when WaitFlash2 =>\r
- state <= WaitFlash2;\r
- if (flash_busy = '0') then\r
- state <= ReadRAM;\r
- end if;\r
- when ReadRAM =>\r
- state <= WaitRAM1;\r
- master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);\r
- when WaitRAM1 =>\r
- if (ram_data_o = x"01") then --Version: 16 Bit\r
- state <= WaitRAM2;\r
- master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);\r
- elsif (ram_data_o = x"02" and DATA_BUS_WIDTH > 24) then --Version: 32 Bit\r
- state <= WaitRAM2_32;\r
- master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);\r
- else -- break\r
- master_DATA_OUT(15 downto 0) <= x"ff" & ram_data_o;\r
- state <= DisableFLASH1;\r
- end if;\r
- when WaitRAM2 =>\r
- master_ADDR_OUT <= ram_data_o;\r
- state <= WaitRAM3;\r
- master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);\r
- when WaitRAM2_32 =>\r
- master_ADDR_OUT <= ram_data_o;\r
- state <= WaitRAM3_32;\r
- master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);\r
- when WaitRAM3 =>\r
- master_DATA_OUT(15 downto 0) <= ram_data_o & x"00";\r
- state <= WaitRAM4;\r
- when WaitRAM3_32 =>\r
- if (DATA_BUS_WIDTH > 31) then\r
- master_DATA_OUT(31 downto 0) <= ram_data_o & x"000000";\r
- end if;\r
- master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);\r
- state <= WaitRAM4_32;\r
- when WaitRAM4 =>\r
- master_DATA_OUT(15 downto 0) <= master_DATA_OUT(15 downto 8) & ram_data_o;\r
- state <= WriteSPI;\r
- master_WRITE_OUT <= '1';\r
- when WaitRAM4_32 =>\r
- if (DATA_BUS_WIDTH > 31) then\r
- master_DATA_OUT(31 downto 0) <= master_DATA_OUT(31 downto 24) & ram_data_o & x"0000";\r
- end if;\r
- master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);\r
- state <= WaitRAM5_32;\r
- when WaitRAM5_32 =>\r
- if (DATA_BUS_WIDTH > 31) then\r
- master_DATA_OUT(31 downto 0) <= master_DATA_OUT(31 downto 16) & ram_data_o & x"00";\r
- end if;\r
- master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 2);\r
- -- padding bytes\r
- state <= WaitRAM6_32;\r
- when WaitRAM6_32 =>\r
- if (DATA_BUS_WIDTH > 31) then\r
- master_DATA_OUT(31 downto 0) <= master_DATA_OUT(31 downto 8) & ram_data_o;\r
- end if;\r
- state <= WriteSPI;\r
- master_WRITE_OUT <= '1';\r
- when WriteSPI =>\r
- -- prepare for next cycle\r
- if (master_word_counter = x"F") then\r
- --master_DATA_OUT(15 downto 0) <= x"eeee";\r
- state <= ReadPage;\r
- master_word_counter <= "0000";\r
- master_flash_page <= std_logic_vector(unsigned(master_flash_page) + 1);\r
- else\r
- state <= ReadRAM;\r
- master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);\r
- end if;\r
- when DisableFLASH1 =>\r
- state <= DisableFLASH2;\r
- master_flash_command <= "101";\r
- master_flash_go <= '1';\r
- when DisableFLASH2 =>\r
- state <= DisableFLASH3;\r
- master_flash_go <= '0';\r
- when DisableFLASH3 =>\r
- if (flash_busy = '0') then\r
- state <= IDLE;\r
- master_flash_command <= "000";\r
- end if;\r
- \r
- end case;\r
- end if;\r
-end process;\r
- \r
-\r
-end architecture;\r
-\r
- \r
- \r
-\r
+-- Generic flash controller
+-- Should be placed between spi_slave and the local logic
+-- (see e.g. dirich/thresholds/thresholds.vhd)
+--
+-- Data in the user flash will be unpacked during boot, the data has the
+-- following format:
+-- Version : 1 Byte (must be 0x01 or 0x02, otherwise the unpacking will be cancelled)
+-- Version = 0x01 : 16 Bit version
+-- SPI address : 1 Byte
+-- SPI data : 2 Bytes in big-endian
+-- Version = 0x02 : 32 Bit version
+-- SPI address : 1 Byte
+-- SPI data : 4 Bytes in big-endian
+-- 2 paddings bytes
+--
+-- SPI registers:
+-- 0x4x : Mapped flash page (16 Bytes)
+-- 0x50 : Flash command (see Padiwa manual)
+-- Bits 15-13 : Flash command
+-- Bits 12-0 : Flash page
+-- 0x5C : control register
+-- Bit 0 : Enable cfg flash
+-- Bit 1 : Flash error (read-only)
+-- Bit 2 : Flash busy (read-only)
+-- Bit 4 : Master start (starts unpacking = booting)
+-- Bit 5 : Master running (read-only)
+-- 0x5D : Bits 0/1: Flash memory read buswidth:
+-- 00 : 8 Bit, 01 : 16 Bit, 11 : 32 Bit (if available)
+-- Bit 4: 0: Little Endian; 1: Big Endian
+-- Bit 11-8 : Burst counter
+-- 0x5E-5F : Debug registers
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library machxo3lf;
+use machxo3lf.all;
+
+library work;
+use work.trb_net_std.all;
+
+entity generic_flash_ctrl is
+ generic (MASTER_STARTPAGE : std_logic_vector(12 downto 0) := "1" & x"C00";
+ DATA_BUS_WIDTH : integer := 16
+ );
+ port(
+ CLK_l : in std_logic; --local clock
+ CLK_f : in std_logic; --flash clock
+ RESET : in std_logic;
+
+ -- 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/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_BUSY_OUT : out std_logic
+ );
+end entity;
+
+architecture arch of generic_flash_ctrl is
+
+ component UFM_WB
+ port(
+ clk_i : in std_logic;
+ rst_n : in std_logic;
+ cmd : in std_logic_vector(2 downto 0);
+ ufm_page : in std_logic_vector(12 downto 0);
+ GO : in std_logic;
+ BUSY : out std_logic;
+ ERR : out std_logic;
+ mem_clk : out std_logic;
+ mem_we : out std_logic;
+ mem_ce : out std_logic;
+ mem_addr : out std_logic_vector(3 downto 0);
+ mem_wr_data : out std_logic_vector(7 downto 0);
+ mem_rd_data : in std_logic_vector(7 downto 0)
+ );
+ end component;
+
+ signal reg_SPI_DATA_OUT : std_logic_vector(DATA_BUS_WIDTH-1 downto 0);
+ signal reg_SPI_READY_OUT : std_logic;
+ signal reg_LOC_DATA_OUT : std_logic_vector(DATA_BUS_WIDTH-1 downto 0);
+ signal reg_LOC_ADDR_OUT : std_logic_vector(7 downto 0);
+ signal reg_LOC_WRITE_OUT : std_logic;
+ signal reg_LOC_READ_OUT : std_logic;
+
+ signal flashram_addr_i : std_logic_vector(3 downto 0);
+ signal flashram_cen_i : std_logic;
+ signal flashram_reset : std_logic;
+ signal flashram_write_i: std_logic;
+ signal flashram_data_i : std_logic_vector(7 downto 0);
+ signal flashram_data_o : std_logic_vector(7 downto 0);
+
+ signal flash_command : std_logic_vector(2 downto 0);
+ signal spi_flash_command : std_logic_vector(2 downto 0);
+ signal flash_page : std_logic_vector(12 downto 0);
+ signal spi_flash_page : std_logic_vector(12 downto 0);
+ signal flash_go : std_logic;
+ signal spi_flash_go : std_logic;
+ signal flash_busy : std_logic;
+ signal flash_err : std_logic;
+
+ signal ram_write_i : std_logic;
+ signal ram_data_i : std_logic_vector(7 downto 0);
+ signal ram_data_o : std_logic_vector(7 downto 0);
+ signal ram_addr_i : std_logic_vector(3 downto 0);
+ signal spi_ram_addr_i : std_logic_vector(3 downto 0);
+
+ 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 burst_counter : std_logic_vector(3 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,
+ WaitRAM2_32, WaitRAM3_32, WaitRAM4_32, WaitRAM5_32, WaitRAM6_32, WriteSPI, DisableFLASH1, DisableFLASH2, DisableFLASH3);
+ signal state : state_type := IDLE;
+ signal master_running : std_logic;
+ signal master_word_counter : std_logic_vector(3 downto 0);
+ signal master_flash_page : std_logic_vector(12 downto 0) := "0000000000000";
+ signal master_flash_command : std_logic_vector(2 downto 0);
+ signal master_flash_go : std_logic;
+ signal master_start_reg : std_logic := '0';
+ signal clean_master_start_reg : std_logic := '0';
+ signal master_DATA_OUT : std_logic_vector(DATA_BUS_WIDTH-1 downto 0);
+ signal master_ADDR_OUT : std_logic_vector(7 downto 0);
+ signal master_WRITE_OUT : std_logic;
+
+ signal auto_reset : std_logic := '1';
+ signal auto_dbg : std_logic := '0';
+ signal auto_cnt : std_logic_vector(19 downto 0) := x"00000";
+
+begin
+
+ THE_FLASH_RAM : entity work.flashram
+ port map(
+ DataInA => ram_data_i,
+ DataInB => flashram_data_i,
+ AddressA => ram_addr_i,
+ AddressB => flashram_addr_i,
+ ClockA => CLK_l,
+ ClockB => CLK_f,
+ ClockEnA => '1',
+ ClockEnB => flashram_cen_i,
+ WrA => ram_write_i,
+ WrB => flashram_write_i,
+ ResetA => RESET,
+ ResetB => RESET,
+ QA => ram_data_o,
+ QB => flashram_data_o
+ );
+
+ THE_FLASH : UFM_WB
+ port map(
+ clk_i => CLK_f,
+ rst_n => not RESET,
+ cmd => flash_command,
+ ufm_page => flash_page,
+ GO => flash_go,
+ BUSY => flash_busy,
+ ERR => flash_err,
+ mem_clk => open,
+ mem_we => flashram_write_i,
+ mem_ce => flashram_cen_i,
+ mem_addr => flashram_addr_i,
+ mem_wr_data => flashram_data_i,
+ mem_rd_data => flashram_data_o
+ );
+
+ LOC_DATA_OUT <= reg_LOC_DATA_OUT;
+ LOC_ADDR_OUT <= reg_LOC_ADDR_OUT;
+ LOC_WRITE_OUT <= reg_LOC_WRITE_OUT;
+ 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_l);
+
+ reg_LOC_DATA_OUT <= SPI_DATA_IN;
+ reg_LOC_ADDR_OUT <= SPI_ADDR_IN;
+ reg_LOC_WRITE_OUT <= SPI_WRITE_IN;
+ reg_LOC_READ_OUT <= SPI_READ_IN;
+ if (out_delay = "000") then
+ reg_SPI_DATA_OUT <= LOC_DATA_IN;
+ reg_SPI_READY_OUT <= LOC_READY_IN;
+ end if;
+
+ ram_write_i <= '0';
+ ram_data_i <= x"00";
+ if (burst_counter = "0000" and out_delay = "000") then
+ spi_ram_addr_i <= x"0";
+ else
+ spi_ram_addr_i <= spi_ram_addr_i;
+ end if;
+
+ if (flash_busy = '1') then
+ spi_flash_go <= '0';
+ end if;
+
+
+ if (clean_master_start_reg = '1') then
+ master_start_reg <= '0';
+ end if;
+
+ if (SPI_WRITE_IN = '1') then
+ if (SPI_ADDR_IN(7 downto 4) = x"4") then
+ reg_LOC_WRITE_OUT <= '0';
+ ram_write_i <= '1';
+ ram_data_i <= SPI_DATA_IN(7 downto 0);
+ spi_ram_addr_i <= SPI_ADDR_IN(3 downto 0);
+ elsif (SPI_ADDR_IN(7 downto 0) = x"5C") then
+ reg_LOC_WRITE_OUT <= '0';
+ enable_cfg_flash <= SPI_DATA_IN(0);
+ master_start_reg <= SPI_DATA_IN(4);
+ elsif (SPI_ADDR_IN(7 downto 0) = x"5d") then
+ reg_LOC_WRITE_OUT <= '0';
+ memreg <= SPI_DATA_IN;
+ elsif (SPI_ADDR_IN(7 downto 0) = x"5f") then
+ reg_LOC_WRITE_OUT <= '0';
+ testreg <= 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);
+ if (enable_cfg_flash = '1') then
+ spi_flash_page <= SPI_DATA_IN(12 downto 0);
+ else
+ spi_flash_page <= "111" & SPI_DATA_IN(9 downto 0);
+ end if;
+ spi_flash_go <= '1';
+ end if;
+ end if;
+
+ if (master_running = '1') then
+ reg_LOC_WRITE_OUT <= master_WRITE_OUT;
+ reg_LOC_READ_OUT <= '0';
+ reg_LOC_DATA_OUT <= master_DATA_OUT;
+ reg_LOC_ADDR_OUT <= master_ADDR_OUT;
+ end if;
+
+ if (out_delay = "001") then
+ reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');
+ 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;
+ if (SPI_BUSY_IN = '0') then
+ out_delay <= "010";
+ end if;
+ 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 24 bit burst
+ spi_ram_addr_i <= std_logic_vector(unsigned(spi_ram_addr_i)+1); --prepare nibble3
+ end if;
+ if (memreg(4) = '1') then
+ reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto DATA_BUS_WIDTH-8) <= ram_data_o;
+ else
+ reg_SPI_DATA_OUT(15 downto 0) <= x"00" & ram_data_o; -- write nibble1
+ end if;
+ out_delay <= "011";
+ end if;
+ elsif (out_delay = "011") then
+ reg_LOC_READ_OUT <= '0';
+ if (memreg(4) = '1') then
+ reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto DATA_BUS_WIDTH-16) <= reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto DATA_BUS_WIDTH-8) & ram_data_o;
+ else
+ reg_SPI_DATA_OUT(15 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(7 downto 0);
+ -- write nibble2
+ end if;
+ 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';
+ if (memreg(4) = '1') then
+ reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto DATA_BUS_WIDTH-24) <= reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto DATA_BUS_WIDTH-16) & ram_data_o;
+ else
+ reg_SPI_DATA_OUT(23 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(15 downto 0);
+ end if;
+ out_delay <= "101";
+ elsif (out_delay = "101" and DATA_BUS_WIDTH > 24) then
+ reg_LOC_READ_OUT <= '0';
+ reg_SPI_READY_OUT <= '1';
+ if (memreg(4) = '1') then
+ reg_SPI_DATA_OUT(31 downto 0) <= reg_SPI_DATA_OUT(31 downto 8) & ram_data_o;
+ else
+ reg_SPI_DATA_OUT(31 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(23 downto 0);
+ end if;
+ out_delay <= "000";
+ else
+ out_delay <= "000";
+ end if;
+
+ if (out_delay = "000" and burst_counter /= "0000" and SPI_BUSY_IN = '0' and reg_SPI_READY_OUT = '0') then
+ out_delay <= "001";
+ reg_LOC_READ_OUT <= '0';
+ reg_SPI_READY_OUT <= '0';
+ spi_ram_addr_i <= std_logic_vector(unsigned(spi_ram_addr_i)+1);
+ burst_counter <= std_logic_vector(unsigned(burst_counter)-1);
+ end if;
+
+ if (SPI_READ_IN = '1') then
+ if (SPI_ADDR_IN(7 downto 4) = x"4" and burst_counter = "0000") then
+ reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');
+ out_delay <= "001";
+ reg_LOC_READ_OUT <= '0';
+ reg_SPI_READY_OUT <= '0';
+ spi_ram_addr_i <= SPI_ADDR_IN(3 downto 0); -- prepare nibble1
+ burst_counter <= memreg(11 downto 8);
+ elsif (SPI_ADDR_IN(7 downto 0) = x"5C") then
+ reg_LOC_READ_OUT <= '0';
+ reg_SPI_READY_OUT <= '1';
+ reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');
+ reg_SPI_DATA_OUT(15 downto 0) <= x"00" & "00" & master_running & master_start_reg & '0' & flash_busy & flash_err & enable_cfg_flash;
+ elsif (SPI_ADDR_IN(7 downto 0) = x"5d") then
+ reg_LOC_READ_OUT <= '0';
+ reg_SPI_READY_OUT <= '1';
+ reg_SPI_DATA_OUT <= memreg;
+ reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');
+ reg_SPI_DATA_OUT(11 downto 8) <= burst_counter;
+ -- 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';
+ reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 0) <= (others => '0');
+ reg_SPI_DATA_OUT <= master_DATA_OUT;
+ elsif (SPI_ADDR_IN(7 downto 0) = x"5f") then
+ reg_LOC_READ_OUT <= '0';
+ reg_SPI_READY_OUT <= '1';
+ reg_SPI_DATA_OUT <= testreg;
+ --reg_SPI_DATA_OUT(15 downto 0) <= x"000" & master_word_counter;
+ end if;
+ end if;
+
+end process;
+
+master_running <= '0' when state = IDLE else '1';
+ram_addr_i <= master_word_counter when master_running = '1' else spi_ram_addr_i;
+flash_go <= master_flash_go when master_running = '1' else spi_flash_go;
+flash_page <= master_flash_page when master_running = '1' else spi_flash_page;
+flash_command <= master_flash_command when master_running = '1' else spi_flash_command;
+
+state_machine : process (clk_f)
+begin
+ if rising_edge(clk_f) then
+ master_flash_go <= '0';
+ master_WRITE_OUT <= '0';
+ clean_master_start_reg <= '0';
+
+ if (DATA_BUS_WIDTH-1 > 15) then
+ master_DATA_OUT(DATA_BUS_WIDTH-1 downto 16) <= (others => '0');
+ end if;
+
+ case state is
+ when IDLE =>
+ if (master_start_reg = '1' or auto_reset = '1') then
+ state <= Start;
+ clean_master_start_reg <= '1';
+ master_DATA_OUT <= (others => '0');
+ master_ADDR_OUT <= x"00";
+ if (auto_reset = '1') then
+ auto_cnt <= std_logic_vector(unsigned(auto_cnt) + 1);
+ state <= IDLE;
+ if (auto_cnt = x"FFFFF") then
+ auto_reset <= '0';
+ state <= EnableFLASH1;
+ master_flash_command <= "100";
+ master_flash_go <= '1';
+ end if;
+ else
+ master_flash_command <= "000";
+ end if;
+ end if;
+ when EnableFLASH1 =>
+ auto_dbg <= '1';
+ state <= EnableFLASH2;
+ when EnableFLASH2 =>
+ state <= EnableFLASH3;
+ when EnableFLASH3 =>
+ state <= EnableFLASH3;
+ if (flash_busy = '0') then
+ state <= Start;
+ master_flash_command <= "000";
+ end if;
+ when Start =>
+ master_flash_page <= MASTER_STARTPAGE;
+ master_word_counter <= "0000";
+ state <= ReadPage;
+ when ReadPage =>
+ master_flash_go <= '1';
+ state <= WaitFlash1;
+ when WaitFlash1 =>
+ state <= WaitFlash2;
+ when WaitFlash2 =>
+ state <= WaitFlash2;
+ if (flash_busy = '0') then
+ state <= ReadRAM;
+ end if;
+ when ReadRAM =>
+ state <= WaitRAM1;
+ master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);
+ when WaitRAM1 =>
+ if (ram_data_o = x"01") then --Version: 16 Bit
+ state <= WaitRAM2;
+ master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);
+ elsif (ram_data_o = x"02" and DATA_BUS_WIDTH > 24) then --Version: 32 Bit
+ state <= WaitRAM2_32;
+ master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);
+ else -- break
+ master_DATA_OUT(15 downto 0) <= x"ff" & ram_data_o;
+ state <= DisableFLASH1;
+ end if;
+ when WaitRAM2 =>
+ master_ADDR_OUT <= ram_data_o;
+ state <= WaitRAM3;
+ master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);
+ when WaitRAM2_32 =>
+ master_ADDR_OUT <= ram_data_o;
+ state <= WaitRAM3_32;
+ master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);
+ when WaitRAM3 =>
+ master_DATA_OUT(15 downto 0) <= ram_data_o & x"00";
+ state <= WaitRAM4;
+ when WaitRAM3_32 =>
+ if (DATA_BUS_WIDTH > 31) then
+ master_DATA_OUT(31 downto 0) <= ram_data_o & x"000000";
+ end if;
+ master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);
+ state <= WaitRAM4_32;
+ when WaitRAM4 =>
+ master_DATA_OUT(15 downto 0) <= master_DATA_OUT(15 downto 8) & ram_data_o;
+ state <= WriteSPI;
+ master_WRITE_OUT <= '1';
+ when WaitRAM4_32 =>
+ if (DATA_BUS_WIDTH > 31) then
+ master_DATA_OUT(31 downto 0) <= master_DATA_OUT(31 downto 24) & ram_data_o & x"0000";
+ end if;
+ master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);
+ state <= WaitRAM5_32;
+ when WaitRAM5_32 =>
+ if (DATA_BUS_WIDTH > 31) then
+ master_DATA_OUT(31 downto 0) <= master_DATA_OUT(31 downto 16) & ram_data_o & x"00";
+ end if;
+ master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 2);
+ -- padding bytes
+ state <= WaitRAM6_32;
+ when WaitRAM6_32 =>
+ if (DATA_BUS_WIDTH > 31) then
+ master_DATA_OUT(31 downto 0) <= master_DATA_OUT(31 downto 8) & ram_data_o;
+ end if;
+ state <= WriteSPI;
+ master_WRITE_OUT <= '1';
+ when WriteSPI =>
+ -- prepare for next cycle
+ if (master_word_counter = x"F") then
+ --master_DATA_OUT(15 downto 0) <= x"eeee";
+ state <= ReadPage;
+ master_word_counter <= "0000";
+ master_flash_page <= std_logic_vector(unsigned(master_flash_page) + 1);
+ else
+ state <= ReadRAM;
+ master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);
+ end if;
+ when DisableFLASH1 =>
+ state <= DisableFLASH2;
+ master_flash_command <= "101";
+ master_flash_go <= '1';
+ when DisableFLASH2 =>
+ state <= DisableFLASH3;
+ master_flash_go <= '0';
+ when DisableFLASH3 =>
+ if (flash_busy = '0') then
+ state <= IDLE;
+ master_flash_command <= "000";
+ end if;
+
+ end case;
+ end if;
+end process;
+
+
+end architecture;
+
+
+
+