Bootrom, icache, bugfixes, ...
This commit is contained in:
parent
af2cad643b
commit
34d5aadf0c
@ -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;
|
||||||
@ -201,6 +205,6 @@ 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;
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
)
|
)
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user