Introduced J-Bus

git-svn-id: http://moon:8086/svn/vhdl/trunk@27 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2008-10-07 17:26:27 +00:00
parent 3ecd76f185
commit dd38d30198
14 changed files with 4720 additions and 4523 deletions
+43 -43
View File
@@ -14,8 +14,14 @@ ENTITY dcache IS
);
Port
(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
RST_I : in STD_LOGIC;
CLK_I : in STD_LOGIC;
ACK_I : in STD_LOGIC;
SRDY_I : in STD_LOGIC;
ADDR_O : out word_t;
DAT_I : in word_t;
STB_O : out STD_LOGIC;
CYC_O : out STD_LOGIC;
en : in STD_LOGIC;
cpu_en : in STD_LOGIC;
cpu_r_wn : in STD_LOGIC;
@@ -23,14 +29,7 @@ ENTITY dcache IS
cpu_addr : in word_t;
cpu_din : in word_t;
cpu_dout : out word_t;
cpu_busy : out STD_LOGIC;
mem_req : out STD_LOGIC;
mem_gnt : in STD_LOGIC;
mem_en : out STD_LOGIC;
mem_addr : out word_t;
mem_din : in word_t;
mem_valid : in STD_LOGIC;
mem_rdy : in STD_LOGIC
cpu_busy : out STD_LOGIC
);
END dcache;
@@ -181,10 +180,10 @@ begin
cpu_index_reg:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rst = '1' then
if rising_edge(CLK_I) then
if RST_I = '1' then
cache_index_reg <= (others => '0');
tag_index_reg <= (others => '0');
cpu_was_write <= '0';
@@ -200,9 +199,9 @@ cpu_index_reg:
end process;
cpu_was_wr_reg:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rising_edge(CLK_I) then
cpu_was_en <= '0';
cpu_we2 <= '0';
if cpu_en = '1' and en = '1' then
@@ -219,8 +218,8 @@ inst_tag_ram : dpram_1w1r
data_width => tram_data_width
)
PORT MAP (
clka => clk,
clkb => clk,
clka => CLK_I,
clkb => CLK_I,
en_a => '1',
en_b => tram_re,
we_a => tram_we,
@@ -240,8 +239,8 @@ gen_data_ram:
data_width => word_t'length/4
)
PORT MAP (
clk_a => clk,
clk_b => clk,
clk_a => CLK_I,
clk_b => CLK_I,
en_a => '1',
en_b => dram_en,
we_a => ctrl_dram_we(i),
@@ -256,10 +255,10 @@ gen_data_ram:
end generate;
cache_state_next:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rst = '1' then
if rising_edge(CLK_I) then
if RST_I = '1' then
s <= init;
else
s <= sn;
@@ -277,14 +276,14 @@ cache_state_next:
tram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
cache_entry_out <= to_dcache_entry(tram_dout);
cpu_dram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and cpu_we2 = '0') else (cache_index_reg & word_index_reg);
mem_addr <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
ADDR_O <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
ctrl_dram_addr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width);
ctrl_dram_din <= mem_din;
ctrl_dram_we <= (3 downto 0 => (data_write and mem_valid)) or ctrl_force_we;
ctrl_dram_din <= DAT_I;
ctrl_dram_we <= (3 downto 0 => (data_write and ACK_I)) or ctrl_force_we;
cpu_dram_we <= cpu_we_reg when (cpu_we2 = '1' and cache_write_miss = '0') else (others => '0');
cache_state:
process(s, cache_read_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, mem_valid, tag_index_reg, cpu_en, cpu_r_wn, mem_gnt, mem_rdy, cpu_was_en, cpu_was_write, cpu_we_reg)
process(s, cache_read_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, cpu_r_wn, SRDY_I, cpu_was_en, cpu_was_write, cpu_we_reg)
begin
cpu_reg_en <= '0';
cache_busy <= '1';
@@ -293,8 +292,8 @@ cache_state:
ram_index_count_rst <= '0';
mem_index_count_en <= '0';
mem_index_count_rst <= '0';
mem_req <= '0';
mem_en <= '0';
CYC_O <= '0';
STB_O <= '0';
dram_en <= '0';
tram_re <= '0';
was_miss <= '0';
@@ -320,6 +319,7 @@ cache_state:
sn <= mem_request;
cpu_reg_en <= '0';
cache_busy <= '1';
CYC_O <= '1';
end if;
end if;
when flush =>
@@ -339,30 +339,30 @@ cache_state:
when mem_request =>
ram_index_count_rst <= '1';
mem_index_count_rst <= '1';
mem_req <= '1';
if mem_gnt = '1' then
CYC_O <= '1';
if SRDY_I = '1' then
sn <= mem_access;
end if;
when mem_access =>
data_write <= '1';
mem_req <= '1';
if mem_rdy = '1' then
CYC_O <= '1';
if SRDY_I = '1' then
mem_index_count_en <= '1';
mem_en <= '1';
STB_O <= '1';
if mem_index_count = 2**word_index_width-1 then
sn <= mem_data;
end if;
end if;
when mem_data =>
mem_req <= '1';
CYC_O <= '1';
data_write <= '1';
if ram_index_count = 2**word_index_width-1 then
if mem_valid = '1' then
if ACK_I = '1' then
sn <= upd_cache;
end if;
end if;
when upd_cache =>
mem_req <= '1';
CYC_O <= '1';
tram_addr_wr <= cache_index_reg;
tram_we <= '1';
cache_entry_in.valid <= '1';
@@ -388,9 +388,9 @@ cache_state:
end process;
cache_index_counter:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rising_edge(CLK_I) then
if cache_index_count_en = '0' then
cache_index_count <= 2**cache_index_width-1;
elsif cache_index_count /= 0 then
@@ -400,12 +400,12 @@ cache_index_counter:
end process;
ram_index_counter:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rising_edge(CLK_I) then
if ram_index_count_rst = '1' then
ram_index_count <= 0;
elsif data_write = '1' and mem_valid = '1' then
elsif data_write = '1' and ACK_I = '1' then
if ram_index_count /= 2**word_index_width-1 then
ram_index_count <= ram_index_count + 1;
end if;
@@ -414,9 +414,9 @@ ram_index_counter:
end process;
mem_index_counter:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rising_edge(CLK_I) then
if mem_index_count_rst = '1' then
mem_index_count <= 0;
elsif mem_index_count_en = '1' then
+42 -42
View File
@@ -14,20 +14,19 @@ ENTITY icache IS
);
Port
(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
RST_I : in STD_LOGIC;
CLK_I : in STD_LOGIC;
ACK_I : in STD_LOGIC;
SRDY_I : in STD_LOGIC;
ADDR_O : out word_t;
DAT_I : in word_t;
STB_O : out STD_LOGIC;
CYC_O : out STD_LOGIC;
en : in STD_LOGIC;
cpu_en : in STD_LOGIC;
cpu_addr : in word_t;
cpu_dout : out word_t;
cpu_busy : out STD_LOGIC;
mem_req : out STD_LOGIC;
mem_gnt : in STD_LOGIC;
mem_en : out STD_LOGIC;
mem_addr : out word_t;
mem_din : in word_t;
mem_valid : in STD_LOGIC;
mem_rdy : in STD_LOGIC
cpu_busy : out STD_LOGIC
);
END icache;
@@ -143,10 +142,10 @@ begin
cpu_index_reg:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rst = '1' then
if rising_edge(CLK_I) then
if RST_I = '1' then
cache_index_reg <= (others => '0');
tag_index_reg <= (others => '0');
elsif cpu_reg_en = '1' then
@@ -163,8 +162,8 @@ inst_tag_ram : dpram_1w1r
data_width => tag_ram_data_width
)
PORT MAP (
clka => clk,
clkb => clk,
clka => CLK_I,
clkb => CLK_I,
en_a => '1',
en_b => tag_ram_re,
we_a => tag_ram_we,
@@ -180,8 +179,8 @@ inst_data_ram : dpram_1w1r
data_width => word_t'length
)
PORT MAP (
clka => clk,
clkb => clk,
clka => CLK_I,
clkb => CLK_I,
en_a => '1',
en_b => data_ram_re,
we_a => data_ram_we,
@@ -193,10 +192,10 @@ inst_data_ram : dpram_1w1r
cache_state_next:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rst = '1' then
if rising_edge(CLK_I) then
if RST_I = '1' then
s <= init;
else
s <= sn;
@@ -213,13 +212,13 @@ cache_state_next:
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
cache_entry_out <= to_icache_entry(tag_ram_data_rd);
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (cache_index_reg & word_index_reg);
mem_addr <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
ADDR_O <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
data_ram_addr_wr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width);
data_ram_data_wr <= mem_din;
data_ram_we <= data_write and mem_valid;
data_ram_data_wr <= DAT_I;
data_ram_we <= data_write and ACK_I;
cache_state:
process(s, cache_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, mem_valid, tag_index_reg, cpu_en, mem_gnt, mem_rdy, en)
process(s, cache_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, SRDY_I, en)
begin
cpu_reg_en <= '0';
cache_busy <= '1';
@@ -228,8 +227,8 @@ cache_state:
ram_index_count_rst <= '0';
mem_index_count_en <= '0';
mem_index_count_rst <= '0';
mem_req <= '0';
mem_en <= '0';
CYC_O <= '0';
STB_O <= '0';
data_ram_re <= '0';
tag_ram_re <= '0';
was_miss <= '0';
@@ -250,6 +249,7 @@ cache_state:
sn <= mem_request;
cpu_reg_en <= '0';
cache_busy <= '1';
CYC_O <= '1';
elsif cpu_en = '1' then
cpu_reg_en <= '1';
data_ram_re <= '1';
@@ -273,37 +273,37 @@ cache_state:
when mem_request =>
ram_index_count_rst <= '1';
mem_index_count_rst <= '1';
mem_req <= '1';
if mem_gnt = '1' then
CYC_O <= '1';
if SRDY_I = '1' then
sn <= mem_access;
end if;
when mem_access =>
data_write <= '1';
mem_req <= '1';
if mem_rdy = '1' then
CYC_O <= '1';
if SRDY_I = '1' then
mem_index_count_en <= '1';
mem_en <= '1';
STB_O <= '1';
if mem_index_count = 2**word_index_width-1 then
sn <= mem_data;
end if;
end if;
when mem_data =>
mem_req <= '1';
CYC_O <= '1';
data_write <= '1';
if ram_index_count = 2**word_index_width-1 then
if mem_valid = '1' then
if ACK_I = '1' then
sn <= upd_cache;
end if;
end if;
when upd_cache =>
mem_req <= '1';
CYC_O <= '1';
tag_ram_addr_wr <= cache_index_reg;
tag_ram_we <= '1';
cache_entry_in.valid <= '1';
sn <= rd_cache;
when rd_cache =>
-- mem_req <= '1';
-- CYC_O <= '1';
tag_ram_re <= '1';
data_ram_re <= '1';
was_miss <= '1';
@@ -314,9 +314,9 @@ cache_state:
end process;
cache_index_counter:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rising_edge(CLK_I) then
if cache_index_count_en = '0' then
cache_index_count <= 2**cache_index_width-1;
elsif cache_index_count /= 0 then
@@ -326,12 +326,12 @@ cache_index_counter:
end process;
ram_index_counter:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rising_edge(CLK_I) then
if ram_index_count_rst = '1' then
ram_index_count <= 0;
elsif data_write = '1' and mem_valid = '1' then
elsif data_write = '1' and ACK_I = '1' then
if ram_index_count /= 2**word_index_width-1 then
ram_index_count <= ram_index_count + 1;
end if;
@@ -340,9 +340,9 @@ ram_index_counter:
end process;
mem_index_counter:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rising_edge(CLK_I) then
if mem_index_count_rst = '1' then
mem_index_count <= 0;
elsif mem_index_count_en = '1' then
+275 -200
View File
@@ -31,10 +31,18 @@ use work.mips_types.all;
entity bui is
Port
(
rst : in STD_LOGIC;
clk : in STD_LOGIC;
ce : in STD_LOGIC;
cpu_wait : out STD_LOGIC;
RST_I : in STD_LOGIC;
CLK_I : in STD_LOGIC;
ACK_I : in STD_LOGIC;
SRDY_I : in STD_LOGIC;
ADDR_O : out word_t;
DAT_I : in word_t;
DAT_O : out word_t;
WE_O : out STD_LOGIC;
SEL_O : out unsigned(3 downto 0);
CYC_O : out STD_LOGIC;
STB_O : out STD_LOGIC;
MRDY_O : out STD_LOGIC;
cpu_imem_rdy : out STD_LOGIC;
cpu_imem_en : in STD_LOGIC;
cpu_imem_addr : in word_t;
@@ -45,22 +53,13 @@ entity bui is
cpu_dmem_we : in unsigned(3 downto 0);
cpu_dmem_dout : in word_t;
cpu_dmem_din : out word_t;
cpu_dmem_addr : in word_t;
mem_valid : in STD_LOGIC;
mem_rdy : in STD_LOGIC;
mem_addr : out word_t;
mem_din : in word_t;
mem_dout : out word_t;
mem_re : out STD_LOGIC;
mem_we : out unsigned(3 downto 0);
mem_ce : out STD_LOGIC
cpu_dmem_addr : in word_t
);
end bui;
architecture behavior of bui is
COMPONENT icache
COMPONENT icache
GENERIC
(
cache_size : natural := 2048; -- words
@@ -68,24 +67,23 @@ COMPONENT icache
);
PORT
(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
RST_I : in STD_LOGIC;
CLK_I : in STD_LOGIC;
ACK_I : in STD_LOGIC;
SRDY_I : in STD_LOGIC;
ADDR_O : out word_t;
DAT_I : in word_t;
STB_O : out STD_LOGIC;
CYC_O : out STD_LOGIC;
en : in STD_LOGIC;
cpu_en : in STD_LOGIC;
cpu_addr : in word_t;
cpu_dout : out word_t;
cpu_busy : out STD_LOGIC;
mem_en : out STD_LOGIC;
mem_req : out STD_LOGIC;
mem_gnt : in STD_LOGIC;
mem_addr : out word_t;
mem_din : in word_t;
mem_valid : in STD_LOGIC;
mem_rdy : in STD_LOGIC
cpu_busy : out STD_LOGIC
);
END COMPONENT;
END COMPONENT;
COMPONENT dcache
COMPONENT dcache
GENERIC
(
cache_size : natural := 2048; -- words
@@ -93,8 +91,14 @@ COMPONENT dcache
);
PORT
(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
RST_I : in STD_LOGIC;
CLK_I : in STD_LOGIC;
ACK_I : in STD_LOGIC;
SRDY_I : in STD_LOGIC;
ADDR_O : out word_t;
DAT_I : in word_t;
STB_O : out STD_LOGIC;
CYC_O : out STD_LOGIC;
en : in STD_LOGIC;
cpu_en : in STD_LOGIC;
cpu_r_wn : in STD_LOGIC;
@@ -102,54 +106,141 @@ COMPONENT dcache
cpu_addr : in word_t;
cpu_din : in word_t;
cpu_dout : out word_t;
cpu_busy : out STD_LOGIC;
mem_req : out STD_LOGIC;
mem_gnt : in STD_LOGIC;
mem_en : out STD_LOGIC;
mem_addr : out word_t;
mem_din : in word_t;
mem_valid : in STD_LOGIC;
mem_rdy : in STD_LOGIC
cpu_busy : out STD_LOGIC
);
END COMPONENT;
END COMPONENT;
type bus_state_t is (init, ready, i_cache_bus_access, d_cache_bus_access, d_bus_start, d_bus_access, d_bus_finish);
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 dmem_re : std_logic;
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 dmem_dout : word_t;
signal dmem_din : word_t;
signal dmem_addr : word_t;
signal imem_addr : word_t;
signal imem_mem_out_en : std_logic;
signal dmem_mem_out_en : std_logic;
signal dmem_ack : std_logic;
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 bus_req : std_logic;
signal icache_mem_en : std_logic;
signal icache_mem_req : std_logic;
signal icache_mem_gnt : std_logic;
signal icache_mem_addr : word_t;
signal dcache_mem_en : std_logic;
signal dcache_mem_req : std_logic;
signal dcache_mem_gnt : std_logic;
signal dcache_mem_addr : word_t;
signal CYC_O_icache : std_logic;
signal CYC_O_dcache : std_logic;
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;
signal STB_O_icache : std_logic;
signal STB_O_dcache : std_logic;
signal STB_O_dmem : std_logic;
signal DAT_I_dmem : word_t;
signal DAT_O_dmem : word_t;
signal SEL_O_dmem : unsigned(3 downto 0);
signal WE_O_dmem : std_logic;
signal dcached : std_logic;
signal duncached_access : 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;
begin
mem_ce <= mem_rdy and bus_req;
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
if rising_edge(CLK_I) then
if RST_I = '1' then
STB_O <= '0';
elsif dmem_mem_gnt = '1' then
STB_O <= STB_O_dmem;
elsif dcache_mem_gnt = '1' then
STB_O <= STB_O_dcache;
elsif icache_mem_gnt = '1' then
STB_O <= STB_O_icache;
elsif SRDY_I = '1' then
STB_O <= '0';
end if;
end if;
end process;
bus_out:
process(CLK_I)
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');
elsif dmem_mem_gnt = '1' then
CYC_O <= CYC_O_dmem;
ADDR_O <= ADDR_O_dmem;
DAT_O <= DAT_O_dmem;
WE_O <= WE_O_dmem;
SEL_O <= SEL_O_dmem;
elsif dcache_mem_gnt = '1' then
CYC_O <= CYC_O_dcache;
ADDR_O <= ADDR_O_dcache;
elsif icache_mem_gnt = '1' then
CYC_O <= CYC_O_icache;
ADDR_O <= ADDR_O_icache;
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';
cpu_imem_rdy <= not icache_busy after 4.5 ns;
-- cpu_imem_din <= imem_din;
-- cpu_wait <= busy after 5.5 ns;
cpu_wait <= '0';
cpu_dmem_rdy <= not (dcache_busy1 or dcache_busy2) after 4.5 ns;
inst_icache : icache
@@ -160,20 +251,19 @@ inst_icache : icache
)
PORT MAP
(
clk => clk,
rst => rst,
CLK_I => CLK_I,
RST_I => RST_I,
STB_O => STB_O_icache,
CYC_O => CYC_O_icache,
ADDR_O => ADDR_O_icache,
DAT_I => DAT_I,
ACK_I => ACK_I,
SRDY_I => SRDY_I_icache,
en => '1',
cpu_en => cpu_imem_en,
cpu_addr => cpu_imem_addr,
cpu_dout => cpu_imem_din,
cpu_busy => icache_busy,
mem_en => icache_mem_en,
mem_req => icache_mem_req,
mem_gnt => icache_mem_gnt,
mem_addr => icache_mem_addr,
mem_din => mem_din,
mem_valid => mem_valid,
mem_rdy => mem_rdy
cpu_busy => icache_busy
);
inst_dcache : dcache
@@ -184,8 +274,14 @@ inst_dcache : dcache
)
PORT MAP
(
clk => clk,
rst => rst,
CLK_I => CLK_I,
RST_I => RST_I,
CYC_O => CYC_O_dcache,
STB_O => STB_O_dcache,
ADDR_O => ADDR_O_dcache,
DAT_I => DAT_I,
ACK_I => ACK_I,
SRDY_I => SRDY_I_dcache,
en => dcached,
cpu_en => dcache_en,
cpu_r_wn => cpu_dmem_re,
@@ -193,139 +289,160 @@ inst_dcache : dcache
cpu_addr => cpu_dmem_addr,
cpu_din => cpu_dmem_dout,
cpu_dout => dcache_dout,
cpu_busy => dcache_busy2,
mem_req => dcache_mem_req,
mem_gnt => dcache_mem_gnt,
mem_en => dcache_mem_en,
mem_addr => dcache_mem_addr,
mem_din => mem_din,
mem_valid => mem_valid,
mem_rdy => mem_rdy
cpu_busy => dcache_busy2
);
dcached <= '1' when cpu_dmem_addr(31 downto 28) /= X"A" else '0';
cpu_dmem_din <= dmem_din when duncached_access = '1' else dcache_dout; -- when dmem_valid = '1' else ram_dout after 0.5 ns;
cpu_dmem_din <= DAT_I_dmem when dmem_mem_gnt = '1' else dcache_dout;
dcache_en <= cpu_dmem_en and not dcache_busy1;
dcache_flags:
process(clk)
proc_busy:
process(CLK_I)
begin
if rising_edge(clk) then
if rst = '1' then
if rising_edge(CLK_I) then
if RST_I = '1' then
dcache_busy1 <= '0';
else
duncached_access <= '0';
if dmem_ack = '1' then
duncached_access <= '1';
if dmem_re = '1' then
if mem_valid = '1' then
dcache_busy1 <= '0';
end if;
else
dcache_busy1 <= '0';
end if;
end if;
if cpu_dmem_en = '1' and dcache_busy1 = '0' and dcache_busy2 = '0' then
dcache_busy1 <= '1';
if dcached = '1' and cpu_dmem_re = '1' then
dcache_busy1 <= '0';
end if;
end if;
end if;
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)
process(CLK_I)
begin
if rising_edge(clk) then
if cpu_dmem_en = '1' and dcache_busy1 = '0' and dcache_busy2 = '0' then
dmem_dout <= cpu_dmem_dout;
dmem_addr <= cpu_dmem_addr;
dmem_re <= cpu_dmem_re;
dmem_we <= cpu_dmem_we;
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 process;
dcache_data:
process(clk)
process(CLK_I)
begin
if rising_edge(clk) then
if rst = '1' then
dmem_din <= (others => '0');
elsif dcache_busy1 = '1' and mem_valid = '1' then
dmem_din <= mem_din;
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
DAT_I_dmem <= DAT_I;
end if;
end if;
end process;
cpu_access_state_next:
process(CLK_I)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
s_ca <= ca_init;
else
s_ca <= sn_ca;
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)
process(CLK_I)
begin
if rising_edge(clk) then
if rst = '1' then
if rising_edge(CLK_I) then
if RST_I = '1' then
s <= init;
elsif ce = '1' then
else
s <= sn;
end if;
end if;
end process;
bus_state:
process(s, icache_mem_en, icache_mem_req, dcache_busy1, dcache_mem_req, dcache_mem_en, dmem_re, mem_rdy, mem_valid)
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem)
begin
imem_mem_out_en <= '0';
dmem_mem_out_en <= '0';
icache_mem_gnt <= '0';
dcache_mem_gnt <= '0';
dmem_ack <= '0';
sn <= s;
icache_mem_gnt <= '0';
dcache_mem_gnt <= '0';
dmem_mem_gnt <= '0';
sn <= s;
case s is
when init =>
if mem_rdy = '1' then
sn <= ready;
end if;
sn <= ready;
when ready =>
if dcache_busy1 = '1' then
if mem_rdy = '1' then
dmem_mem_out_en <= '1';
if dmem_re = '0' then
sn <= d_bus_finish;
else
sn <= d_bus_access;
end if;
end if;
elsif icache_mem_req = '1' then
if CYC_O_dmem = '1' then
sn <= uncached_bus_access;
dmem_mem_gnt <= '1';
elsif CYC_O_icache = '1' then
sn <= i_cache_bus_access;
elsif dcache_mem_req = '1' then
icache_mem_gnt <= '1';
elsif CYC_O_dcache = '1' then
sn <= d_cache_bus_access;
dcache_mem_gnt <= '1';
end if;
when i_cache_bus_access =>
icache_mem_gnt <= '1';
if icache_mem_en = '1' then
imem_mem_out_en <= '1';
elsif icache_mem_req = '0' then
if CYC_O_icache = '0' then
sn <= ready;
-- icache_mem_gnt <= '0';
end if;
when d_cache_bus_access =>
dcache_mem_gnt <= '1';
if dcache_mem_en = '1' then
dmem_mem_out_en <= '1';
elsif dcache_mem_req = '0' then
if CYC_O_dcache = '0' then
sn <= ready;
-- dcache_mem_gnt <= '0';
end if;
when d_bus_access =>
if mem_valid = '1' then
dmem_ack <= '1';
sn <= ready;
end if;
when d_bus_finish =>
if mem_rdy = '1' then
dmem_ack <= '1';
sn <= ready;
when uncached_bus_access =>
dmem_mem_gnt <= '1';
if CYC_O_dmem = '0' then
sn <= ready;
-- dmem_mem_gnt <= '0';
end if;
when others =>
sn <= ready;
@@ -333,48 +450,6 @@ bus_state:
end process;
bus_request:
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
bus_req <= '0';
elsif dmem_mem_out_en = '1' or imem_mem_out_en = '1' then
bus_req <= '1';
elsif mem_rdy = '1' then
bus_req <= '0';
end if;
end if;
end process;
bus_out:
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
mem_dout <= (others => '0');
mem_addr <= (others => '0');
mem_re <= '0';
mem_we <= (others => '0');
elsif dmem_mem_out_en = '1' then
if dcache_mem_gnt = '1' then
mem_addr <= dcache_mem_addr;
mem_re <= '1';
mem_we <= (others => '0');
else
mem_dout <= dmem_dout;
mem_addr <= dmem_addr;
mem_re <= dmem_re;
mem_we <= dmem_we;
end if;
elsif imem_mem_out_en = '1' then
mem_addr <= icache_mem_addr;
mem_re <= '1';
mem_we <= (others => '0');
end if;
end if;
end process;
-------------------------------------------------------------------
end behavior;
+46 -44
View File
@@ -31,17 +31,19 @@ use work.mips_types.all;
entity mips_top is
Port
(
rst : in STD_LOGIC;
clk : in STD_LOGIC;
int : in unsigned (5 downto 0);
mem_valid : in STD_LOGIC;
mem_rdy : in STD_LOGIC;
mem_en : out STD_LOGIC;
mem_re : out STD_LOGIC;
mem_we : out unsigned(3 downto 0);
mem_din : in unsigned (WORD_WIDTH-1 downto 0);
mem_dout : out unsigned (WORD_WIDTH-1 downto 0);
mem_addr : out unsigned (WORD_WIDTH-1 downto 0)
RST_I : in STD_LOGIC;
CLK_I : in STD_LOGIC;
ACK_I : in STD_LOGIC;
SRDY_I : in STD_LOGIC;
ADDR_O : out word_t;
DAT_I : in word_t;
DAT_O : out word_t;
WE_O : out STD_LOGIC;
SEL_O : out unsigned(3 downto 0);
CYC_O : out STD_LOGIC;
STB_O : out STD_LOGIC;
MRDY_O : out STD_LOGIC;
INT : in unsigned (5 downto 0)
);
end mips_top;
@@ -67,7 +69,6 @@ architecture rtl of mips_top is
dmem_dout : out word_t
);
END COMPONENT;
signal halt : std_logic;
signal imem_rdy : std_logic;
signal imem_en : std_logic;
signal imem_addr : word_t;
@@ -80,13 +81,22 @@ architecture rtl of mips_top is
signal dmem_din : word_t;
signal dmem_we : unsigned(3 downto 0);
COMPONENT bui
Port
PORT
(
rst : in STD_LOGIC;
clk : in STD_LOGIC;
ce : in STD_LOGIC;
cpu_wait : out STD_LOGIC;
RST_I : in STD_LOGIC;
CLK_I : in STD_LOGIC;
ACK_I : in STD_LOGIC;
SRDY_I : in STD_LOGIC;
ADDR_O : out word_t;
DAT_I : in word_t;
DAT_O : out word_t;
WE_O : out STD_LOGIC;
SEL_O : out unsigned(3 downto 0);
CYC_O : out STD_LOGIC;
STB_O : out STD_LOGIC;
MRDY_O : out STD_LOGIC;
cpu_imem_rdy : out STD_LOGIC;
cpu_imem_en : in STD_LOGIC;
cpu_imem_addr : in word_t;
@@ -95,17 +105,9 @@ architecture rtl of mips_top is
cpu_dmem_en : in STD_LOGIC;
cpu_dmem_re : in STD_LOGIC;
cpu_dmem_we : in unsigned(3 downto 0);
cpu_dmem_addr : in word_t;
cpu_dmem_din : out word_t;
cpu_dmem_dout : in word_t;
mem_valid : in STD_LOGIC;
mem_rdy : in STD_LOGIC;
mem_addr : out word_t;
mem_din : in word_t;
mem_dout : out word_t;
mem_re : out STD_LOGIC;
mem_we : out unsigned(3 downto 0);
mem_ce : out STD_LOGIC
cpu_dmem_din : out word_t;
cpu_dmem_addr : in word_t
);
END COMPONENT;
@@ -116,10 +118,10 @@ begin
inst_pipeline: pipeline
PORT MAP
(
rst => rst,
clk => clk,
halt => halt,
int => int,
rst => RST_I,
clk => CLK_I,
halt => '0',
int => INT,
imem_rdy => imem_rdy,
imem_en => imem_en,
imem_addr => imem_addr,
@@ -136,10 +138,18 @@ inst_pipeline: pipeline
inst_bui: bui
PORT MAP
(
rst => rst,
clk => clk,
ce => '1',
cpu_wait => halt,
RST_I => RST_I,
CLK_I => CLK_I,
ACK_I => ACK_I,
SRDY_I => SRDY_I,
ADDR_O => ADDR_O,
DAT_I => DAT_I,
DAT_O => DAT_O,
WE_O => WE_O,
SEL_O => SEL_O,
CYC_O => CYC_O,
STB_O => STB_O,
MRDY_O => MRDY_O,
cpu_imem_rdy => imem_rdy,
cpu_imem_en => imem_en,
cpu_imem_addr => imem_addr,
@@ -150,15 +160,7 @@ inst_bui: bui
cpu_dmem_we => dmem_we,
cpu_dmem_addr => dmem_addr,
cpu_dmem_din => dmem_din,
cpu_dmem_dout => dmem_dout,
mem_valid => mem_valid,
mem_rdy => mem_rdy,
mem_addr => mem_addr,
mem_din => mem_din,
mem_dout => mem_dout,
mem_re => mem_re,
mem_we => mem_we,
mem_ce => mem_en
cpu_dmem_dout => dmem_dout
);
end rtl;