flashrom: Changed SPI core to conform to DataFlash behavior, changed main fsm to request the right number of transactions
This commit is contained in:
parent
a1efcf62c4
commit
9b379e70fe
@ -1,92 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
entity bench_flashrom_spi is
|
|
||||||
end entity bench_flashrom_spi;
|
|
||||||
|
|
||||||
library design;
|
|
||||||
use design.all;
|
|
||||||
|
|
||||||
architecture RTL of bench_flashrom_spi is
|
|
||||||
signal clk : std_logic;
|
|
||||||
signal spi_clk : std_logic;
|
|
||||||
signal rst : std_logic;
|
|
||||||
signal spi_si : std_logic;
|
|
||||||
signal spi_so : std_logic;
|
|
||||||
signal spi_sck : std_logic;
|
|
||||||
signal spi_reset_n : std_logic;
|
|
||||||
signal spi_cs_n : std_logic;
|
|
||||||
signal spi_wp_n : std_logic;
|
|
||||||
signal toSpiDataIn : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
||||||
signal toSpiWrite : STD_LOGIC;
|
|
||||||
signal toSpiFull : STD_LOGIC;
|
|
||||||
signal fromSpiDataOut : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
||||||
signal fromSpiRead : STD_LOGIC;
|
|
||||||
signal fromSpiEmpty : STD_LOGIC;
|
|
||||||
|
|
||||||
procedure waitclk is
|
|
||||||
begin
|
|
||||||
wait until rising_edge(clk);
|
|
||||||
end procedure waitclk;
|
|
||||||
|
|
||||||
procedure strobe(signal s : out std_logic) is
|
|
||||||
begin
|
|
||||||
s <= '1';
|
|
||||||
waitclk;
|
|
||||||
s <= '0';
|
|
||||||
waitclk;
|
|
||||||
end procedure strobe;
|
|
||||||
|
|
||||||
begin
|
|
||||||
flashrom_spi_inst : entity design.flashrom_spi
|
|
||||||
port map(
|
|
||||||
spi_clk => spi_clk,
|
|
||||||
clk => clk,
|
|
||||||
rst => rst,
|
|
||||||
spi_si => spi_si,
|
|
||||||
spi_so => spi_so,
|
|
||||||
spi_sck => spi_sck,
|
|
||||||
spi_reset_n => spi_reset_n,
|
|
||||||
spi_cs_n => spi_cs_n,
|
|
||||||
spi_wp_n => spi_wp_n,
|
|
||||||
toSpiDataIn => toSpiDataIn,
|
|
||||||
toSpiWrite => toSpiWrite,
|
|
||||||
toSpiFull => toSpiFull,
|
|
||||||
fromSpiDataOut => fromSpiDataOut,
|
|
||||||
fromSpiRead => fromSpiRead,
|
|
||||||
fromSpiEmpty => fromSpiEmpty
|
|
||||||
);
|
|
||||||
|
|
||||||
clock_driver : process
|
|
||||||
constant period : time := 10 ns;
|
|
||||||
begin
|
|
||||||
clk <= '0';
|
|
||||||
wait for period / 2;
|
|
||||||
clk <= '1';
|
|
||||||
wait for period / 2;
|
|
||||||
end process clock_driver;
|
|
||||||
spi_clk <= clk;
|
|
||||||
|
|
||||||
test : process is
|
|
||||||
begin
|
|
||||||
spi_so <= '0';
|
|
||||||
rst <= '1';
|
|
||||||
toSpiDataIn <= (others => '0');
|
|
||||||
toSpiWrite <= '0';
|
|
||||||
fromSpiRead <= '0';
|
|
||||||
|
|
||||||
wait for 40 ns;
|
|
||||||
|
|
||||||
rst <= '0';
|
|
||||||
wait for 20 ns;
|
|
||||||
toSpiDataIn <= x"55";
|
|
||||||
strobe(toSpiWrite);
|
|
||||||
waitclk;
|
|
||||||
toSpiDataIn <= x"AA";
|
|
||||||
strobe(toSpiWrite);
|
|
||||||
|
|
||||||
wait;
|
|
||||||
end process test;
|
|
||||||
|
|
||||||
end architecture RTL;
|
|
@ -49,8 +49,26 @@ architecture rtl of bench_flashrom_controller is
|
|||||||
signal spi_reset_n : std_logic;
|
signal spi_reset_n : std_logic;
|
||||||
signal spi_cs_n : std_logic;
|
signal spi_cs_n : std_logic;
|
||||||
signal spi_wp_n : std_logic;
|
signal spi_wp_n : std_logic;
|
||||||
|
signal spi_busy : std_logic;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
DataFlash_inst : entity work.DataFlash
|
||||||
|
generic map(
|
||||||
|
flashmemory => "devicemodels/memory.txt",
|
||||||
|
Rapid_interface => true,
|
||||||
|
fsck => 66,
|
||||||
|
DEVICE => "AT45DB011D",
|
||||||
|
Tsck => 13.6 ns)
|
||||||
|
port map(
|
||||||
|
SI => spi_si,
|
||||||
|
CSB => spi_cs_n,
|
||||||
|
SCK => spi_sck,
|
||||||
|
WPB => spi_wp_n,
|
||||||
|
RESETB => spi_reset_n,
|
||||||
|
SO => spi_so,
|
||||||
|
RDYBSY => spi_busy
|
||||||
|
);
|
||||||
|
|
||||||
flashrom_controller_inst : entity design.flashrom_controller
|
flashrom_controller_inst : entity design.flashrom_controller
|
||||||
port map(
|
port map(
|
||||||
clk => clk,
|
clk => clk,
|
||||||
@ -89,7 +107,7 @@ begin
|
|||||||
bench : process is
|
bench : process is
|
||||||
begin
|
begin
|
||||||
rst <= '1';
|
rst <= '1';
|
||||||
clr <= '0';
|
clr <= '0';
|
||||||
wait for 10 ns * 2;
|
wait for 10 ns * 2;
|
||||||
wait until (rising_edge(clk));
|
wait until (rising_edge(clk));
|
||||||
rst <= '0';
|
rst <= '0';
|
||||||
@ -102,98 +120,4 @@ begin
|
|||||||
wait;
|
wait;
|
||||||
end process bench;
|
end process bench;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- debugging only!
|
|
||||||
spi_so_p : process is
|
|
||||||
procedure spitx(constant value : std_logic) is
|
|
||||||
begin
|
|
||||||
spi_so <= value;
|
|
||||||
wait until rising_edge(spi_sck);
|
|
||||||
end procedure spitx;
|
|
||||||
begin
|
|
||||||
spi_so <= '0';
|
|
||||||
wait until rising_edge(spi_sck);
|
|
||||||
wait until rising_edge(spi_sck);
|
|
||||||
|
|
||||||
|
|
||||||
-- 0x0 (dummy)
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
-- INFO FOO: 0x1F
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('1');
|
|
||||||
spitx('1');
|
|
||||||
spitx('1');
|
|
||||||
spitx('1');
|
|
||||||
spitx('1');
|
|
||||||
--
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('1');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('1');
|
|
||||||
spitx('1');
|
|
||||||
spitx('1');
|
|
||||||
--
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('1');
|
|
||||||
--
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- 0x88
|
|
||||||
spitx('1');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('1');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
-- 0x44
|
|
||||||
spitx('0');
|
|
||||||
spitx('1');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('1');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
-- 0x22
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('1');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('0');
|
|
||||||
spitx('1');
|
|
||||||
spitx('0');
|
|
||||||
|
|
||||||
wait;
|
|
||||||
end process spi_so_p;
|
|
||||||
end architecture rtl;
|
end architecture rtl;
|
||||||
|
@ -38,6 +38,7 @@ end entity flashrom_controller;
|
|||||||
architecture RTL of flashrom_controller is
|
architecture RTL of flashrom_controller is
|
||||||
constant spif_max_word_length : integer := 32;
|
constant spif_max_word_length : integer := 32;
|
||||||
constant max_dummy_bits : integer := 16;
|
constant max_dummy_bits : integer := 16;
|
||||||
|
constant bootup_delay : integer := 4000;
|
||||||
|
|
||||||
type state_t is (INIT, GETINFO, IDLE);
|
type state_t is (INIT, GETINFO, IDLE);
|
||||||
signal state : state_t;
|
signal state : state_t;
|
||||||
@ -80,6 +81,8 @@ begin
|
|||||||
transmission_active => spif_transmission_active);
|
transmission_active => spif_transmission_active);
|
||||||
|
|
||||||
flashrom_controller_p : process(clk, rst) is
|
flashrom_controller_p : process(clk, rst) is
|
||||||
|
variable temp_cnt : integer range 0 to bootup_delay;
|
||||||
|
|
||||||
procedure default_state is
|
procedure default_state is
|
||||||
begin
|
begin
|
||||||
spi_reset_n <= '1';
|
spi_reset_n <= '1';
|
||||||
@ -97,6 +100,8 @@ begin
|
|||||||
spif_data_in_length <= 0;
|
spif_data_in_length <= 0;
|
||||||
spif_data_out_length <= 0;
|
spif_data_out_length <= 0;
|
||||||
spif_data_out_dummy_bits <= 0;
|
spif_data_out_dummy_bits <= 0;
|
||||||
|
|
||||||
|
temp_cnt := 0;
|
||||||
end procedure reset_state;
|
end procedure reset_state;
|
||||||
begin
|
begin
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
@ -109,20 +114,28 @@ begin
|
|||||||
case state is
|
case state is
|
||||||
when INIT =>
|
when INIT =>
|
||||||
words_sent <= 0;
|
words_sent <= 0;
|
||||||
state <= GETINFO;
|
if temp_cnt = bootup_delay then
|
||||||
|
temp_cnt := 0;
|
||||||
|
state <= GETINFO;
|
||||||
|
else
|
||||||
|
temp_cnt := temp_cnt + 1;
|
||||||
|
end if;
|
||||||
when GETINFO =>
|
when GETINFO =>
|
||||||
spif_data_in_length <= 16; -- Other bits after OpCode are don't care, so just repeat OPC
|
spif_data_in_length <= 8; -- Other bits after OpCode are don't care, so just repeat OPC
|
||||||
spif_data_out_length <= 32;
|
spif_data_out_length <= 32;
|
||||||
spif_data_out_dummy_bits <= 8;
|
spif_data_out_dummy_bits <= 8;
|
||||||
spif_data_in_valid <= '1';
|
spif_data_in_valid <= '1';
|
||||||
spif_data_in <= FLASHROM_COMMAND_MANUFACTURER_ID & padBits(spif_data_in, FLASHROM_COMMAND_MANUFACTURER_ID);
|
spif_data_in <= FLASHROM_COMMAND_MANUFACTURER_ID & padBits(spif_data_in, FLASHROM_COMMAND_MANUFACTURER_ID);
|
||||||
if spif_data_out_valid = '1' then
|
if spif_data_out_valid = '1' then
|
||||||
info <= spif_data_out;
|
info <= spif_data_out;
|
||||||
state <= IDLE;
|
state <= IDLE;
|
||||||
spif_data_in_valid <= '0';
|
|
||||||
end if;
|
end if;
|
||||||
when IDLE =>
|
if temp_cnt = 5 then
|
||||||
null;
|
spif_data_in_valid <= '0';
|
||||||
|
elsif spif_data_next = '1' then
|
||||||
|
temp_cnt := temp_cnt + 1;
|
||||||
|
end if;
|
||||||
|
when IDLE => null;
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
@ -43,6 +43,7 @@ architecture RTL of flashrom_spi is
|
|||||||
signal data_out_length_i : integer range 0 to max_word_length;
|
signal data_out_length_i : integer range 0 to max_word_length;
|
||||||
signal delayCycle : std_logic;
|
signal delayCycle : std_logic;
|
||||||
signal oneBitRead : std_logic;
|
signal oneBitRead : std_logic;
|
||||||
|
signal pseudoEdge : boolean;
|
||||||
signal dummy_passed : boolean;
|
signal dummy_passed : boolean;
|
||||||
begin
|
begin
|
||||||
toSpi : process(clk, rst) is
|
toSpi : process(clk, rst) is
|
||||||
@ -50,6 +51,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
data_next <= '0';
|
data_next <= '0';
|
||||||
data_out_valid <= '0';
|
data_out_valid <= '0';
|
||||||
|
pseudoEdge <= false;
|
||||||
end procedure default_state;
|
end procedure default_state;
|
||||||
|
|
||||||
procedure reset_state is
|
procedure reset_state is
|
||||||
@ -85,11 +87,15 @@ begin
|
|||||||
bitCounter <= 0;
|
bitCounter <= 0;
|
||||||
bitCounterIn <= 0;
|
bitCounterIn <= 0;
|
||||||
data_in_length_i <= 0;
|
data_in_length_i <= 0;
|
||||||
|
pseudoEdge <= true;
|
||||||
end if;
|
end if;
|
||||||
|
ckDiv <= 0;
|
||||||
when TX =>
|
when TX =>
|
||||||
if ckDiv = clk_divider - 2 then
|
if ckDiv = clk_divider - 2 or pseudoEdge then
|
||||||
spi_sck <= not spi_sck;
|
if not pseudoEdge then
|
||||||
if spi_sck = '0' then -- rising edge
|
spi_sck <= not spi_sck;
|
||||||
|
end if;
|
||||||
|
if spi_sck = '1' or pseudoEdge then -- falling edge -> provide data
|
||||||
if bitCounter = data_in_length_i then
|
if bitCounter = data_in_length_i then
|
||||||
bitCounter <= 0;
|
bitCounter <= 0;
|
||||||
if data_in_valid = '1' then
|
if data_in_valid = '1' then
|
||||||
@ -104,7 +110,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
|
||||||
|
Loading…
Reference in New Issue
Block a user