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;
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;

View File

@ -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

View File

@ -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