diff --git a/bench/bench_flashrom_wb.vhd b/bench/bench_flashrom_wb.vhd index 2d2eba5..11043a9 100644 --- a/bench/bench_flashrom_wb.vhd +++ b/bench/bench_flashrom_wb.vhd @@ -85,6 +85,8 @@ begin end process clock_driver; test : process is + constant DEL : integer := 2; + begin rst <= '1'; wb_in.ADR <= (others => '0'); @@ -101,16 +103,17 @@ begin wait until wb_out.ACK = '1'; wb_in.CYC <= '0'; wb_in.STB <= '0'; - waitnclk(30); + waitnclk(DEL); wb_in.ADR <= std_logic_vector(to_unsigned(4, 32)); wb_in.CYC <= '1'; wb_in.STB <= '1'; wb_in.WE <= '0'; wait until wb_out.ACK = '1'; + waitclk; wb_in.CYC <= '0'; wb_in.STB <= '0'; - waitnclk(30); + waitnclk(22); --waitnclk(22); -- Time after read to write needs to be longer wb_in.ADR <= std_logic_vector(to_unsigned(4, 32)); wb_in.DAT <= x"deadbeef"; @@ -118,27 +121,42 @@ begin wb_in.STB <= '1'; wb_in.WE <= '1'; wait until wb_out.ACK = '1'; + waitclk; wb_in.CYC <= '0'; wb_in.STB <= '0'; - waitnclk(30); + waitnclk(DEL); + + wb_in.ADR <= std_logic_vector(to_unsigned(8, 32)); + wb_in.DAT <= x"600dbee2"; + wb_in.CYC <= '1'; + wb_in.STB <= '1'; + wb_in.WE <= '1'; + wait until wb_out.ACK = '1'; + waitclk; + wb_in.CYC <= '0'; + wb_in.STB <= '0'; + waitnclk(DEL); wb_in.ADR <= std_logic_vector(to_unsigned(4, 32)); wb_in.CYC <= '1'; wb_in.STB <= '1'; wb_in.WE <= '0'; wait until wb_out.ACK = '1'; + waitclk; + assert wb_out.DAT = x"deadbeef" report "Readback error @ 4 [1]" severity error; wb_in.CYC <= '0'; wb_in.STB <= '0'; - waitnclk(30); + waitnclk(DEL); wb_in.ADR <= std_logic_vector(to_unsigned(256, 32)); wb_in.CYC <= '1'; wb_in.STB <= '1'; wb_in.WE <= '0'; wait until wb_out.ACK = '1'; + waitclk; wb_in.CYC <= '0'; - wb_in.STB <= '0'; - waitnclk(30); + wb_in.STB <= '0'; + waitnclk(DEL); wb_in.ADR <= std_logic_vector(to_unsigned(256, 32)); wb_in.DAT <= x"b000b1e5"; @@ -146,27 +164,59 @@ begin wb_in.STB <= '1'; wb_in.WE <= '1'; wait until wb_out.ACK = '1'; + waitclk; wb_in.CYC <= '0'; wb_in.STB <= '0'; - waitnclk(30); + waitnclk(DEL); wb_in.ADR <= std_logic_vector(to_unsigned(256, 32)); + wb_in.DAT <= x"12345678"; wb_in.CYC <= '1'; wb_in.STB <= '1'; wb_in.WE <= '0'; wait until wb_out.ACK = '1'; + waitclk; wb_in.CYC <= '0'; wb_in.STB <= '0'; - waitnclk(30); + assert wb_out.DAT = x"b000b1e5" report "Readback error @ 256" severity error; + waitnclk(DEL); wb_in.ADR <= std_logic_vector(to_unsigned(4, 32)); wb_in.CYC <= '1'; wb_in.STB <= '1'; wb_in.WE <= '0'; wait until wb_out.ACK = '1'; + waitclk; wb_in.CYC <= '0'; wb_in.STB <= '0'; - waitnclk(30); + assert wb_out.DAT = x"deadbeef" report "Readback error @ 4 [2]" severity error; + waitnclk(DEL); + + wb_in.ADR <= std_logic_vector(to_unsigned(0, 32)); + wb_in.CYC <= '1'; + wb_in.STB <= '1'; + wb_in.WE <= '0'; + wait until wb_out.ACK = '1'; + waitclk; + wb_in.CYC <= '0'; + wb_in.STB <= '0'; + assert wb_out.DAT = x"00010203" report "Readback error @ 0 [2]" severity error; + waitnclk(DEL); + + wb_in.ADR <= std_logic_vector(to_unsigned(8, 32)); + wb_in.CYC <= '1'; + wb_in.STB <= '1'; + wb_in.WE <= '0'; + wait until wb_out.ACK = '1'; + waitclk; + wb_in.CYC <= '0'; + wb_in.STB <= '0'; + assert wb_out.DAT = x"600dbee2" report "Readback error @ 8 [2]" severity error; + waitnclk(DEL); + + wait for 10 us; + report "--- TEST FINISHED ---" severity failure; + wait; end process test; diff --git a/cores/flashrom-wb/flashrom_spi.vhd b/cores/flashrom-wb/flashrom_spi.vhd index 7f01e1a..9d330cd 100644 --- a/cores/flashrom-wb/flashrom_spi.vhd +++ b/cores/flashrom-wb/flashrom_spi.vhd @@ -4,9 +4,10 @@ use ieee.numeric_std.all; entity flashrom_spi is generic( - clk_divider : integer range 2 to 9999 := 2; - max_word_length : integer := 32; - max_dummy_bits : integer := 8 + clk_divider : integer range 2 to 9999 := 2; + max_word_length : integer := 32; + max_dummy_bits : integer := 8; + cs_inactive_cycles : integer := 10 ); port( clk : in std_logic; @@ -46,13 +47,15 @@ architecture RTL of flashrom_spi is signal pseudoEdge : boolean; signal dummy_passed : boolean; signal prevent_retrig : boolean; + signal cs_inactive_cnt : integer range 0 to cs_inactive_cycles; begin toSpi : process(clk, rst) is procedure default_state is begin - data_next <= '0'; - data_out_valid <= '0'; - pseudoEdge <= false; + data_next <= '0'; + data_out_valid <= '0'; + pseudoEdge <= false; + cs_inactive_cnt <= 0; end procedure default_state; procedure reset_state is @@ -78,20 +81,26 @@ begin else case state is when IDLE => - prevent_retrig <= false; - delayCycle <= '0'; - spi_sck <= '0'; - oneBitRead <= '0'; - dummy_passed <= false; - data_out <= (others => '0'); + cs_inactive_cnt <= cs_inactive_cnt; + prevent_retrig <= false; + delayCycle <= '0'; + spi_sck <= '0'; + oneBitRead <= '0'; + dummy_passed <= false; + data_out <= (others => '0'); if ckDiv = clk_divider - 2 then -- ensures cs inactive time between transactions - if data_in_valid = '1' then - ckDiv <= 0; - state <= TX; - bitCounter <= 0; - bitCounterIn <= 0; - data_in_length_i <= 0; - pseudoEdge <= true; + if cs_inactive_cnt = cs_inactive_cycles then + if data_in_valid = '1' then + ckDiv <= 0; + state <= TX; + bitCounter <= 0; + bitCounterIn <= 0; + data_in_length_i <= 0; + pseudoEdge <= true; + end if; + else + ckDiv <= 0; + cs_inactive_cnt <= cs_inactive_cnt + 1; end if; else ckDiv <= ckDiv + 1; @@ -125,7 +134,7 @@ begin bitCounter <= bitCounter + 1; shiftreg <= shiftreg(shiftreg'high - 1 downto 0) & '0'; end if; - --else -- spi_sck = '1' (falling edge) + --else -- spi_sck = '1' (falling edge) data_out <= data_out(data_out'high - 1 downto 0) & spi_so; if bitCounterIn = 0 then diff --git a/cores/flashrom-wb/flashrom_wb.vhd b/cores/flashrom-wb/flashrom_wb.vhd index 2244121..3a52a32 100644 --- a/cores/flashrom-wb/flashrom_wb.vhd +++ b/cores/flashrom-wb/flashrom_wb.vhd @@ -100,6 +100,7 @@ begin state <= WAITCON; bootup_complete <= '0'; dirty <= '0'; + cache_control_addr <= (others => '0'); end procedure reset_state; begin if rst = '1' then @@ -115,7 +116,7 @@ begin state <= IDLE; end if; when IDLE => - if ready = '1' and delay_cycle = '0' then + if ready = '1' and delay_cycle = '0' and bootup_complete = '1' then if wb_in.CYC = '1' and wb_in.STB = '1' then if (requested_page /= current_page) then -- Page swap required if (dirty = '0') then