Added CS inactive delay + some other fixes

This commit is contained in:
Markus Koch 2017-02-26 15:13:19 +01:00
parent e053da3ae1
commit d33b027e28
3 changed files with 90 additions and 30 deletions

View File

@ -85,6 +85,8 @@ begin
end process clock_driver; end process clock_driver;
test : process is test : process is
constant DEL : integer := 2;
begin begin
rst <= '1'; rst <= '1';
wb_in.ADR <= (others => '0'); wb_in.ADR <= (others => '0');
@ -101,16 +103,17 @@ begin
wait until wb_out.ACK = '1'; wait until wb_out.ACK = '1';
wb_in.CYC <= '0'; wb_in.CYC <= '0';
wb_in.STB <= '0'; wb_in.STB <= '0';
waitnclk(30); waitnclk(DEL);
wb_in.ADR <= std_logic_vector(to_unsigned(4, 32)); wb_in.ADR <= std_logic_vector(to_unsigned(4, 32));
wb_in.CYC <= '1'; wb_in.CYC <= '1';
wb_in.STB <= '1'; wb_in.STB <= '1';
wb_in.WE <= '0'; wb_in.WE <= '0';
wait until wb_out.ACK = '1'; wait until wb_out.ACK = '1';
waitclk;
wb_in.CYC <= '0'; wb_in.CYC <= '0';
wb_in.STB <= '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.ADR <= std_logic_vector(to_unsigned(4, 32));
wb_in.DAT <= x"deadbeef"; wb_in.DAT <= x"deadbeef";
@ -118,27 +121,42 @@ begin
wb_in.STB <= '1'; wb_in.STB <= '1';
wb_in.WE <= '1'; wb_in.WE <= '1';
wait until wb_out.ACK = '1'; wait until wb_out.ACK = '1';
waitclk;
wb_in.CYC <= '0'; wb_in.CYC <= '0';
wb_in.STB <= '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.ADR <= std_logic_vector(to_unsigned(4, 32));
wb_in.CYC <= '1'; wb_in.CYC <= '1';
wb_in.STB <= '1'; wb_in.STB <= '1';
wb_in.WE <= '0'; wb_in.WE <= '0';
wait until wb_out.ACK = '1'; 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.CYC <= '0';
wb_in.STB <= '0'; wb_in.STB <= '0';
waitnclk(30); waitnclk(DEL);
wb_in.ADR <= std_logic_vector(to_unsigned(256, 32)); wb_in.ADR <= std_logic_vector(to_unsigned(256, 32));
wb_in.CYC <= '1'; wb_in.CYC <= '1';
wb_in.STB <= '1'; wb_in.STB <= '1';
wb_in.WE <= '0'; wb_in.WE <= '0';
wait until wb_out.ACK = '1'; wait until wb_out.ACK = '1';
waitclk;
wb_in.CYC <= '0'; wb_in.CYC <= '0';
wb_in.STB <= '0'; wb_in.STB <= '0';
waitnclk(30); waitnclk(DEL);
wb_in.ADR <= std_logic_vector(to_unsigned(256, 32)); wb_in.ADR <= std_logic_vector(to_unsigned(256, 32));
wb_in.DAT <= x"b000b1e5"; wb_in.DAT <= x"b000b1e5";
@ -146,27 +164,59 @@ begin
wb_in.STB <= '1'; wb_in.STB <= '1';
wb_in.WE <= '1'; wb_in.WE <= '1';
wait until wb_out.ACK = '1'; wait until wb_out.ACK = '1';
waitclk;
wb_in.CYC <= '0'; wb_in.CYC <= '0';
wb_in.STB <= '0'; wb_in.STB <= '0';
waitnclk(30); waitnclk(DEL);
wb_in.ADR <= std_logic_vector(to_unsigned(256, 32)); wb_in.ADR <= std_logic_vector(to_unsigned(256, 32));
wb_in.DAT <= x"12345678";
wb_in.CYC <= '1'; wb_in.CYC <= '1';
wb_in.STB <= '1'; wb_in.STB <= '1';
wb_in.WE <= '0'; wb_in.WE <= '0';
wait until wb_out.ACK = '1'; wait until wb_out.ACK = '1';
waitclk;
wb_in.CYC <= '0'; wb_in.CYC <= '0';
wb_in.STB <= '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.ADR <= std_logic_vector(to_unsigned(4, 32));
wb_in.CYC <= '1'; wb_in.CYC <= '1';
wb_in.STB <= '1'; wb_in.STB <= '1';
wb_in.WE <= '0'; wb_in.WE <= '0';
wait until wb_out.ACK = '1'; wait until wb_out.ACK = '1';
waitclk;
wb_in.CYC <= '0'; wb_in.CYC <= '0';
wb_in.STB <= '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; wait;
end process test; end process test;

