Added CS inactive delay + some other fixes
This commit is contained in:
parent
e053da3ae1
commit
d33b027e28
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user