From: Ingo Froehlich Date: Tue, 27 Feb 2018 12:26:13 +0000 (+0100) Subject: timing optimization, IF X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=c6c379229e1a7e69ca85f97c04827400dc9da65e;p=vhdlbasics.git timing optimization, IF --- diff --git a/machxo3/flash/generic_flash_ctrl.vhd b/machxo3/flash/generic_flash_ctrl.vhd index 74f7a4e..1f5f6c5 100644 --- a/machxo3/flash/generic_flash_ctrl.vhd +++ b/machxo3/flash/generic_flash_ctrl.vhd @@ -118,18 +118,18 @@ architecture arch of generic_flash_ctrl is signal flash_command_register : std_logic_vector(2 downto 0) := "000"; signal spi_flash_command : std_logic_vector(2 downto 0); signal flash_page : std_logic_vector(15 downto 0); - signal raw_flash_page : std_logic_vector(15 downto 0); signal spi_flash_page : std_logic_vector(15 downto 0); signal flash_go : std_logic; - signal spi_flash_go : std_logic; + signal spi_flash_go : std_logic; signal flash_busy : std_logic; signal flash_err : std_logic; - signal raw_select_cfg : std_logic; + signal select_cfg : std_logic; signal flash_mode : std_logic := '0'; 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 raw_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); @@ -141,7 +141,7 @@ 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, WaitRAM1, WaitRAM2, WaitRAM3, WaitRAM4, + type state_type is (IDLE, EnableFLASH1, EnableFLASH2, EnableFLASH3, Start, ReadPage, WaitFlash1, WaitFlash2, 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; @@ -175,7 +175,7 @@ begin WrB => flashram_write_i, ResetA => RESET, ResetB => RESET, - QA => ram_data_o, + QA => raw_ram_data_o, QB => flashram_data_o ); @@ -184,8 +184,8 @@ begin clk_i => CLK_f, rst_n => not RESET, cmd => flash_command, - ufm_page => raw_flash_page, - select_cfg => raw_select_cfg, + ufm_page => flash_page, + select_cfg => select_cfg, GO => flash_go, BUSY => flash_busy, ERR => flash_err, @@ -206,22 +206,43 @@ begin LOC_BUSY_OUT <= SPI_BUSY_IN; -MODE_SELECTOR : process (flash_mode, flash_page, enable_cfg_flash) +MODE_SELECTOR : process begin + wait until rising_edge(clk_f); + if (master_running = '1') then + flash_go <= master_flash_go; + flash_command <= master_flash_command; + else + flash_go <= spi_flash_go; + flash_command <= spi_flash_command; + end if; + if (flash_mode = '0') then - raw_flash_page(12 downto 0) <= flash_page(12 downto 0); - raw_flash_page(15 downto 13) <= "000"; - raw_select_cfg <= '1'; - if (flash_page(12 downto 10) = "111") then - raw_select_cfg <= '0'; - raw_flash_page(12 downto 10) <= "000"; + select_cfg <= '0'; + if (master_running = '1') then + 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 + select_cfg <= '0'; + flash_page(12 downto 10) <= "000"; + end if; end if; - else - raw_flash_page <= flash_page; - raw_select_cfg <= enable_cfg_flash; + else --new 16 bit mode + flash_page <= spi_flash_page; + select_cfg <= enable_cfg_flash; end if; end process; - + +SYNC_RAM : process +begin + wait until rising_edge(clk_l); + ram_data_o <= raw_ram_data_o; +end process; + PROC_SELECTOR : process begin wait until rising_edge(clk_l); @@ -245,8 +266,7 @@ PROC_SELECTOR : process begin if (flash_busy = '1') then spi_flash_go <= '0'; end if; - - + if (clean_master_start_reg = '1') then master_start_reg <= '0'; end if; @@ -298,65 +318,72 @@ PROC_SELECTOR : process begin 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 + 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; out_delay <= "010"; end if; elsif (out_delay = "010") then - reg_LOC_READ_OUT <= '0'; + reg_LOC_READ_OUT <= '0'; + out_delay <= "011"; + 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; + elsif (out_delay = "011") then 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_DATA_OUT(15 downto 0) <= flash_busy & flash_err & "000000" & ram_data_o; -- write nibble1 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; + else + reg_LOC_READ_OUT <= '0'; 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"; + spi_ram_addr_i <= std_logic_vector(unsigned(spi_ram_addr_i)+1); --prepare nibble4 + out_delay <= "100"; end if; - elsif (out_delay = "011") then - reg_LOC_READ_OUT <= '0'; - if (memreg(4) = '1') then + elsif (out_delay = "100") then + if (memreg(4) = '1') then -- write nibble2 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 + reg_LOC_READ_OUT <= '0'; + reg_SPI_READY_OUT <= '0'; + out_delay <= "101"; + if (memreg(1) = '0' or DATA_BUS_WIDTH < 24) 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 + elsif (out_delay = "101") then + if (DATA_BUS_WIDTH > 16) then + if (memreg(4) = '1') then -- write nibble3 + 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; + end if; 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); + out_delay <= "110"; + if (DATA_BUS_WIDTH < 32) then + out_delay <= "000"; + reg_SPI_READY_OUT <= '1'; end if; - out_delay <= "101"; - elsif (out_delay = "101" and DATA_BUS_WIDTH > 24) then + elsif (out_delay = "110") 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); + if (DATA_BUS_WIDTH > 24) then + if (memreg(4) = '1') then -- write nibble4 + 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; end if; out_delay <= "000"; else @@ -408,16 +435,12 @@ PROC_SELECTOR : process begin --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 <= ("000" & 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_l) +MASTER_DRIVER : process (clk_l) begin if rising_edge(clk_l) then @@ -427,13 +450,15 @@ begin 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; + master_running <= '1'; + +-- 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 => + master_running <= '0'; if ((master_start_reg = '1' or auto_reset = '1') and (flash_mode = '0')) then state <= Start; clean_master_start_reg <= '1'; @@ -478,6 +503,9 @@ begin state <= ReadRAM; end if; when ReadRAM => + state <= ReadRAM0; + master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1); + when ReadRAM0 => state <= WaitRAM1; master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1); when WaitRAM1 => @@ -494,13 +522,13 @@ begin when WaitRAM2 => master_ADDR_OUT <= ram_data_o; state <= WaitRAM3; - master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1); + --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"; + master_DATA_OUT(15 downto 8) <= ram_data_o; state <= WaitRAM4; when WaitRAM3_32 => if (DATA_BUS_WIDTH > 31) then @@ -516,14 +544,14 @@ begin 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); + --master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 1); + master_word_counter <= std_logic_vector(unsigned(master_word_counter) + 2); -- padding bytes 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 + --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 @@ -534,7 +562,6 @@ begin 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);