From d4573d2f6f087dd5c7ee08c405101a2d6e14c36e Mon Sep 17 00:00:00 2001 From: Ingo Froehlich Date: Tue, 7 May 2019 17:26:56 +0200 Subject: [PATCH] first version for auto write to flash --- machxo3/flash/generic_flash_ctrl.vhd | 130 ++++++++++++++++++++++----- 1 file changed, 107 insertions(+), 23 deletions(-) diff --git a/machxo3/flash/generic_flash_ctrl.vhd b/machxo3/flash/generic_flash_ctrl.vhd index 5ae30a9..f34676e 100644 --- a/machxo3/flash/generic_flash_ctrl.vhd +++ b/machxo3/flash/generic_flash_ctrl.vhd @@ -52,6 +52,7 @@ use work.trb_net_std.all; entity generic_flash_ctrl is generic (MASTER_STARTPAGE : std_logic_vector(12 downto 0) := "1" & x"C00"; + USE_OLD_13BIT_MODE : integer := c_NO; DATA_BUS_WIDTH : integer := 16 ); port( @@ -129,10 +130,14 @@ architecture arch of generic_flash_ctrl is signal flash_busy : std_logic; signal flash_err : std_logic; signal select_cfg : std_logic; - signal flash_mode : std_logic := '0'; + signal flash_mode : std_logic := '1'; signal ram_write_i : std_logic; + signal spi_ram_write_i : std_logic; + signal master_ram_write_i : std_logic; signal ram_data_i : std_logic_vector(7 downto 0); + signal spi_ram_data_i : std_logic_vector(7 downto 0); + signal master_ram_data_i : std_logic_vector(7 downto 0); signal ram_data_o : std_logic_vector(7 downto 0); signal raw_ram_data_o : std_logic_vector(7 downto 0); signal ram_addr_i : std_logic_vector(3 downto 0); @@ -146,7 +151,9 @@ architecture arch of generic_flash_ctrl is signal out_delay : std_logic_vector(2 downto 0); - type state_type is (IDLE, EnableFLASH1, EnableFLASH2, EnableFLASH3, Start, ReadPage, WaitFlash1, WaitFlash2, ReadRAM, ReadRAM0, WaitRAM1, WaitRAM2, WaitRAM3, WaitRAM4, + type state_type is (IDLE, EnableFLASH1, EnableFLASH2, EnableFLASH3, Start, ReadPage, WritePage, WaitFlash1, WaitFlash2, + ReadSPI0, ReadSPI1, ReadSPI2, ReadSPI3, + ReadRAM, ReadRAM0, 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; @@ -156,9 +163,17 @@ architecture arch of generic_flash_ctrl is signal master_flash_go : std_logic; signal master_start_reg : std_logic := '0'; signal clean_master_start_reg : std_logic := '0'; + signal master_readback : 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 master_READ_OUT : std_logic; + signal master_readback_reg : std_logic_vector(7 downto 0) := x"00"; + signal readback_reg : std_logic_vector(7 downto 0) := x"00"; + signal master_readback_num : std_logic_vector(3 downto 0) := x"0"; + signal readback_num : std_logic_vector(3 downto 0) := x"0"; + + signal auto_reset : std_logic := '1'; signal auto_dbg : std_logic := '0'; @@ -215,30 +230,36 @@ MODE_SELECTOR : process begin wait until rising_edge(clk_f); if (master_running = '1') then - flash_go <= master_flash_go; + flash_go <= master_flash_go; flash_command <= master_flash_command; else - flash_go <= spi_flash_go; + flash_go <= spi_flash_go; flash_command <= spi_flash_command; end if; - if (flash_mode = '0') then + if (flash_mode = '0' and USE_OLD_13BIT_MODE = c_YES) then select_cfg <= '0'; if (master_running = '1') then - flash_page(9 downto 0) <= master_flash_page(9 downto 0); + flash_page(9 downto 0) <= master_flash_page(9 downto 0); flash_page(15 downto 10) <= "000000"; else flash_page(12 downto 0) <= spi_flash_page(12 downto 0); flash_page(15 downto 13) <= "000"; select_cfg <= '1'; - if (spi_flash_page(12 downto 10) = "111") then + if (spi_flash_page(12 downto 10) = "111" or enable_cfg_flash = '0') then select_cfg <= '0'; flash_page(12 downto 10) <= "000"; end if; end if; else --new 16 bit mode - flash_page <= spi_flash_page; - select_cfg <= enable_cfg_flash; + if (master_running = '1') then + flash_page(9 downto 0) <= master_flash_page(9 downto 0); + flash_page(15 downto 10) <= "000000"; + select_cfg <= '0'; + else + flash_page <= spi_flash_page; + select_cfg <= enable_cfg_flash; + end if; end if; end process; @@ -269,8 +290,8 @@ PROC_SELECTOR : process begin reg_SPI_READY_OUT <= LOC_READY_IN; end if; - ram_write_i <= '0'; - ram_data_i <= x"00"; + spi_ram_write_i <= '0'; + spi_ram_data_i <= x"00"; if (burst_counter = "0000" and out_delay = "000") then spi_ram_addr_i <= x"0"; else @@ -288,14 +309,17 @@ PROC_SELECTOR : process begin 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_write_i <= '1'; + spi_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); - flash_mode <= SPI_DATA_IN(8); + master_readback <= SPI_DATA_IN(2); --new + master_start_reg <= SPI_DATA_IN(3); --changed + readback_num <= SPI_DATA_IN(7 downto 4); + readback_reg <= SPI_DATA_IN(15 downto 8); + --flash_mode <= SPI_DATA_IN(8); --XXX elsif (SPI_ADDR_IN(7 downto 0) = x"5d") then reg_LOC_WRITE_OUT <= '0'; memreg <= SPI_DATA_IN; @@ -306,7 +330,7 @@ PROC_SELECTOR : process begin flash_command_register <= SPI_DATA_IN(3 downto 1); elsif (SPI_ADDR_IN(7 downto 0) = x"50" and spi_flash_go = '0') then reg_LOC_WRITE_OUT <= '0'; - if (flash_mode = '0') then + if (flash_mode = '0' and USE_OLD_13BIT_MODE = c_YES) then spi_flash_command <= SPI_DATA_IN(15 downto 13); if (enable_cfg_flash = '1') then spi_flash_page <= "000" & SPI_DATA_IN(12 downto 0); @@ -315,7 +339,7 @@ PROC_SELECTOR : process begin end if; else spi_flash_command <= flash_command_register; - spi_flash_page <= SPI_DATA_IN(15 downto 0); + spi_flash_page <= SPI_DATA_IN(15 downto 0); end if; spi_flash_go <= '1'; end if; @@ -323,7 +347,7 @@ PROC_SELECTOR : process begin if (master_running = '1') then reg_LOC_WRITE_OUT <= master_WRITE_OUT; - reg_LOC_READ_OUT <= '0'; + reg_LOC_READ_OUT <= master_READ_OUT; reg_LOC_DATA_OUT <= master_DATA_OUT; reg_LOC_ADDR_OUT <= master_ADDR_OUT; end if; @@ -454,7 +478,10 @@ PROC_SELECTOR : process begin end process; -ram_addr_i <= master_word_counter when master_running = '1' else spi_ram_addr_i; +ram_addr_i <= master_word_counter when master_running = '1' else spi_ram_addr_i; +ram_data_i <= master_ram_data_i when master_running = '1' else spi_ram_data_i; +ram_write_i <= master_ram_write_i when master_running = '1' else spi_ram_write_i; + MASTER_DRIVER : process (clk_l) begin @@ -465,6 +492,7 @@ begin end if; master_WRITE_OUT <= '0'; + master_READ_OUT <= '0'; clean_master_start_reg <= '0'; master_running <= '1'; @@ -475,7 +503,8 @@ begin case state is when IDLE => master_running <= '0'; - if ((master_start_reg = '1' or auto_reset = '1') and (flash_mode = '0')) then + --if ((master_start_reg = '1' or auto_reset = '1') and (flash_mode = '0')) then + if ((master_start_reg = '1' or auto_reset = '1') and (flash_mode = '1')) then state <= Start; clean_master_start_reg <= '1'; master_DATA_OUT <= (others => '0'); @@ -505,19 +534,74 @@ begin master_flash_command <= "000"; end if; when Start => - master_flash_page <= MASTER_STARTPAGE; + --master_flash_page <= MASTER_STARTPAGE; + master_flash_page <= (others => '0'); master_word_counter <= "0000"; - state <= ReadPage; + if master_readback = '1' then + state <= ReadSPI0; + master_readback_num <= readback_num; + master_readback_reg <= readback_reg; + master_word_counter <= x"F"; + else + state <= ReadPage; + end if; when ReadPage => master_flash_go <= '1'; state <= WaitFlash1; + when WritePage => + master_flash_go <= '1'; + master_flash_command <= "010"; + state <= WaitFlash1; + master_ram_write_i <= '0'; when WaitFlash1 => state <= WaitFlash2; when WaitFlash2 => state <= WaitFlash2; if (flash_busy = '0' and master_flash_go = '0') then - state <= ReadRAM; + if master_readback = '1' then + if master_readback_num = x"0" then + state <= DisableFLASH1; + else + state <= ReadSPI0; + master_flash_page <= std_logic_vector(unsigned(master_flash_page) + 1); + --master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1); + end if; + else + state <= ReadRAM; + end if; + end if; + + --read from registers and write to flash + when ReadSPI0 => + master_ADDR_OUT <= master_readback_reg; + master_READ_OUT <= '1'; + state <= ReadSPI1; + master_ram_data_i <= x"01"; --16bit version only + master_ram_write_i <= '1'; + master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1); + when ReadSPI1 => + state <= ReadSPI2; + master_ram_data_i <= master_readback_reg; + master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1); + when ReadSPI2 => + master_ram_data_i <= LOC_DATA_IN(15 downto 8); + master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1); + master_readback_num <= std_logic_vector(unsigned(master_readback_num) - 1); + master_readback_reg <= std_logic_vector(unsigned(master_readback_reg) + 1); + state <= ReadSPI3; + when ReadSPI3 => + master_ram_data_i <= LOC_DATA_IN(7 downto 0); + -- prepare for next cycle + if (master_word_counter = x"F" or master_readback_num = x"0") then + state <= WritePage; + master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1); + else + state <= ReadSPI0; + master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1); end if; + + + --READ from flash and store to registers when ReadRAM => state <= ReadRAM0; master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1); -- 2.43.0