Added data mask support

git-svn-id: http://moon:8086/svn/vhdl/trunk@29 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2008-10-08 19:33:27 +00:00
parent e873c4ef07
commit 316b998f86
+42 -131
View File
@@ -110,17 +110,14 @@ architecture behavior of bui is
);
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);
signal s, sn : bus_state_t;
signal s_ca, sn_ca : ca_state_t;
signal dmem_we : unsigned(3 downto 0);
signal dcache_dout : word_t;
signal dcache_mem_gnt : std_logic;
signal icache_mem_gnt : std_logic;
signal dmem_mem_gnt : std_logic;
signal dcache_busy1 : std_logic;
signal dcache_busy2 : std_logic;
signal icache_busy : std_logic;
signal CYC_O_icache : std_logic;
@@ -128,7 +125,6 @@ architecture behavior of bui is
signal CYC_O_dmem : std_logic;
signal SRDY_I_icache : std_logic;
signal SRDY_I_dcache : std_logic;
signal SRDY_I_dmem : std_logic;
signal ADDR_O_icache : word_t;
signal ADDR_O_dcache : word_t;
signal ADDR_O_dmem : word_t;
@@ -141,41 +137,10 @@ architecture behavior of bui is
signal WE_O_dmem : std_logic;
signal dcached : std_logic;
signal dcache_en : std_logic;
signal ca_reg_en : 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;
signal uncached_access : std_logic;
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:
process(CLK_I)
begin
@@ -199,8 +164,6 @@ bus_out:
begin
if rising_edge(CLK_I) then
CYC_O <= '0';
WE_O <= '0';
SEL_O <= (others => '0');
if RST_I = '1' then
ADDR_O <= (others => '0');
DAT_O <= (others => '0');
@@ -213,35 +176,25 @@ bus_out:
elsif dcache_mem_gnt = '1' then
CYC_O <= CYC_O_dcache;
ADDR_O <= ADDR_O_dcache;
WE_O <= '0';
SEL_O <= (others => '0');
elsif icache_mem_gnt = '1' then
CYC_O <= CYC_O_icache;
ADDR_O <= ADDR_O_icache;
WE_O <= '0';
SEL_O <= (others => '0');
end if;
end if;
end process;
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_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_din <= imem_din;
-- cpu_wait <= busy after 5.5 ns;
cpu_dmem_rdy <= not (dcache_busy1 or dcache_busy2) after 4.5 ns;
cpu_dmem_rdy <= not (CYC_O_dmem or dcache_busy2) after 4.5 ns;
inst_icache : icache
GENERIC MAP
@@ -293,35 +246,27 @@ inst_dcache : dcache
);
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;
dcache_en <= cpu_dmem_en and not dcache_busy1;
cpu_dmem_din <= dcache_dout when uncached_access = '0' else DAT_I_dmem;
dcache_en <= cpu_dmem_en and not CYC_O_dmem;
proc_busy:
dcache_flags:
process(CLK_I)
begin
if rising_edge(CLK_I) then
uncached_access <= '0';
if RST_I = '1' then
dcache_busy1 <= '0';
elsif ACK_I = '1' and dmem_mem_gnt = '1' then
dcache_busy1 <= '0';
elsif cpu_dmem_en = '1' and ca_reg_en = '1' then
dcache_busy1 <= '1';
end if;
end if;
end process;
dcache_regs:
process(CLK_I)
begin
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;
CYC_O_dmem <= '0';
else
if ACK_I = '1' and dmem_mem_gnt = '1' then
uncached_access <= not WE_O_dmem;
CYC_O_dmem <= '0';
end if;
if cpu_dmem_en = '1' and CYC_O_dmem = '0' and dcache_busy2 = '0' then
CYC_O_dmem <= '1';
if dcached = '1' and cpu_dmem_re = '1' then
CYC_O_dmem <= '0';
end if;
end if;
end if;
end if;
end process;
@@ -332,65 +277,27 @@ dcache_data:
if rising_edge(CLK_I) then
if RST_I = '1' then
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;
end if;
end if;
end process;
cpu_access_state_next:
dcache_regs:
process(CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
s_ca <= ca_init;
else
s_ca <= sn_ca;
WE_O_dmem <= '0';
SEL_O_dmem <= (others => '0');
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 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:
process(CLK_I)
@@ -405,26 +312,30 @@ bus_state_next:
end process;
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
icache_mem_gnt <= '0';
dcache_mem_gnt <= '0';
dmem_mem_gnt <= '0';
STB_O_dmem <= '0';
sn <= s;
case s is
when init =>
sn <= ready;
when ready =>
if CYC_O_dmem = '1' then
sn <= uncached_bus_access;
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
sn <= i_cache_bus_access;
icache_mem_gnt <= '1';
-- icache_mem_gnt <= '1';
elsif CYC_O_dcache = '1' then
sn <= d_cache_bus_access;
dcache_mem_gnt <= '1';
-- dcache_mem_gnt <= '1';
end if;
when i_cache_bus_access =>
icache_mem_gnt <= '1';
@@ -440,7 +351,7 @@ bus_state:
end if;
when uncached_bus_access =>
dmem_mem_gnt <= '1';
if CYC_O_dmem = '0' then
if ACK_I = '1' then
sn <= ready;
-- dmem_mem_gnt <= '0';
end if;