]> jspc29.x-matter.uni-frankfurt.de Git - vhdlbasics.git/commitdiff
first version for auto write to flash
authorIngo Froehlich <ingo@nomail.fake>
Tue, 7 May 2019 15:26:56 +0000 (17:26 +0200)
committerIngo Froehlich <ingo@nomail.fake>
Tue, 7 May 2019 15:26:56 +0000 (17:26 +0200)
machxo3/flash/generic_flash_ctrl.vhd

index 5ae30a9b94d41bf8d53f1ac11e01da682db6fa51..f34676e44e7a8c39c337b6e30fe3b95a412153cd 100644 (file)
@@ -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);