flashrom: Added Wishbone controller

This commit is contained in:
Markus Koch 2016-12-10 20:51:00 +01:00
parent 9051e3385b
commit e053da3ae1
3 changed files with 464 additions and 0 deletions

173
bench/bench_flashrom_wb.vhd Normal file
View File

@ -0,0 +1,173 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library design;
use design.all;
library ip;
use ip.wishbone_package.all;
entity bench_flashrom_wb is
end entity bench_flashrom_wb;
architecture RTL of bench_flashrom_wb is
signal clk : std_logic;
signal rst : std_logic;
signal clr : std_logic;
signal wb_in : wishbone_v3_slave_in;
signal wb_out : wishbone_v3_slave_out;
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 spi_busy : std_logic;
procedure waitclk is
begin
wait until rising_edge(clk);
end procedure waitclk;
procedure waitnclk(n : integer) is
begin
for i in 1 to n loop
wait until rising_edge(clk);
end loop;
end procedure waitnclk;
procedure strobe(signal s : out std_logic) is
begin
s <= '1';
waitclk;
s <= '0';
waitclk;
end procedure strobe;
begin
DataFlash_inst : entity work.DataFlash
generic map(
flashmemory => "devicemodels/memory.txt",
Rapid_interface => true,
fsck => 66,
DEVICE => "AT45DB011D", --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_wb_inst : entity design.flashrom_wb
port map(
clk => clk,
rst => rst,
clr => clr,
wb_in => wb_in,
wb_out => wb_out,
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
);
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;
test : process is
begin
rst <= '1';
wb_in.ADR <= (others => '0');
wait for 10 ns * 2;
wait until (rising_edge(clk));
rst <= '0';
wait for 10 ns * 2;
wait until (rising_edge(clk));
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';
wb_in.CYC <= '0';
wb_in.STB <= '0';
waitnclk(30);
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';
wb_in.CYC <= '0';
wb_in.STB <= '0';
waitnclk(30);
wb_in.ADR <= std_logic_vector(to_unsigned(4, 32));
wb_in.DAT <= x"deadbeef";
wb_in.CYC <= '1';
wb_in.STB <= '1';
wb_in.WE <= '1';
wait until wb_out.ACK = '1';
wb_in.CYC <= '0';
wb_in.STB <= '0';
waitnclk(30);
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';
wb_in.CYC <= '0';
wb_in.STB <= '0';
waitnclk(30);
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';
wb_in.CYC <= '0';
wb_in.STB <= '0';
waitnclk(30);
wb_in.ADR <= std_logic_vector(to_unsigned(256, 32));
wb_in.DAT <= x"b000b1e5";
wb_in.CYC <= '1';
wb_in.STB <= '1';
wb_in.WE <= '1';
wait until wb_out.ACK = '1';
wb_in.CYC <= '0';
wb_in.STB <= '0';
waitnclk(30);
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';
wb_in.CYC <= '0';
wb_in.STB <= '0';
waitnclk(30);
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';
wb_in.CYC <= '0';
wb_in.STB <= '0';
waitnclk(30);
wait;
end process test;
end architecture RTL;

View File

@ -0,0 +1,202 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library ip;
use ip.wishbone_package.all;
use ip.all;
use work.flashrom_pkg.all;
entity flashrom_wb is
port(
clk : in std_logic;
rst : in std_logic;
clr : in std_logic;
-- Wishbone
wb_in : in wishbone_v3_slave_in;
wb_out : out wishbone_v3_slave_out;
-- SPI Flash Hardware Signals
spi_si : out std_logic; -- spi serial in
spi_so : in std_logic; -- spi serial out
spi_sck : out std_logic; -- spi clock
spi_reset_n : out std_logic; -- spi hard reset
spi_cs_n : out std_logic; -- spi chip select
spi_wp_n : out std_logic -- spi write protect
);
end entity flashrom_wb;
architecture rtl of flashrom_wb is
-- Controller Signals
signal current_page : std_logic_vector(FLASHROM_PAGE_ADDR_WIDTH - 1 downto 0);
signal ready : std_logic;
signal sync_stb : std_logic;
signal load_stb : std_logic;
signal status_update_stb : std_logic;
signal status : std_logic_vector(7 downto 0);
signal info : std_logic_vector(31 downto 0);
signal data_in : std_logic_vector(7 downto 0);
signal data_in_next : std_logic;
signal data_out : std_logic_vector(7 downto 0);
signal data_out_valid : std_logic;
--
signal bootup_complete : std_logic;
type state_t is (WAITCON, IDLE, LOADPAGE, WRITEPAGE);
signal state : state_t;
--
signal requested_page : std_logic_vector(current_page'range);
signal requested_byte : std_logic_vector(7 downto 0);
signal dirty : std_logic;
-- Cache Memory
type cache_t is array (0 to 63) of std_logic_vector(31 downto 0);
signal cache : cache_t;
signal cache_addr : std_logic_vector(7 downto 0);
signal cache_control_addr : unsigned(7 downto 0);
signal cache_we : std_logic;
signal cache_dOut : std_logic_vector(31 downto 0);
signal cache_dIn : std_logic_vector(31 downto 0);
signal data_in_shift : std_logic_vector(31 downto 0);
signal delay_cycle : std_logic;
begin
flashrom_controller_inst : entity work.flashrom_controller
port map(
clk => clk,
rst => rst,
clr => clr,
page => current_page,
ready => ready,
sync_stb => sync_stb,
load_stb => load_stb,
status_update_stb => status_update_stb,
status => status,
info => info,
data_in => data_in,
data_in_next => data_in_next,
data_out => data_out,
data_out_valid => data_out_valid,
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
);
wb_ctrl : process(clk, rst) is
procedure default_state is
begin
load_stb <= '0';
sync_stb <= '0';
wb_out.ACK <= '0';
cache_we <= '0';
delay_cycle <= '0';
end procedure default_state;
procedure reset_state is
begin
default_state;
state <= WAITCON;
bootup_complete <= '0';
dirty <= '0';
end procedure reset_state;
begin
if rst = '1' then
reset_state;
elsif rising_edge(clk) then
default_state;
if clr = '1' then
reset_state;
else
case state is
when WAITCON =>
if ready = '1' then
state <= IDLE;
end if;
when IDLE =>
if ready = '1' and delay_cycle = '0' 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
state <= LOADPAGE;
load_stb <= '1';
cache_control_addr <= (others => '1'); -- Wraparound...
end if;
if (dirty = '1') then
state <= WRITEPAGE;
sync_stb <= '1';
cache_control_addr <= to_unsigned(1, cache_control_addr'length);
end if;
else -- Same page
wb_out.ACK <= '1';
if wb_in.WE = '1' then
dirty <= '1';
cache_dIn <= wb_in.DAT;
cache_we <= '1';
cache_control_addr <= unsigned(wb_in.ADR(7 downto 0));
end if;
end if;
end if;
end if;
if (bootup_complete = '0') then
state <= LOADPAGE;
load_stb <= '1';
cache_control_addr <= (others => '1'); -- Wraparound...
end if;
when LOADPAGE =>
bootup_complete <= '1';
current_page <= requested_page;
if data_out_valid = '1' then
cache_dIn <= cache_dIn(23 downto 0) & data_out;
cache_control_addr <= cache_control_addr + 1;
cache_we <= '1';
if cache_control_addr = 254 then
state <= IDLE;
delay_cycle <= '1';
end if;
end if;
when WRITEPAGE =>
if cache_control_addr = 1 then
data_in_shift <= cache_dOut;
end if;
if data_in_next = '1' then
if cache_control_addr(1 downto 0) = "00" then
data_in_shift <= cache_dOut;
else
data_in_shift <= data_in_shift(23 downto 0) & x"00";
end if;
cache_control_addr <= cache_control_addr + 1;
if cache_control_addr = 0 then
state <= IDLE;
dirty <= '0';
delay_cycle <= '1';
end if;
end if;
end case;
end if;
end if;
end process wb_ctrl;
requested_page <= wb_in.ADR(FLASHROM_PAGE_ADDR_WIDTH + 8 - 1 downto 8);
requested_byte <= wb_in.ADR(7 downto 0);
data_in <= data_in_shift(31 downto 24);
-- Cache Memory Controller
cache_mem_p : process(clk, rst) is
begin
if rst = '1' then
cache_dOut <= (others => '0');
elsif rising_edge(clk) then
cache_dOut <= cache(to_integer(unsigned(cache_addr(cache_addr'length - 1 downto 2))));
if cache_we = '1' then
cache(to_integer(unsigned(cache_addr(cache_addr'length - 1 downto 2)))) <= cache_dIn;
end if;
end if;
end process cache_mem_p;
cache_addr <= wb_in.ADR(7 downto 0) when (state = IDLE and cache_we = '0') else std_logic_vector(cache_control_addr);
wb_out.DAT <= cache_dOut;
end architecture rtl;

89
wave/flashrom_wb.do Normal file
View File

@ -0,0 +1,89 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/clk
add wave -noupdate /bench_flashrom_wb/DataFlash_inst/RDYBSY
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/rst
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/clr
add wave -noupdate -expand /bench_flashrom_wb/flashrom_wb_inst/wb_in
add wave -noupdate -expand /bench_flashrom_wb/flashrom_wb_inst/wb_out
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/spi_si
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/spi_so
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/spi_sck
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/spi_reset_n
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/spi_cs_n
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/spi_wp_n
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/current_page
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/ready
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/sync_stb
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/load_stb
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/status_update_stb
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/status
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/info
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/data_in
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/data_in_next
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/data_out
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/data_out_valid
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/bootup_complete
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/state
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/requested_page
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/requested_byte
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/dirty
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/cache_we
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/cache_addr
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/cache_control_addr
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/cache_dOut
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/cache_dIn
add wave -noupdate /bench_flashrom_wb/flashrom_wb_inst/cache
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/rst
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/clr
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/ready
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/page
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/sync_stb
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/load_stb
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/status_update_stb
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/status
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/info
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/data_in
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/data_in_next
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/data_out
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/data_out_valid
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spi_si
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spi_so
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spi_sck
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spi_reset_n
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spi_cs_n
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spi_wp_n
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/state
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spif_data_in_valid
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spif_data_in
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spif_data_in_length
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spif_data_next
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spif_data_out
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spif_data_out_valid
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spif_data_out_length
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/words_sent
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spif_data_out_dummy_bits
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spif_transmission_active
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/command_is_latched
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/spif_max_word_length
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/max_dummy_bits
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/bootup_delay
add wave -noupdate -expand -group flashrom-ctrlr /bench_flashrom_wb/flashrom_wb_inst/flashrom_controller_inst/status_reg_poll_delay
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {182209 ns} 0}
quietly wave cursor active 1
configure wave -namecolwidth 173
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ns
update
WaveRestoreZoom {168208 ns} {199740 ns}