Compare commits
No commits in common. "9ff74212428e334fa14fc0f15ca8e271e97b1947" and "b01f74648e91da85bcdee7bcd04de1935f33e28b" have entirely different histories.
9ff7421242
...
b01f74648e
@ -37,7 +37,7 @@ architecture rtl of bench_flashrom_controller is
|
|||||||
signal sync_stb : std_logic;
|
signal sync_stb : std_logic;
|
||||||
signal load_stb : std_logic;
|
signal load_stb : std_logic;
|
||||||
signal status_update_stb : std_logic;
|
signal status_update_stb : std_logic;
|
||||||
signal status : std_logic_vector(7 downto 0);
|
signal status : std_logic_vector(31 downto 0);
|
||||||
signal info : std_logic_vector(31 downto 0);
|
signal info : std_logic_vector(31 downto 0);
|
||||||
signal data_in : std_logic_vector(7 downto 0);
|
signal data_in : std_logic_vector(7 downto 0);
|
||||||
signal data_in_valid : std_logic;
|
signal data_in_valid : std_logic;
|
||||||
@ -50,7 +50,6 @@ architecture rtl of bench_flashrom_controller is
|
|||||||
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;
|
signal spi_busy : std_logic;
|
||||||
signal spi_clk_cnt : integer := 0;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
DataFlash_inst : entity work.DataFlash
|
DataFlash_inst : entity work.DataFlash
|
||||||
@ -58,7 +57,7 @@ begin
|
|||||||
flashmemory => "devicemodels/memory.txt",
|
flashmemory => "devicemodels/memory.txt",
|
||||||
Rapid_interface => true,
|
Rapid_interface => true,
|
||||||
fsck => 66,
|
fsck => 66,
|
||||||
DEVICE => "AT45DB011D", --AT45DB011D
|
DEVICE => "AT45DB011D",
|
||||||
Tsck => 13.6 ns)
|
Tsck => 13.6 ns)
|
||||||
port map(
|
port map(
|
||||||
SI => spi_si,
|
SI => spi_si,
|
||||||
@ -116,30 +115,9 @@ begin
|
|||||||
wait until (rising_edge(clk));
|
wait until (rising_edge(clk));
|
||||||
|
|
||||||
-- bench code here
|
-- bench code here
|
||||||
wait until ready = '1';
|
|
||||||
strobe(load_stb);
|
|
||||||
|
|
||||||
wait until ready = '1';
|
|
||||||
strobe(load_stb);
|
|
||||||
|
|
||||||
wait until ready = '1';
|
|
||||||
strobe(status_update_stb);
|
|
||||||
|
|
||||||
wait until ready = '1';
|
|
||||||
strobe(status_update_stb);
|
|
||||||
|
|
||||||
wait until ready = '1';
|
|
||||||
strobe(status_update_stb);
|
|
||||||
|
|
||||||
wait until ready = '1';
|
|
||||||
strobe(load_stb);
|
|
||||||
wait;
|
wait;
|
||||||
end process bench;
|
end process bench;
|
||||||
|
|
||||||
spiclkcounter : process is
|
|
||||||
begin
|
|
||||||
wait until spi_sck = '1';
|
|
||||||
spi_clk_cnt <= spi_clk_cnt + 1;
|
|
||||||
end process spiclkcounter;
|
|
||||||
|
|
||||||
end architecture rtl;
|
end architecture rtl;
|
||||||
|
@ -16,7 +16,7 @@ entity flashrom_controller is
|
|||||||
sync_stb : in std_logic; -- Synchronize current memory page with chip, only sampled when ready
|
sync_stb : in std_logic; -- Synchronize current memory page with chip, only sampled when ready
|
||||||
load_stb : in std_logic; -- Load page into local buffer, only sampled when ready
|
load_stb : in std_logic; -- Load page into local buffer, only sampled when ready
|
||||||
status_update_stb : in std_logic; -- Update status vector
|
status_update_stb : in std_logic; -- Update status vector
|
||||||
status : out std_logic_vector(7 downto 0); -- value of the status register (update using status_update_stb)
|
status : out std_logic_vector(31 downto 0); -- value of the status register (update using status_update_stb)
|
||||||
info : out std_logic_vector(31 downto 0); -- value of the information register (updated on reset)
|
info : out std_logic_vector(31 downto 0); -- value of the information register (updated on reset)
|
||||||
|
|
||||||
-- Data IF
|
-- Data IF
|
||||||
@ -40,7 +40,7 @@ architecture RTL of flashrom_controller is
|
|||||||
constant max_dummy_bits : integer := 16;
|
constant max_dummy_bits : integer := 16;
|
||||||
constant bootup_delay : integer := 4000;
|
constant bootup_delay : integer := 4000;
|
||||||
|
|
||||||
type state_t is (INIT, GETINFO, GETSTATUS, IDLE);
|
type state_t is (INIT, GETINFO, IDLE);
|
||||||
signal state : state_t;
|
signal state : state_t;
|
||||||
|
|
||||||
signal spif_data_in_valid : std_logic;
|
signal spif_data_in_valid : std_logic;
|
||||||
@ -59,7 +59,7 @@ begin
|
|||||||
|
|
||||||
flashrom_spi_inst : entity work.flashrom_spi
|
flashrom_spi_inst : entity work.flashrom_spi
|
||||||
generic map(
|
generic map(
|
||||||
clk_divider => 4,
|
clk_divider => 2,
|
||||||
max_word_length => spif_max_word_length,
|
max_word_length => spif_max_word_length,
|
||||||
max_dummy_bits => max_dummy_bits)
|
max_dummy_bits => max_dummy_bits)
|
||||||
port map(
|
port map(
|
||||||
@ -82,13 +82,11 @@ begin
|
|||||||
|
|
||||||
flashrom_controller_p : process(clk, rst) is
|
flashrom_controller_p : process(clk, rst) is
|
||||||
variable temp_cnt : integer range 0 to bootup_delay;
|
variable temp_cnt : integer range 0 to bootup_delay;
|
||||||
variable done : boolean;
|
|
||||||
|
|
||||||
procedure default_state is
|
procedure default_state is
|
||||||
begin
|
begin
|
||||||
spi_reset_n <= '1';
|
spi_reset_n <= '1';
|
||||||
spif_data_in_valid <= '0';
|
spif_data_in_valid <= '0';
|
||||||
done := false;
|
|
||||||
end procedure default_state;
|
end procedure default_state;
|
||||||
|
|
||||||
procedure reset_state is
|
procedure reset_state is
|
||||||
@ -105,29 +103,6 @@ begin
|
|||||||
|
|
||||||
temp_cnt := 0;
|
temp_cnt := 0;
|
||||||
end procedure reset_state;
|
end procedure reset_state;
|
||||||
|
|
||||||
procedure run_command_single(constant data_in_length : integer; constant data_out_length : integer; constant data_out_dummy_bits : integer; constant nTxWords : integer; constant data_in : std_logic_vector(31 downto 0)) is
|
|
||||||
begin
|
|
||||||
spif_data_in_length <= data_in_length;
|
|
||||||
spif_data_out_length <= data_out_length;
|
|
||||||
spif_data_out_dummy_bits <= data_out_dummy_bits;
|
|
||||||
spif_data_in_valid <= '1';
|
|
||||||
spif_data_in <= data_in;
|
|
||||||
|
|
||||||
if temp_cnt = nTxWords then
|
|
||||||
spif_data_in_valid <= '0';
|
|
||||||
elsif spif_data_next = '1' then
|
|
||||||
temp_cnt := temp_cnt + 1;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
if spif_data_out_valid = '1' then
|
|
||||||
spif_data_in_valid <= '0';
|
|
||||||
done := true;
|
|
||||||
state <= IDLE;
|
|
||||||
temp_cnt := 0;
|
|
||||||
end if;
|
|
||||||
end procedure run_command_single;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
reset_state;
|
reset_state;
|
||||||
@ -145,27 +120,24 @@ begin
|
|||||||
else
|
else
|
||||||
temp_cnt := temp_cnt + 1;
|
temp_cnt := temp_cnt + 1;
|
||||||
end if;
|
end if;
|
||||||
when GETINFO => -- TODO: In simulation I can only call this command once?!
|
when GETINFO =>
|
||||||
run_command_single(8, 32, 8, 5, FLASHROM_COMMAND_MANUFACTURER_ID & padBits(spif_data_in, FLASHROM_COMMAND_MANUFACTURER_ID));
|
spif_data_in_length <= 8; -- Other bits after OpCode are don't care, so just repeat OPC
|
||||||
if done then
|
spif_data_out_length <= 32;
|
||||||
info <= spif_data_out;
|
spif_data_out_dummy_bits <= 8;
|
||||||
|
spif_data_in_valid <= '1';
|
||||||
|
spif_data_in <= FLASHROM_COMMAND_MANUFACTURER_ID & padBits(spif_data_in, FLASHROM_COMMAND_MANUFACTURER_ID);
|
||||||
|
if spif_data_out_valid = '1' then
|
||||||
|
info <= spif_data_out;
|
||||||
|
state <= IDLE;
|
||||||
end if;
|
end if;
|
||||||
when IDLE =>
|
if temp_cnt = 5 then
|
||||||
temp_cnt := 0;
|
spif_data_in_valid <= '0';
|
||||||
if status_update_stb = '1' then
|
elsif spif_data_next = '1' then
|
||||||
state <= GETSTATUS;
|
temp_cnt := temp_cnt + 1;
|
||||||
end if;
|
|
||||||
if load_stb = '1' then --debug only
|
|
||||||
state <= GETINFO;
|
|
||||||
end if;
|
|
||||||
when GETSTATUS =>
|
|
||||||
run_command_single(8, 8, 16, 3, FLASHROM_COMMAND_GET_STATUS & padBits(spif_data_in, FLASHROM_COMMAND_GET_STATUS));
|
|
||||||
if done then
|
|
||||||
status <= spif_data_out(7 downto 0);
|
|
||||||
end if;
|
end if;
|
||||||
|
when IDLE => null;
|
||||||
end case;
|
end case;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process flashrom_controller_p;
|
end process flashrom_controller_p;
|
||||||
ready <= '1' when state = IDLE else '0';
|
|
||||||
end architecture RTL;
|
end architecture RTL;
|
||||||
|
@ -5,7 +5,6 @@ use ieee.numeric_std.all;
|
|||||||
package flashrom_pkg is
|
package flashrom_pkg is
|
||||||
constant FLASHROM_ADDR_WIDTH : integer := 12;
|
constant FLASHROM_ADDR_WIDTH : integer := 12;
|
||||||
constant FLASHROM_COMMAND_MANUFACTURER_ID : std_logic_vector(7 downto 0) := x"9F";
|
constant FLASHROM_COMMAND_MANUFACTURER_ID : std_logic_vector(7 downto 0) := x"9F";
|
||||||
constant FLASHROM_COMMAND_GET_STATUS : std_logic_vector(7 downto 0) := x"D7";
|
|
||||||
|
|
||||||
function padBits(target : std_logic_vector; other : std_logic_vector) return std_logic_vector;
|
function padBits(target : std_logic_vector; other : std_logic_vector) return std_logic_vector;
|
||||||
end package flashrom_pkg;
|
end package flashrom_pkg;
|
||||||
|
@ -87,20 +87,14 @@ begin
|
|||||||
bitCounter <= 0;
|
bitCounter <= 0;
|
||||||
bitCounterIn <= 0;
|
bitCounterIn <= 0;
|
||||||
data_in_length_i <= 0;
|
data_in_length_i <= 0;
|
||||||
pseudoEdge <= true;
|
pseudoEdge <= true;
|
||||||
end if;
|
end if;
|
||||||
ckDiv <= 0;
|
ckDiv <= 0;
|
||||||
when TX =>
|
when TX =>
|
||||||
if ckDiv = clk_divider - 2 or pseudoEdge then
|
if ckDiv = clk_divider - 2 or pseudoEdge then
|
||||||
ckDiv <= 0;
|
|
||||||
if not pseudoEdge then
|
if not pseudoEdge then
|
||||||
spi_sck <= not spi_sck;
|
spi_sck <= not spi_sck;
|
||||||
end if;
|
end if;
|
||||||
if spi_sck = '0' and bitCounter = data_in_length_i and data_in_valid = '0' then
|
|
||||||
-- Prevent last clock cycle (make it a "passive" one)
|
|
||||||
spi_sck <= '0';
|
|
||||||
pseudoEdge <= true;
|
|
||||||
end if;
|
|
||||||
if spi_sck = '1' or pseudoEdge then -- falling edge -> provide data
|
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user