View File

@ -4,9 +4,10 @@ use ieee.numeric_std.all;
entity flashrom_spi is entity flashrom_spi is
generic( generic(
clk_divider : integer range 2 to 9999 := 2; clk_divider : integer range 2 to 9999 := 2;
max_word_length : integer := 32; max_word_length : integer := 32;
max_dummy_bits : integer := 8 max_dummy_bits : integer := 8;
cs_inactive_cycles : integer := 10
); );
port( port(
clk : in std_logic; clk : in std_logic;
@ -46,13 +47,15 @@ architecture RTL of flashrom_spi is
signal pseudoEdge : boolean; signal pseudoEdge : boolean;
signal dummy_passed : boolean; signal dummy_passed : boolean;
signal prevent_retrig : boolean; signal prevent_retrig : boolean;
signal cs_inactive_cnt : integer range 0 to cs_inactive_cycles;
begin begin
toSpi : process(clk, rst) is toSpi : process(clk, rst) is
procedure default_state is procedure default_state is
begin begin
data_next <= '0'; data_next <= '0';
data_out_valid <= '0'; data_out_valid <= '0';
pseudoEdge <= false; pseudoEdge <= false;
cs_inactive_cnt <= 0;
end procedure default_state; end procedure default_state;
procedure reset_state is procedure reset_state is
@ -78,20 +81,26 @@ begin
else else
case state is case state is
when IDLE => when IDLE =>
prevent_retrig <= false; cs_inactive_cnt <= cs_inactive_cnt;
delayCycle <= '0'; prevent_retrig <= false;
spi_sck <= '0'; delayCycle <= '0';
oneBitRead <= '0'; spi_sck <= '0';
dummy_passed <= false; oneBitRead <= '0';
data_out <= (others => '0'); dummy_passed <= false;
data_out <= (others => '0');
if ckDiv = clk_divider - 2 then -- ensures cs inactive time between transactions if ckDiv = clk_divider - 2 then -- ensures cs inactive time between transactions
if data_in_valid = '1' then if cs_inactive_cnt = cs_inactive_cycles then
ckDiv <= 0; if data_in_valid = '1' then
state <= TX; ckDiv <= 0;
bitCounter <= 0; state <= TX;
bitCounterIn <= 0; bitCounter <= 0;
data_in_length_i <= 0; bitCounterIn <= 0;
pseudoEdge <= true; data_in_length_i <= 0;
pseudoEdge <= true;
end if;
else
ckDiv <= 0;
cs_inactive_cnt <= cs_inactive_cnt + 1;
end if; end if;
else else
ckDiv <= ckDiv + 1; ckDiv <= ckDiv + 1;
@ -125,7 +134,7 @@ begin
bitCounter <= bitCounter + 1; bitCounter <= bitCounter + 1;
shiftreg <= shiftreg(shiftreg'high - 1 downto 0) & '0'; shiftreg <= shiftreg(shiftreg'high - 1 downto 0) & '0';
end if; 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; data_out <= data_out(data_out'high - 1 downto 0) & spi_so;
if bitCounterIn = 0 then if bitCounterIn = 0 then

View File

@ -100,6 +100,7 @@ begin
state <= WAITCON; state <= WAITCON;
bootup_complete <= '0'; bootup_complete <= '0';
dirty <= '0'; dirty <= '0';
cache_control_addr <= (others => '0');
end procedure reset_state; end procedure reset_state;
begin begin
if rst = '1' then if rst = '1' then
@ -115,7 +116,7 @@ begin
state <= IDLE; state <= IDLE;
end if; end if;
when IDLE => 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 wb_in.CYC = '1' and wb_in.STB = '1' then
if (requested_page /= current_page) then -- Page swap required if (requested_page /= current_page) then -- Page swap required
if (dirty = '0') then if (dirty = '0') then