Bootrom, icache, bugfixes, ...

This commit is contained in:
Markus Koch 2017-03-02 22:22:43 +01:00
parent af2cad643b
commit 34d5aadf0c
5 changed files with 63 additions and 51 deletions

View File

@ -10,21 +10,22 @@ use work.flashrom_pkg.all;
entity flashrom_wb is entity flashrom_wb is
port( port(
clk : in std_logic; clk : in std_logic;
rst : in std_logic; rst : in std_logic;
clr : in std_logic; clr : in std_logic;
-- Wishbone -- Wishbone
wb_in : in wishbone_v3_slave_in; wb_in : in wishbone_v3_slave_in;
wb_out : out wishbone_v3_slave_out; wb_out : out wishbone_v3_slave_out;
dbg_allow_write : in std_logic;
-- SPI Flash Hardware Signals -- SPI Flash Hardware Signals
spi_si : out std_logic; -- spi serial in spi_si : out std_logic; -- spi serial in
spi_so : in std_logic; -- spi serial out spi_so : in std_logic; -- spi serial out
spi_sck : out std_logic; -- spi clock spi_sck : out std_logic; -- spi clock
spi_reset_n : out std_logic; -- spi hard reset spi_reset_n : out std_logic; -- spi hard reset
spi_cs_n : out std_logic; -- spi chip select spi_cs_n : out std_logic; -- spi chip select
spi_wp_n : out std_logic -- spi write protect spi_wp_n : out std_logic -- spi write protect
); );
end entity flashrom_wb; end entity flashrom_wb;
@ -58,7 +59,7 @@ architecture rtl of flashrom_wb is
signal cache_dOut : std_logic_vector(31 downto 0); signal cache_dOut : std_logic_vector(31 downto 0);
signal cache_dIn : 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 data_in_shift : std_logic_vector(31 downto 0);
signal delay_cycle : std_logic; signal delay_cycle : integer range 0 to 1;
begin begin
flashrom_controller_inst : entity work.flashrom_controller flashrom_controller_inst : entity work.flashrom_controller
port map( port map(
@ -87,20 +88,20 @@ begin
wb_ctrl : process(clk, rst) is wb_ctrl : process(clk, rst) is
procedure default_state is procedure default_state is
begin begin
load_stb <= '0'; load_stb <= '0';
sync_stb <= '0'; sync_stb <= '0';
wb_out.ACK <= '0'; wb_out.ACK <= '0';
cache_we <= '0'; cache_we <= '0';
delay_cycle <= '0';
end procedure default_state; end procedure default_state;
procedure reset_state is procedure reset_state is
begin begin
default_state; default_state;
state <= WAITCON; state <= WAITCON;
bootup_complete <= '0'; bootup_complete <= '0';
dirty <= '0'; dirty <= '0';
cache_control_addr <= (others => '0'); cache_control_addr <= (others => '0');
delay_cycle <= 1;
end procedure reset_state; end procedure reset_state;
begin begin
if rst = '1' then if rst = '1' then
@ -116,8 +117,11 @@ begin
state <= IDLE; state <= IDLE;
end if; end if;
when IDLE => when IDLE =>
if ready = '1' and delay_cycle = '0' and bootup_complete = '1' then if (delay_cycle /= 0) then
if wb_in.CYC = '1' and wb_in.STB = '1' then delay_cycle <= delay_cycle - 1;
end if;
if ready = '1' and delay_cycle = 0 and bootup_complete = '1' then
if wb_in.CYC = '1' and wb_in.STB = '1' and wb_out.ACK <= '0' then -- wb_out.ACK ensures empty period between accesses
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
state <= LOADPAGE; state <= LOADPAGE;
@ -133,7 +137,7 @@ begin
else -- Same page else -- Same page
wb_out.ACK <= '1'; wb_out.ACK <= '1';
if wb_in.WE = '1' then if wb_in.WE = '1' then
dirty <= '1'; dirty <= dbg_allow_write; -- TODO: SWITCH BACK TO '1' TO ALLOW WRITES!
cache_dIn <= wb_in.DAT; cache_dIn <= wb_in.DAT;
cache_we <= '1'; cache_we <= '1';
cache_control_addr <= unsigned(wb_in.ADR(7 downto 0)); cache_control_addr <= unsigned(wb_in.ADR(7 downto 0));
@ -156,7 +160,7 @@ begin
cache_we <= '1'; cache_we <= '1';
if cache_control_addr = 254 then if cache_control_addr = 254 then
state <= IDLE; state <= IDLE;
delay_cycle <= '1'; delay_cycle <= 1;
end if; end if;
end if; end if;
when WRITEPAGE => when WRITEPAGE =>
@ -174,7 +178,7 @@ begin
if cache_control_addr = 0 then if cache_control_addr = 0 then
state <= IDLE; state <= IDLE;
dirty <= '0'; dirty <= '0';
delay_cycle <= '1'; delay_cycle <= 1; -- TODO: 1 should be enough
end if; end if;
end if; end if;
end case; end case;
@ -200,7 +204,7 @@ begin
cache_addr <= wb_in.ADR(7 downto 0) when (state = IDLE and cache_we = '0') else std_logic_vector(cache_control_addr); 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; wb_out.DAT <= cache_dOut;
status_update_stb <= '0'; status_update_stb <= '0';
end architecture rtl; end architecture rtl;

View File

@ -113,7 +113,7 @@ begin
SR(i)(1) <= tx_busy(i); -- TXActive SR(i)(1) <= tx_busy(i); -- TXActive
-- WB -- WB
if slave_i.CYC = '1' and slave_i.STB = '1' then if slave_i.CYC = '1' and slave_i.STB = '1' and slave_o.ACK <= '0' then
if unsigned(slave_i.ADR) = to_unsigned((registersPerCore * i), slave_i.ADR'length) then -- CRx if unsigned(slave_i.ADR) = to_unsigned((registersPerCore * i), slave_i.ADR'length) then -- CRx
slave_o.DAT <= CR(i); slave_o.DAT <= CR(i);
if slave_i.we = '1' then if slave_i.we = '1' then

View File

@ -152,12 +152,12 @@ begin
-- wb_out => intercon_slave_o(INTERCON_ID_SRAM) -- wb_out => intercon_slave_o(INTERCON_ID_SRAM)
-- ); -- );
-- CPU -- CPU (boots to 0x000 instead of 0x100)
interrupt <= (others => '0'); interrupt <= (others => '0');
mor1kx_vhdl_inst : entity ip.mor1kx_vhdl mor1kx_vhdl_inst : entity ip.mor1kx_vhdl
port map( port map(
clk => clk, clk => clk,
rst => mor1kx_rst, rst => mor1kx_rst or GPIOA(10),
data_o => intercon_master_o(1), data_o => intercon_master_o(1),
data_i => intercon_master_i(1), data_i => intercon_master_i(1),
inst_o => intercon_master_o(0), inst_o => intercon_master_o(0),
@ -285,7 +285,16 @@ begin
avl_write_req_0 <= (intercon_slave_i(INTERCON_ID_DDR3).STB and intercon_slave_i(INTERCON_ID_DDR3).WE) and avl_reqEn; avl_write_req_0 <= (intercon_slave_i(INTERCON_ID_DDR3).STB and intercon_slave_i(INTERCON_ID_DDR3).WE) and avl_reqEn;
avl_size_0 <= "001"; avl_size_0 <= "001";
intercon_slave_o(INTERCON_ID_DDR3).DAT <= avl_rdata_0; --intercon_slave_o(INTERCON_ID_DDR3).DAT <= avl_rdata_0;
-- DDR3 first words include boot rom code
ddr3_mem_data : with intercon_slave_i(INTERCON_ID_DDR3).ADR select intercon_slave_o(INTERCON_ID_DDR3).DAT <=
x"18604000" when x"00000000",
--x"18600200" when x"00000000",
x"a8630100" when x"00000004",
x"44001800" when x"00000008",
x"15000000" when x"0000000c",
avl_rdata_0 when others; -- nop
intercon_slave_o(INTERCON_ID_DDR3).ERR <= '0'; intercon_slave_o(INTERCON_ID_DDR3).ERR <= '0';
intercon_slave_o(INTERCON_ID_DDR3).RTY <= '0'; intercon_slave_o(INTERCON_ID_DDR3).RTY <= '0';
intercon_slave_o(INTERCON_ID_DDR3).ACK <= (readAck or writeAck) and intercon_slave_i(INTERCON_ID_DDR3).STB; intercon_slave_o(INTERCON_ID_DDR3).ACK <= (readAck or writeAck) and intercon_slave_i(INTERCON_ID_DDR3).STB;
@ -298,7 +307,7 @@ begin
if rst = '1' then if rst = '1' then
avl_reqEn <= '1'; avl_reqEn <= '1';
elsif rising_edge(clk) then elsif rising_edge(clk) then
if intercon_slave_i(INTERCON_ID_DDR3).STB = '1' and not intercon_slave_o(INTERCON_ID_DDR3).ACK= '1' then if intercon_slave_i(INTERCON_ID_DDR3).STB = '1' and not intercon_slave_o(INTERCON_ID_DDR3).ACK = '1' then
avl_reqEn <= '0'; avl_reqEn <= '0';
else else
avl_reqEn <= '1'; avl_reqEn <= '1';
@ -309,17 +318,18 @@ begin
-- Non Volatile Memory -- Non Volatile Memory
flashrom_wb_inst : entity work.flashrom_wb flashrom_wb_inst : entity work.flashrom_wb
port map( port map(
clk => clk, dbg_allow_write => not GPIOA(11),
rst => rst, clk => clk,
clr => '0', rst => rst,
wb_in => intercon_slave_i(INTERCON_ID_FLASH), clr => '0',
wb_out => intercon_slave_o(INTERCON_ID_FLASH), wb_in => intercon_slave_i(INTERCON_ID_FLASH),
spi_si => flash_si, wb_out => intercon_slave_o(INTERCON_ID_FLASH),
spi_so => flash_so, spi_si => flash_si,
spi_sck => flash_sck, spi_so => flash_so,
spi_reset_n => flash_reset_n, spi_sck => flash_sck,
spi_cs_n => flash_cs_n, spi_reset_n => flash_reset_n,
spi_wp_n => flash_wp_n spi_cs_n => flash_cs_n,
spi_wp_n => flash_wp_n
); );
-- GPIO -- GPIO
@ -363,16 +373,14 @@ begin
master_i => intercon_slave_o, master_i => intercon_slave_o,
master_o => intercon_slave_i, master_o => intercon_slave_i,
address => ( address => (
--INTERCON_ID_SRAM => x"00000000",
INTERCON_ID_DDR3 => x"00000000", INTERCON_ID_DDR3 => x"00000000",
INTERCON_ID_FLASH => x"40000000", INTERCON_ID_FLASH => x"40000000",
INTERCON_ID_GPIO => x"80000000", INTERCON_ID_GPIO => x"C0000000",
INTERCON_ID_UART => x"80000100" INTERCON_ID_UART => x"C0000100"
), ),
mask => ( mask => (
--INTERCON_ID_SRAM => x"ffffff00", -- TODO: Match size of SRAM (or remove)
INTERCON_ID_DDR3 => x"f0000000", INTERCON_ID_DDR3 => x"f0000000",
INTERCON_ID_FLASH => x"fffff000", -- TODO: Correct size INTERCON_ID_FLASH => x"ffc00000",
INTERCON_ID_GPIO => x"fffffff0", INTERCON_ID_GPIO => x"fffffff0",
INTERCON_ID_UART => x"ffffffc0" INTERCON_ID_UART => x"ffffffc0"
) )

View File

@ -234,7 +234,7 @@
`include "mor1kx-sprs.v" `include "mor1kx-sprs.v"
/* Exception addresses */ /* Exception addresses */
`define OR1K_RESET_VECTOR 5'h01 `define OR1K_RESET_VECTOR 5'h00
`define OR1K_BERR_VECTOR 5'h02 `define OR1K_BERR_VECTOR 5'h02
`define OR1K_DPF_VECTOR 5'h03 `define OR1K_DPF_VECTOR 5'h03
`define OR1K_IPF_VECTOR 5'h04 `define OR1K_IPF_VECTOR 5'h04

View File

@ -20,7 +20,7 @@ package mor1kx_pkg is
constant FEATURE_DMMU_HW_TLB_RELOAD : string := "NONE"; constant FEATURE_DMMU_HW_TLB_RELOAD : string := "NONE";
constant OPTION_DMMU_SET_WIDTH : integer := 6; constant OPTION_DMMU_SET_WIDTH : integer := 6;
constant OPTION_DMMU_WAYS : integer := 1; constant OPTION_DMMU_WAYS : integer := 1;
constant FEATURE_INSTRUCTIONCACHE : string := "NONE"; constant FEATURE_INSTRUCTIONCACHE : string := "ENABLED";
constant OPTION_ICACHE_BLOCK_WIDTH : integer := 5; constant OPTION_ICACHE_BLOCK_WIDTH : integer := 5;
constant OPTION_ICACHE_SET_WIDTH : integer := 9; constant OPTION_ICACHE_SET_WIDTH : integer := 9;
constant OPTION_ICACHE_WAYS : integer := 2; constant OPTION_ICACHE_WAYS : integer := 2;