]> jspc29.x-matter.uni-frankfurt.de Git - vhdlbasics.git/commitdiff
finished master in generic flash ctrl, IF
authorIngo Froehlich <ingo@nomail.fake>
Tue, 22 Aug 2017 14:09:15 +0000 (16:09 +0200)
committerIngo Froehlich <ingo@nomail.fake>
Tue, 22 Aug 2017 14:09:15 +0000 (16:09 +0200)
machxo3/flash/generic_flash_ctrl.vhd

index 9ec5a76ed69bca4628abf5c11b8916b8a8abddc7..ee5670c5cc921682c321047d07ad4c5970c91480 100644 (file)
@@ -1,3 +1,24 @@
+-- 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, otherwise the unpacking will be cancelled)\r
+--   SPI address : 1 Byte\r
+--   SPI data : 2 Bytes in big-endian\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 : Master start (starts unpacking = booting)\r
+--  0x5D-5F : Debug registers\r
+\r
+\r
 library ieee;\r
 use ieee.std_logic_1164.all;\r
 use ieee.numeric_std.all;\r
@@ -9,6 +30,7 @@ library work;
 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
   port(\r
     CLK   : in  std_logic;\r
     RESET : in  std_logic;\r
@@ -27,8 +49,7 @@ entity generic_flash_ctrl is
     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
-    \r
+    LOC_READY_IN  : in  std_logic    \r
     );\r
 end entity;\r
 \r
@@ -52,25 +73,6 @@ architecture arch of generic_flash_ctrl is
       );\r
   end component;\r
 \r
-  --component flashram\r
-  --  port (\r
-  --    DataInA: in  std_logic_vector(7 downto 0);\r
-  --    DataInB: in  std_logic_vector(7 downto 0);\r
-  --    AddressA: in  std_logic_vector(3 downto 0);\r
-  --    AddressB: in  std_logic_vector(3 downto 0);\r
-  --    ClockA: in  std_logic;\r
-  --    ClockB: in  std_logic;\r
-  --    ClockEnA: in  std_logic;\r
-  --    ClockEnB: in  std_logic;\r
-  --    WrA: in  std_logic;\r
-  --    WrB: in  std_logic;\r
-  --    ResetA: in  std_logic;\r
-  --    ResetB: in  std_logic;\r
-  --    QA: out  std_logic_vector(7 downto 0);\r
-  --    QB: out  std_logic_vector(7 downto 0)\r
-  --    );\r
-  --end component;\r
-\r
   signal reg_SPI_DATA_OUT  : std_logic_vector(15 downto 0);\r
   signal reg_SPI_READY_OUT : std_logic;\r
   signal reg_LOC_DATA_OUT  : std_logic_vector(15 downto 0);\r
@@ -86,8 +88,11 @@ architecture arch of generic_flash_ctrl is
   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
@@ -95,12 +100,30 @@ architecture arch of generic_flash_ctrl is
   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
-\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(15 downto 0);\r
 \r
   signal out_delay : std_logic_vector(1 downto 0);\r
   \r
+\r
+  type state_type is (IDLE, EnableFLASH1, EnableFLASH2, EnableFLASH3, Start, ReadPage, WaitFlash1, WaitFlash2, ReadRAM, WaitRAM1, WaitRAM2, WaitRAM3, WaitRAM4, WaitRAM5, WriteSPI);\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(15 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
@@ -139,10 +162,6 @@ begin
       mem_rd_data => flashram_data_o\r
       );\r
 \r
-\r
-  --ram_data_i <= LOC_DATA_IN(7 downto 0);\r
-  --ram_addr_i <= SPI_ADDR_IN(3 downto 0);\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
@@ -163,33 +182,46 @@ PROC_SELECTOR : process begin
 \r
   ram_write_i <= '0';\r
   ram_data_i <= x"00";\r
-  ram_addr_i <= x"0";\r
-  flash_go <= '0';\r
+  spi_ram_addr_i <= x"0";\r
+  spi_flash_go <= '0';\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
-      ram_addr_i  <= SPI_ADDR_IN(3 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(1);\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
-      flash_command <= SPI_DATA_IN(15 downto 13);\r
-      if(enable_cfg_flash = '1') then\r
-        flash_page <= SPI_DATA_IN(12 downto 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
-        flash_page <= "111" & SPI_DATA_IN(9 downto 0);\r
+        spi_flash_page <= "111" & SPI_DATA_IN(9 downto 0);\r
       end if;\r
-      flash_go <= '1';      \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
+  \r
   if (out_delay = "01") then\r
     reg_LOC_READ_OUT  <= '0';\r
     reg_SPI_READY_OUT <= '0';\r
@@ -208,19 +240,127 @@ PROC_SELECTOR : process begin
       out_delay <= "01";\r
       reg_LOC_READ_OUT  <= '0';\r
       reg_SPI_READY_OUT <= '0';\r
-      ram_addr_i <= SPI_ADDR_IN(3 downto 0);\r
+      spi_ram_addr_i <= SPI_ADDR_IN(3 downto 0);\r
       --reg_SPI_READY_OUT <= '1';\r
      -- reg_SPI_DATA_OUT  <= flash_busy & flash_err & "00" & ram_addr_i & ram_data_o;\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  <= x"01" & "00000" & master_running & master_start_reg & 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  <= 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  <= 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  <= testreg;\r
+      reg_SPI_DATA_OUT  <= x"000" & master_word_counter;\r
     end if;\r
   end if;\r
   \r
 end process;\r
 \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)\r
+begin\r
+  if rising_edge(CLK) then\r
+    master_flash_go  <= '0';\r
+    master_WRITE_OUT <= '0';\r
+    clean_master_start_reg <= '0';\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 <= x"0000";\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 OK\r
+          state <= WaitRAM2;\r
+          master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1);\r
+        else\r
+          master_DATA_OUT <= x"ff" & ram_data_o;\r
+          state <= IDLE;\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 WaitRAM3 =>\r
+        master_DATA_OUT <= ram_data_o & x"00";\r
+        state <= WaitRAM4;\r
+      when WaitRAM4 =>\r
+        master_DATA_OUT <= master_DATA_OUT(15 downto 8) & ram_data_o;\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 <= 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
+    end case;\r
+  end if;\r
+end process;\r
+    \r
+\r
 end architecture;\r
 \r
        \r