]> jspc29.x-matter.uni-frankfurt.de Git - vhdlbasics.git/commitdiff
added 32-bit burst, IF
authorIngo Froehlich <ingo@nomail.fake>
Fri, 25 Aug 2017 14:57:37 +0000 (16:57 +0200)
committerIngo Froehlich <ingo@nomail.fake>
Fri, 25 Aug 2017 14:57:37 +0000 (16:57 +0200)
machxo3/flash/generic_flash_ctrl.vhd

index 7cfeeea9ae4a752b897314a0ff17fe4a1e1f069a..da219b8fbda69e4605f562f65d942cee44391110 100644 (file)
@@ -16,7 +16,9 @@
 --  0x5C : control register\r
 --         Bit 0 : Enable cfg flash\r
 --         Bit 1 : Master start (starts unpacking = booting)\r
---  0x5D-5F : Debug registers\r
+--  0x5D : Flash memory return buswidth:\r
+--         00 : 8 Bit, 01 : 16 Bit, 11 : 32 Bit (if available)\r
+--  0x5E-5F : Debug registers\r
 \r
 \r
 library ieee;\r
@@ -37,21 +39,23 @@ entity generic_flash_ctrl is
     CLK   : in  std_logic;\r
     RESET : in  std_logic;\r
 \r
-    -- SPI in host direction\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 in local direction\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_READY_IN  : in  std_logic;\r
+    LOC_BUSY_OUT  : out std_logic\r
     );\r
 end entity;\r
 \r
@@ -106,8 +110,10 @@ architecture arch of generic_flash_ctrl is
   \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
+  \r
 \r
-  signal out_delay : std_logic_vector(1 downto 0);\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, WaitRAM5, WriteSPI);\r
@@ -170,7 +176,8 @@ begin
   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
+\r
+  LOC_BUSY_OUT  <= SPI_BUSY_IN;\r
   \r
 PROC_SELECTOR : process begin\r
   wait until rising_edge(CLK);\r
@@ -201,9 +208,9 @@ PROC_SELECTOR : process begin
       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
+    elsif (SPI_ADDR_IN(7 downto 0) = x"5d") then\r
       reg_LOC_WRITE_OUT <= '0';\r
-      testreg <= SPI_DATA_IN; \r
+      memreg <= 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
@@ -223,31 +230,65 @@ PROC_SELECTOR : process begin
     reg_LOC_ADDR_OUT  <= master_ADDR_OUT;\r
   end if;\r
   \r
-  if (DATA_BUS_WIDTH-1 > 15) then\r
+  if (DATA_BUS_WIDTH > 16) then\r
     reg_SPI_DATA_OUT(DATA_BUS_WIDTH-1 downto 16) <= (others => '0');\r
   end if;\r
 \r
-  if (out_delay = "01") then\r
+  if (out_delay = "001") then\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
+    out_delay <= "010";\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 32 bit burst\r
+        spi_ram_addr_i <= std_logic_vector(unsigned(spi_ram_addr_i)+1); --prepare nibble3\r
+      end if;\r
+      reg_SPI_DATA_OUT(15 downto 0) <= x"00" & ram_data_o; -- write nibble1\r
+      out_delay <= "011";\r
+    end if;\r
+  elsif (out_delay = "011") then\r
+    reg_LOC_READ_OUT  <= '0';\r
+    reg_SPI_DATA_OUT(15 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(7 downto 0);\r
+    -- write nibble2\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
-    out_delay <= "10";\r
-  elsif (out_delay = "10") then\r
+    reg_SPI_DATA_OUT(23 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(15 downto 0);\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
-    reg_SPI_DATA_OUT(15 downto 0) <= flash_busy & flash_err & "000000" & ram_data_o;\r
-    out_delay <= "00";\r
+    reg_SPI_DATA_OUT(31 downto 0) <= ram_data_o & reg_SPI_DATA_OUT(23 downto 0);\r
   else\r
-    out_delay <= "00";\r
+    out_delay <= "000";\r
   end if;\r
   \r
   if (SPI_READ_IN = '1') then    \r
     if (SPI_ADDR_IN(7 downto 4) = x"4") then\r
-      out_delay <= "01";\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);\r
-      --reg_SPI_READY_OUT <= '1';\r
-     -- reg_SPI_DATA_OUT  <= flash_busy & flash_err & "00" & ram_addr_i & ram_data_o;\r
+      spi_ram_addr_i <= SPI_ADDR_IN(3 downto 0); -- prepare nibble1\r
     elsif (SPI_ADDR_IN(7 downto 0) = x"5C") then\r
       reg_LOC_READ_OUT  <= '0';\r
       reg_SPI_READY_OUT <= '1';\r
@@ -255,7 +296,8 @@ PROC_SELECTOR : process begin
     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(15 downto 0) <= auto_dbg & "00" & master_flash_page;\r
+      reg_SPI_DATA_OUT  <= memreg;\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