Added data mask support
git-svn-id: http://moon:8086/svn/vhdl/trunk@29 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -110,17 +110,14 @@ architecture behavior of bui is
|
|||||||
);
|
);
|
||||||
END COMPONENT;
|
END COMPONENT;
|
||||||
|
|
||||||
type ca_state_t is (ca_init, ca_ready, ca_bus_access, ca_bus_fin);
|
|
||||||
type bus_state_t is (init, ready, i_cache_bus_access, d_cache_bus_access, uncached_bus_access);
|
type bus_state_t is (init, ready, i_cache_bus_access, d_cache_bus_access, uncached_bus_access);
|
||||||
|
|
||||||
signal s, sn : bus_state_t;
|
signal s, sn : bus_state_t;
|
||||||
signal s_ca, sn_ca : ca_state_t;
|
|
||||||
signal dmem_we : unsigned(3 downto 0);
|
signal dmem_we : unsigned(3 downto 0);
|
||||||
signal dcache_dout : word_t;
|
signal dcache_dout : word_t;
|
||||||
signal dcache_mem_gnt : std_logic;
|
signal dcache_mem_gnt : std_logic;
|
||||||
signal icache_mem_gnt : std_logic;
|
signal icache_mem_gnt : std_logic;
|
||||||
signal dmem_mem_gnt : std_logic;
|
signal dmem_mem_gnt : std_logic;
|
||||||
signal dcache_busy1 : std_logic;
|
|
||||||
signal dcache_busy2 : std_logic;
|
signal dcache_busy2 : std_logic;
|
||||||
signal icache_busy : std_logic;
|
signal icache_busy : std_logic;
|
||||||
signal CYC_O_icache : std_logic;
|
signal CYC_O_icache : std_logic;
|
||||||
@@ -128,7 +125,6 @@ architecture behavior of bui is
|
|||||||
signal CYC_O_dmem : std_logic;
|
signal CYC_O_dmem : std_logic;
|
||||||
signal SRDY_I_icache : std_logic;
|
signal SRDY_I_icache : std_logic;
|
||||||
signal SRDY_I_dcache : std_logic;
|
signal SRDY_I_dcache : std_logic;
|
||||||
signal SRDY_I_dmem : std_logic;
|
|
||||||
signal ADDR_O_icache : word_t;
|
signal ADDR_O_icache : word_t;
|
||||||
signal ADDR_O_dcache : word_t;
|
signal ADDR_O_dcache : word_t;
|
||||||
signal ADDR_O_dmem : word_t;
|
signal ADDR_O_dmem : word_t;
|
||||||
@@ -141,41 +137,10 @@ architecture behavior of bui is
|
|||||||
signal WE_O_dmem : std_logic;
|
signal WE_O_dmem : std_logic;
|
||||||
signal dcached : std_logic;
|
signal dcached : std_logic;
|
||||||
signal dcache_en : std_logic;
|
signal dcache_en : std_logic;
|
||||||
signal ca_reg_en : std_logic;
|
signal uncached_access : std_logic;
|
||||||
|
|
||||||
type bui_eval_t is record
|
|
||||||
addr : word_t;
|
|
||||||
dout : word_t;
|
|
||||||
en : std_logic;
|
|
||||||
re : std_logic;
|
|
||||||
we : unsigned (3 downto 0);
|
|
||||||
end record;
|
|
||||||
|
|
||||||
signal bui_eval : bui_eval_t;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
proc_bui_eval:
|
|
||||||
process(CLK_I)
|
|
||||||
variable en : std_logic;
|
|
||||||
begin
|
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
en := cpu_dmem_en and not dcache_busy1;
|
|
||||||
bui_eval.en <= en;
|
|
||||||
if RST_I = '1' then
|
|
||||||
bui_eval.addr <= (others => '0');
|
|
||||||
bui_eval.dout <= (others => '0');
|
|
||||||
bui_eval.re <= '0';
|
|
||||||
bui_eval.we <= (others => '0');
|
|
||||||
elsif en = '1' then
|
|
||||||
bui_eval.addr <= cpu_dmem_addr;
|
|
||||||
bui_eval.dout <= cpu_dmem_dout;
|
|
||||||
bui_eval.re <= cpu_dmem_re;
|
|
||||||
bui_eval.we <= cpu_dmem_we;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
bus_strobe:
|
bus_strobe:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
@@ -199,8 +164,6 @@ bus_out:
|
|||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
CYC_O <= '0';
|
CYC_O <= '0';
|
||||||
WE_O <= '0';
|
|
||||||
SEL_O <= (others => '0');
|
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
ADDR_O <= (others => '0');
|
ADDR_O <= (others => '0');
|
||||||
DAT_O <= (others => '0');
|
DAT_O <= (others => '0');
|
||||||
@@ -213,35 +176,25 @@ bus_out:
|
|||||||
elsif dcache_mem_gnt = '1' then
|
elsif dcache_mem_gnt = '1' then
|
||||||
CYC_O <= CYC_O_dcache;
|
CYC_O <= CYC_O_dcache;
|
||||||
ADDR_O <= ADDR_O_dcache;
|
ADDR_O <= ADDR_O_dcache;
|
||||||
|
WE_O <= '0';
|
||||||
|
SEL_O <= (others => '0');
|
||||||
elsif icache_mem_gnt = '1' then
|
elsif icache_mem_gnt = '1' then
|
||||||
CYC_O <= CYC_O_icache;
|
CYC_O <= CYC_O_icache;
|
||||||
ADDR_O <= ADDR_O_icache;
|
ADDR_O <= ADDR_O_icache;
|
||||||
|
WE_O <= '0';
|
||||||
|
SEL_O <= (others => '0');
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
MRDY_O <= '1';
|
MRDY_O <= '1';
|
||||||
|
|
||||||
-- ADDR_O <= ADDR_O_dcache when dcache_mem_gnt = '1' else
|
|
||||||
-- ADDR_O_icache when icache_mem_gnt = '1' else ADDR_O_dmem;
|
|
||||||
-- DAT_O <= DAT_O_dmem when dmem_mem_gnt = '1' else X"BEEFBABE";
|
|
||||||
-- SEL_O <= SEL_O_dmem when dmem_mem_gnt = '1' else "0000";
|
|
||||||
-- WE_O <= WE_O_dmem when dmem_mem_gnt = '1' else '0';
|
|
||||||
-- STB_O <= STB_O_icache when icache_mem_gnt = '1' else
|
|
||||||
-- STB_O_dcache when dcache_mem_gnt = '1' else
|
|
||||||
-- STB_O_dmem when dmem_mem_gnt = '1' else '0';
|
|
||||||
-- CYC_O <= CYC_O_icache when icache_mem_gnt = '1' else
|
|
||||||
-- CYC_O_dcache when dcache_mem_gnt = '1' else
|
|
||||||
-- CYC_O_dmem when dmem_mem_gnt = '1' else '0';
|
|
||||||
|
|
||||||
SRDY_I_icache <= SRDY_I when icache_mem_gnt = '1' else '0';
|
SRDY_I_icache <= SRDY_I when icache_mem_gnt = '1' else '0';
|
||||||
SRDY_I_dcache <= SRDY_I when dcache_mem_gnt = '1' else '0';
|
SRDY_I_dcache <= SRDY_I when dcache_mem_gnt = '1' else '0';
|
||||||
SRDY_I_dmem <= SRDY_I when dmem_mem_gnt = '1' else '0';
|
-- SRDY_I_dmem <= SRDY_I when dmem_mem_gnt = '1' else '0';
|
||||||
|
|
||||||
cpu_imem_rdy <= not icache_busy after 4.5 ns;
|
cpu_imem_rdy <= not icache_busy after 4.5 ns;
|
||||||
-- cpu_imem_din <= imem_din;
|
cpu_dmem_rdy <= not (CYC_O_dmem or dcache_busy2) after 4.5 ns;
|
||||||
-- cpu_wait <= busy after 5.5 ns;
|
|
||||||
cpu_dmem_rdy <= not (dcache_busy1 or dcache_busy2) after 4.5 ns;
|
|
||||||
|
|
||||||
inst_icache : icache
|
inst_icache : icache
|
||||||
GENERIC MAP
|
GENERIC MAP
|
||||||
@@ -293,35 +246,27 @@ inst_dcache : dcache
|
|||||||
);
|
);
|
||||||
|
|
||||||
dcached <= '1' when cpu_dmem_addr(31 downto 28) /= X"A" else '0';
|
dcached <= '1' when cpu_dmem_addr(31 downto 28) /= X"A" else '0';
|
||||||
cpu_dmem_din <= DAT_I_dmem when dmem_mem_gnt = '1' else dcache_dout;
|
cpu_dmem_din <= dcache_dout when uncached_access = '0' else DAT_I_dmem;
|
||||||
dcache_en <= cpu_dmem_en and not dcache_busy1;
|
dcache_en <= cpu_dmem_en and not CYC_O_dmem;
|
||||||
|
|
||||||
proc_busy:
|
dcache_flags:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
|
uncached_access <= '0';
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
dcache_busy1 <= '0';
|
CYC_O_dmem <= '0';
|
||||||
elsif ACK_I = '1' and dmem_mem_gnt = '1' then
|
else
|
||||||
dcache_busy1 <= '0';
|
if ACK_I = '1' and dmem_mem_gnt = '1' then
|
||||||
elsif cpu_dmem_en = '1' and ca_reg_en = '1' then
|
uncached_access <= not WE_O_dmem;
|
||||||
dcache_busy1 <= '1';
|
CYC_O_dmem <= '0';
|
||||||
end if;
|
end if;
|
||||||
end if;
|
if cpu_dmem_en = '1' and CYC_O_dmem = '0' and dcache_busy2 = '0' then
|
||||||
end process;
|
CYC_O_dmem <= '1';
|
||||||
|
if dcached = '1' and cpu_dmem_re = '1' then
|
||||||
dcache_regs:
|
CYC_O_dmem <= '0';
|
||||||
process(CLK_I)
|
end if;
|
||||||
begin
|
end if;
|
||||||
if rising_edge(CLK_I) then
|
|
||||||
if RST_I = '1' then
|
|
||||||
WE_O_dmem <= '0';
|
|
||||||
SEL_O_dmem <= (others => '0');
|
|
||||||
elsif cpu_dmem_en = '1' and ca_reg_en = '1' then
|
|
||||||
DAT_O_dmem <= cpu_dmem_dout;
|
|
||||||
ADDR_O_dmem <= cpu_dmem_addr;
|
|
||||||
WE_O_dmem <= not cpu_dmem_re;
|
|
||||||
SEL_O_dmem <= cpu_dmem_we;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
@@ -332,65 +277,27 @@ dcache_data:
|
|||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
DAT_I_dmem <= (others => '0');
|
DAT_I_dmem <= (others => '0');
|
||||||
elsif ACK_I = '1' and dmem_mem_gnt = '1' then
|
elsif ACK_I = '1' and CYC_O_dmem = '1' then
|
||||||
DAT_I_dmem <= DAT_I;
|
DAT_I_dmem <= DAT_I;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
cpu_access_state_next:
|
dcache_regs:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
s_ca <= ca_init;
|
WE_O_dmem <= '0';
|
||||||
else
|
SEL_O_dmem <= (others => '0');
|
||||||
s_ca <= sn_ca;
|
elsif cpu_dmem_en = '1' and CYC_O_dmem = '0' and dcache_busy2 = '0' then
|
||||||
|
DAT_O_dmem <= cpu_dmem_dout;
|
||||||
|
ADDR_O_dmem <= cpu_dmem_addr;
|
||||||
|
WE_O_dmem <= not cpu_dmem_re;
|
||||||
|
SEL_O_dmem <= cpu_dmem_we;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
cpu_access_state:
|
|
||||||
process(s_ca, cpu_dmem_en, cpu_dmem_re, dcached, SRDY_I_dmem, ACK_I)
|
|
||||||
begin
|
|
||||||
|
|
||||||
ca_reg_en <= '0';
|
|
||||||
CYC_O_dmem <= '0';
|
|
||||||
STB_O_dmem <= '0';
|
|
||||||
sn_ca <= s_ca;
|
|
||||||
|
|
||||||
case s_ca is
|
|
||||||
when ca_init =>
|
|
||||||
sn_ca <= ca_ready;
|
|
||||||
|
|
||||||
when ca_ready =>
|
|
||||||
if cpu_dmem_en = '1' then
|
|
||||||
if dcached = '0' or cpu_dmem_re = '0' then
|
|
||||||
ca_reg_en <= '1';
|
|
||||||
sn_ca <= ca_bus_access;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when ca_bus_access =>
|
|
||||||
CYC_O_dmem <= '1';
|
|
||||||
if SRDY_I_dmem = '1' then
|
|
||||||
STB_O_dmem <= '1';
|
|
||||||
sn_ca <= ca_bus_fin;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when ca_bus_fin =>
|
|
||||||
CYC_O_dmem <= '1';
|
|
||||||
if ACK_I = '1' then
|
|
||||||
sn_ca <= ca_ready;
|
|
||||||
-- CYC_O_dmem <= '0';
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when others =>
|
|
||||||
sn_ca <= ca_ready;
|
|
||||||
end case;
|
|
||||||
|
|
||||||
end process;
|
|
||||||
|
|
||||||
|
|
||||||
bus_state_next:
|
bus_state_next:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
@@ -405,26 +312,30 @@ bus_state_next:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
bus_state:
|
bus_state:
|
||||||
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem)
|
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem, SRDY_I, ACK_I)
|
||||||
begin
|
begin
|
||||||
|
|
||||||
icache_mem_gnt <= '0';
|
icache_mem_gnt <= '0';
|
||||||
dcache_mem_gnt <= '0';
|
dcache_mem_gnt <= '0';
|
||||||
dmem_mem_gnt <= '0';
|
dmem_mem_gnt <= '0';
|
||||||
|
STB_O_dmem <= '0';
|
||||||
sn <= s;
|
sn <= s;
|
||||||
case s is
|
case s is
|
||||||
when init =>
|
when init =>
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
when ready =>
|
when ready =>
|
||||||
if CYC_O_dmem = '1' then
|
if CYC_O_dmem = '1' then
|
||||||
sn <= uncached_bus_access;
|
|
||||||
dmem_mem_gnt <= '1';
|
dmem_mem_gnt <= '1';
|
||||||
|
if SRDY_I = '1' then
|
||||||
|
STB_O_dmem <= '1';
|
||||||
|
sn <= uncached_bus_access;
|
||||||
|
end if;
|
||||||
elsif CYC_O_icache = '1' then
|
elsif CYC_O_icache = '1' then
|
||||||
sn <= i_cache_bus_access;
|
sn <= i_cache_bus_access;
|
||||||
icache_mem_gnt <= '1';
|
-- icache_mem_gnt <= '1';
|
||||||
elsif CYC_O_dcache = '1' then
|
elsif CYC_O_dcache = '1' then
|
||||||
sn <= d_cache_bus_access;
|
sn <= d_cache_bus_access;
|
||||||
dcache_mem_gnt <= '1';
|
-- dcache_mem_gnt <= '1';
|
||||||
end if;
|
end if;
|
||||||
when i_cache_bus_access =>
|
when i_cache_bus_access =>
|
||||||
icache_mem_gnt <= '1';
|
icache_mem_gnt <= '1';
|
||||||
@@ -440,7 +351,7 @@ bus_state:
|
|||||||
end if;
|
end if;
|
||||||
when uncached_bus_access =>
|
when uncached_bus_access =>
|
||||||
dmem_mem_gnt <= '1';
|
dmem_mem_gnt <= '1';
|
||||||
if CYC_O_dmem = '0' then
|
if ACK_I = '1' then
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
-- dmem_mem_gnt <= '0';
|
-- dmem_mem_gnt <= '0';
|
||||||
end if;
|
end if;
|
||||||
|
|||||||
Reference in New Issue
Block a user