Initial revision

Committed on the Free edition of March Hare Software CVSNT Server.
Upgrade to CVS Suite for more features and support:
http://march-hare.com/cvsnt/


git-svn-id: http://moon:8086/svn/vhdl/branches/BRANCH_MIPS_TLB@1010 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2013-08-18 08:43:09 +00:00
parent 6dfac747b6
commit e5a31bdf7c
18 changed files with 6157 additions and 12 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+408
View File
@@ -0,0 +1,408 @@
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.mips_types.all;
use work.mips_util_pkg.all;
use work.busmaster_types.all;
ENTITY tb_biu_tlb IS
END tb_biu_tlb;
ARCHITECTURE behavior OF tb_biu_tlb IS
constant DATA_WIDTH : integer := 32;
constant CLK_PERIOD : time := 10 ns;
signal CLK : std_logic := '1';
signal RST : std_logic := '1';
signal INT_O : std_logic;
signal CYC_O : std_logic;
signal STB_O : std_logic;
signal WE_O : std_logic;
signal SEL_O : unsigned(3 downto 0) := (others => '1');
signal ACK_I : std_logic := '0';
signal MRDY_O : std_logic := '1';
signal SRDY_I : std_logic := '0';
signal ADDR_O : unsigned(31 downto 0) := (others => '-');
signal MDAT_I : unsigned(31 downto 0) := (others => '-');
signal MDAT_O : unsigned(31 downto 0) := (others => '-');
signal index_in : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
signal entry_we : STD_LOGIC := '0';
signal entry_lo_in : tlb_entry_lo_t;
signal entry_hi_in : tlb_entry_hi_t;
signal index_out : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
signal entry_re : STD_LOGIC := '0';
signal entry_lo_out : tlb_entry_lo_t;
signal entry_hi_out : tlb_entry_hi_t;
-- CPU control/data
signal cpu_imem_err : STD_LOGIC := '0';
signal cpu_imem_en : STD_LOGIC := '0';
signal cpu_imem_addr : word_t := (others => '-');
signal cpu_imem_dout : word_t;
signal cpu_imem_rdy : STD_LOGIC;
signal cpu_dmem_err : STD_LOGIC := '0';
signal cpu_dmem_en : STD_LOGIC := '0';
signal cpu_dmem_we : STD_LOGIC := '0';
signal cpu_dmem_addr : word_t := (others => '-');
signal cpu_dmem_be : unsigned(3 downto 0) := (others => '1');
signal cpu_dmem_din : word_t := X"BFC0_BABE";
signal cpu_dmem_dout : word_t;
signal cpu_dmem_rdy : STD_LOGIC;
-- BIU control
signal ctrl_in : biu_ctrl_in_t;
signal ctrl_out : biu_ctrl_out_t;
type op_descr_t is (op_idle, op_entry_i_write, op_entry_d_write, op_cpu_i_read, op_cpu_d_read, op_cpu_d_write);
signal op_descr : op_descr_t := op_idle;
signal cpu_imem_din_reg : word_t;
signal cpu_imem_din_vld : STD_LOGIC;
signal cpu_dmem_din_reg : word_t;
signal cpu_dmem_din_vld : STD_LOGIC;
BEGIN
inst_biu: entity work.biu
GENERIC MAP
(
icache_size => 1024, -- words
icache_line => 8, -- words
dcache_size => 1024, -- words
dcache_line => 8 -- words
)
PORT MAP
(
clk => CLK,
imem_err => cpu_imem_err,
imem_rdy => cpu_imem_rdy,
imem_en => cpu_imem_en,
imem_addr => cpu_imem_addr,
imem_dout => cpu_imem_dout,
dmem_err => cpu_dmem_err,
dmem_rdy => cpu_dmem_rdy,
dmem_en => cpu_dmem_en,
dmem_we => cpu_dmem_we,
dmem_be => cpu_dmem_be,
dmem_dout => cpu_dmem_dout,
dmem_din => cpu_dmem_din,
dmem_addr => cpu_dmem_addr,
RST_I => RST,
CLK_I => CLK,
ACK_I => ACK_I,
SRDY_I => SRDY_I,
ADDR_O => ADDR_O,
MDAT_I => MDAT_I,
MDAT_O => MDAT_O,
WE_O => WE_O,
SEL_O => SEL_O,
CYC_O => CYC_O,
STB_O => STB_O,
MRDY_O => MRDY_O,
ctrl_in => ctrl_in,
ctrl_out => ctrl_out
);
inst_rom_wb: entity work.rom_wb
-- GENERIC MAP
-- (
-- NUM_WORDS => 256
-- )
PORT MAP
(
CLK_I => CLK,
RST_I => RST,
CYC_I => CYC_O,
STB_I => STB_O,
-- SEL_I => SEL_O,
WE_I => WE_O,
ACK_O => ACK_I,
SRDY_O => SRDY_I,
MRDY_I => MRDY_O,
ADDR_I => ADDR_O,
-- DAT_I => MDAT_O,
DAT_O => MDAT_I
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
CLK <= not CLK;
end process;
cpu_imem_din_register:
process(clk)
variable en2: std_logic;
begin
if rising_edge(clk) then
cpu_imem_din_vld <= '0';
if en2 = '1' and cpu_imem_rdy = '1' then
cpu_imem_din_reg <= cpu_imem_dout;
cpu_imem_din_vld <= '1';
end if;
en2 := cpu_imem_en;
end if;
end process;
cpu_dmem_din_register:
process(clk)
variable en2: std_logic;
begin
if rising_edge(clk) then
cpu_dmem_din_vld <= '0';
if en2 = '1' and cpu_dmem_rdy = '1' then
cpu_dmem_din_reg <= cpu_dmem_dout;
cpu_dmem_din_vld <= '1';
end if;
en2 := cpu_dmem_en;
end if;
end process;
ctrl_in.icache.inv_addr <= X"BEEF_BABE";
ctrl_in.icache.inv_at <= '0';
ctrl_in.icache.inv_all <= '0';
ctrl_in.dcache.inv_addr <= X"BEEF_BABE";
ctrl_in.dcache.inv_at <= '0';
ctrl_in.dcache.inv_all <= '0';
STIMULUS: process
variable result : unsigned(31 downto 0);
procedure cmd_entry_i_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
begin
op_descr <= op_entry_i_write;
ctrl_in.itlb.entry_wr_idx <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
ctrl_in.itlb.entry_hi.vpn <= vpn;
ctrl_in.itlb.entry_hi.asid <= asid;
ctrl_in.itlb.entry_hi.g <= g;
ctrl_in.itlb.entry_lo.pfn <= pfn;
ctrl_in.itlb.entry_lo.n <= n;
ctrl_in.itlb.entry_lo.d <= d;
ctrl_in.itlb.entry_lo.v <= v;
ctrl_in.itlb.entry_we <= '1';
wait until rising_edge(CLK);
ctrl_in.itlb.entry_we <= '0';
end procedure cmd_entry_i_write;
procedure cmd_entry_d_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
begin
op_descr <= op_entry_d_write;
ctrl_in.dtlb.entry_wr_idx <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
ctrl_in.dtlb.entry_hi.vpn <= vpn;
ctrl_in.dtlb.entry_hi.asid <= asid;
ctrl_in.dtlb.entry_hi.g <= g;
ctrl_in.dtlb.entry_lo.pfn <= pfn;
ctrl_in.dtlb.entry_lo.n <= n;
ctrl_in.dtlb.entry_lo.d <= d;
ctrl_in.dtlb.entry_lo.v <= v;
ctrl_in.dtlb.entry_we <= '1';
wait until rising_edge(CLK);
ctrl_in.dtlb.entry_we <= '0';
end procedure cmd_entry_d_write;
procedure cpu_i_read(addr : unsigned) is
begin
op_descr <= op_cpu_i_read;
cpu_imem_addr <= addr;
cpu_imem_en <= '1';
wait until rising_edge(CLK) and cpu_imem_rdy = '1';
cpu_imem_en <= '0';
end procedure cpu_i_read;
procedure cpu_d_read(addr : unsigned) is
begin
op_descr <= op_cpu_d_read;
cpu_dmem_addr <= addr;
cpu_dmem_en <= '1';
wait until rising_edge(CLK) and cpu_dmem_rdy = '1';
cpu_dmem_en <= '0';
end procedure cpu_d_read;
procedure cpu_d_write(addr, data : unsigned) is
begin
op_descr <= op_cpu_d_write;
cpu_dmem_we <= '1';
cpu_dmem_addr <= addr;
cpu_dmem_din <= data;
cpu_dmem_en <= '1';
wait until rising_edge(CLK) and cpu_dmem_rdy = '1';
cpu_dmem_en <= '0';
end procedure cpu_d_write;
begin
wait for 6*CLK_PERIOD;
RST <= '0';
wait for 60*CLK_PERIOD;
wait until rising_edge(CLK) and cpu_imem_rdy = '1' and cpu_dmem_rdy = '1';
cmd_entry_i_write(0, "110000", X"0000_0", X"00DE_C", '0', '0', '0', '1');
cmd_entry_i_write(1, "110000", X"0000_1", X"11DE_C", '0', '0', '0', '1');
cmd_entry_i_write(2, "110000", X"0000_2", X"22DE_C", '0', '0', '0', '1');
cmd_entry_i_write(3, "110000", X"0000_3", X"33DE_C", '0', '0', '0', '1');
cmd_entry_i_write(4, "110000", X"0000_4", X"44DE_C", '0', '0', '0', '1');
cmd_entry_i_write(5, "110000", X"0000_5", X"55DE_C", '0', '0', '0', '1');
cmd_entry_i_write(6, "110000", X"0000_6", X"66DE_C", '0', '0', '0', '1');
cmd_entry_i_write(7, "110000", X"0000_7", X"77DE_C", '0', '0', '0', '1');
cmd_entry_d_write(0, "110000", X"0000_0", X"00DE_C", '0', '0', '0', '1');
cmd_entry_d_write(1, "110000", X"0000_1", X"11DE_C", '0', '0', '0', '1');
cmd_entry_d_write(2, "110000", X"0000_2", X"22DE_C", '0', '0', '0', '1');
cmd_entry_d_write(3, "110000", X"0000_3", X"33DE_C", '0', '0', '0', '1');
cmd_entry_d_write(4, "110000", X"0000_4", X"44DE_C", '0', '0', '0', '1');
cmd_entry_d_write(5, "110000", X"0000_5", X"55DE_C", '0', '0', '0', '1');
cmd_entry_d_write(6, "110000", X"0000_6", X"66DE_C", '0', '0', '0', '1');
cmd_entry_d_write(7, "110000", X"0000_7", X"77DE_C", '0', '0', '0', '1');
cpu_i_read(X"BFC0_0200");
cpu_i_read(X"BFC0_0180");
cpu_d_read(X"BFC0_0200");
cpu_i_read(X"8000_0204");
cpu_i_read(X"8000_0300");
cpu_i_read(X"8000_0304");
cpu_i_read(X"8000_0308");
cpu_i_read(X"9000_0208");
cpu_i_read(X"9000_030C");
cpu_i_read(X"9100_0310");
cpu_i_read(X"9200_0314");
cpu_i_read(X"A000_020C");
cpu_i_read(X"A000_0318");
cpu_i_read(X"A100_031C");
cpu_i_read(X"A200_0320");
cpu_i_read(X"B000_0210");
cpu_i_read(X"B000_0324");
cpu_i_read(X"B000_0328");
cpu_i_read(X"B000_032C");
cpu_i_read(X"0000_0400");
cpu_i_read(X"0000_1420");
cpu_i_read(X"0000_2440");
cpu_i_read(X"0000_3460");
cpu_i_read(X"0000_4480");
cpu_i_read(X"0000_54A0");
cpu_i_read(X"0000_64C0");
cpu_i_read(X"0000_74E0");
cpu_i_read(X"0000_8500");
cpu_i_read(X"0000_9520");
cpu_i_read(X"0000_0400");
cpu_i_read(X"0000_1420");
cpu_i_read(X"0000_2440");
cpu_i_read(X"0000_3460");
cpu_i_read(X"0000_4480");
cpu_i_read(X"0000_54A0");
cpu_i_read(X"0000_64C0");
cpu_i_read(X"0000_74E0");
cpu_i_read(X"0000_0400");
cpu_i_read(X"0000_0410");
cpu_i_read(X"0000_0404");
cpu_i_read(X"0000_0408");
cpu_i_read(X"0000_0404");
cpu_i_read(X"0000_0434");
cpu_i_read(X"0000_0400");
---------------------------------------------
cpu_d_read(X"BFC0_0200");
cpu_d_read(X"BFC0_0180");
cpu_d_read(X"8000_0204");
cpu_d_read(X"8000_0300");
cpu_d_read(X"8000_0304");
cpu_d_read(X"8000_0308");
cpu_d_read(X"9000_0208");
cpu_d_read(X"9000_030C");
cpu_d_read(X"9100_0310");
cpu_d_read(X"9200_0314");
cpu_d_read(X"A000_020C");
cpu_d_read(X"A000_0318");
cpu_d_read(X"A100_031C");
cpu_d_read(X"A200_0320");
cpu_d_read(X"B000_0210");
cpu_d_read(X"B000_0324");
cpu_d_read(X"B000_0328");
cpu_d_read(X"B000_032C");
cpu_d_read(X"0000_0400");
cpu_d_read(X"0000_1420");
cpu_d_read(X"0000_2440");
cpu_d_read(X"0000_3460");
cpu_d_read(X"0000_4480");
cpu_d_read(X"0000_54A0");
cpu_d_read(X"0000_64C0");
cpu_d_read(X"0000_74E0");
cpu_d_read(X"0000_8500");
cpu_d_read(X"0000_9520");
cpu_d_read(X"0000_0400");
cpu_d_read(X"0000_1420");
cpu_d_read(X"0000_2440");
cpu_d_read(X"0000_3460");
cpu_d_read(X"0000_4480");
cpu_d_read(X"0000_54A0");
cpu_d_read(X"0000_64C0");
cpu_d_read(X"0000_74E0");
cpu_d_write(X"0000_0400", X"AAAA_AAAA");
cpu_d_read(X"0000_0400");
cpu_d_read(X"0000_0410");
cpu_d_read(X"0000_0404");
cpu_d_read(X"0000_0408");
cpu_d_write(X"0000_0404", X"5555_5555");
cpu_d_read(X"0000_0404");
cpu_d_write(X"0000_0404", X"6666_6666");
cpu_d_read(X"0000_0434");
cpu_d_write(X"0000_0400", X"1111_1111");
cpu_d_write(X"0000_0404", X"2222_2222");
cpu_d_write(X"0000_0408", X"3333_3333");
cpu_d_write(X"0000_040C", X"4444_4444");
cpu_d_read(X"0000_0400");
wait;
end process;
END;
+161
View File
@@ -0,0 +1,161 @@
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.mips_types.all;
use work.mips_util_pkg.all;
ENTITY tb_cam IS
END tb_cam;
ARCHITECTURE behavior OF tb_cam IS
constant CLK_PERIOD : time := 10 ns;
constant DATA_WIDTH : integer := 20;
constant CAM_NUM_ENTRIES : integer := 32;
signal CLK_O : std_logic := '1';
signal RST_O : std_logic := '1';
signal cam_we : std_logic := '0';
signal cam_re : std_logic := '0';
signal cam_vld : std_logic := '0';
signal cam_rdy : std_logic := '-';
signal cam_addr : unsigned(lg2(CAM_NUM_ENTRIES)-1 downto 0) := (others => '0');
signal cam_data : unsigned(DATA_WIDTH-1 downto 0) := (others => '0');
signal cam_hit : unsigned (CAM_NUM_ENTRIES-1 downto 0);
signal cam_hit_vld : std_logic := '-';
BEGIN
inst_cam: entity work.cam
GENERIC MAP
(
NUM_ENTRIES => CAM_NUM_ENTRIES,
DATA_WIDTH => DATA_WIDTH,
CAM_RAM_MAX_WIDTH => 15
)
PORT MAP
(
rst => RST_O,
clk => CLK_O,
rdy => cam_rdy,
re => cam_re,
we => cam_we,
vld => cam_vld,
addr => cam_addr,
din => cam_data,
hit => cam_hit,
hit_vld => cam_hit_vld
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
CLK_O <= not CLK_O;
end process;
STIMULUS: process
variable result : unsigned(31 downto 0);
procedure cam_entry_write(index : integer; data : unsigned; valid : std_logic) is
begin
cam_data <= data;
cam_addr <= to_unsigned(index, lg2(CAM_NUM_ENTRIES));
cam_vld <= valid;
cam_we <= '1';
wait until rising_edge(CLK_O) and cam_rdy = '1';
cam_we <= '0';
end procedure cam_entry_write;
procedure cam_lookup(data : unsigned) is
begin
cam_data <= data;
cam_re <= '1';
wait until rising_edge(CLK_O) and cam_rdy = '1';
cam_re <= '0';
end procedure cam_lookup;
begin
wait for 6*CLK_PERIOD;
RST_O <= '0';
wait for 60*CLK_PERIOD;
wait until rising_edge(CLK_O) and cam_rdy = '1';
cam_entry_write(1, X"CAFE_1", '1');
cam_entry_write(2, X"CAFE_2", '1');
wait for 8*CLK_PERIOD;
wait until rising_edge(CLK_O) and cam_rdy = '1';
cam_lookup(X"CAFE_1");
cam_lookup(X"CAFE_2");
wait for 8*CLK_PERIOD;
wait until rising_edge(CLK_O) and cam_rdy = '1';
-- overwrite
cam_entry_write(2, X"BEEF_2", '1');
wait for 8*CLK_PERIOD;
wait until rising_edge(CLK_O) and cam_rdy = '1';
-- overwrite entry
cam_entry_write(2, X"CAFE_2", '1');
-- new entry
cam_entry_write(3, X"CAFE_3", '1');
cam_entry_write(4, X"CAFE_4", '1');
wait for 8*CLK_PERIOD;
wait until rising_edge(CLK_O) and cam_rdy = '1';
cam_entry_write(1, X"CAFE_1", '0');
cam_entry_write(2, X"CAFE_2", '0');
cam_entry_write(3, X"CAFE_3", '0');
cam_entry_write(4, X"CAFE_4", '0');
wait for 8*CLK_PERIOD;
wait until rising_edge(CLK_O) and cam_rdy = '1';
cam_lookup(X"BEEF_2");
cam_lookup(X"CAFE_1");
cam_lookup(X"CAFE_2");
cam_lookup(X"CAFE_3");
cam_lookup(X"CAFE_4");
wait for 8*CLK_PERIOD;
wait until rising_edge(CLK_O) and cam_rdy = '1';
cam_entry_write(1, X"CAFE_1", '1');
cam_entry_write(2, X"CAFE_2", '1');
cam_entry_write(3, X"CAFE_3", '1');
cam_entry_write(4, X"CAFE_4", '1');
wait for 8*CLK_PERIOD;
wait until rising_edge(CLK_O) and cam_rdy = '1';
cam_lookup(X"CAFE_1");
cam_lookup(X"CAFE_2");
cam_lookup(X"CAFE_3");
cam_lookup(X"CAFE_4");
wait for 8*CLK_PERIOD;
wait until rising_edge(CLK_O) and cam_rdy = '1';
cam_entry_write(7, X"CAFE_7", '0');
wait for 8*CLK_PERIOD;
wait until rising_edge(CLK_O) and cam_rdy = '1';
wait;
end process;
END;
+389
View File
@@ -0,0 +1,389 @@
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.mips_types.all;
use work.mips_util_pkg.all;
use work.busmaster_types.all;
ENTITY tb_dcache_tlb IS
END tb_dcache_tlb;
ARCHITECTURE behavior OF tb_dcache_tlb IS
constant DATA_WIDTH : integer := 32;
constant CLK_PERIOD : time := 10 ns;
constant TLB_NUM_ENTRIES : integer := 8;
signal CLK : std_logic := '1';
signal RST : std_logic := '1';
signal INT_O : std_logic;
signal CYC_O : std_logic;
signal STB_O : std_logic;
signal WE_O : std_logic;
signal SEL_O : unsigned(3 downto 0) := (others => '1');
signal ACK_I : std_logic := '0';
signal MRDY_O : std_logic := '1';
signal SRDY_I : std_logic := '0';
signal ADDR_O : unsigned(31 downto 0) := (others => '-');
signal MDAT_I : unsigned(31 downto 0) := (others => '-');
signal MDAT_O : unsigned(31 downto 0) := (others => '-');
signal ce : std_logic := '1';
signal index_in : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
signal entry_we : STD_LOGIC := '0';
signal entry_lo_in : tlb_entry_lo_t;
signal entry_hi_in : tlb_entry_hi_t;
signal index_out : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
signal entry_re : STD_LOGIC := '0';
signal entry_lo_out : tlb_entry_lo_t;
signal entry_hi_out : tlb_entry_hi_t;
signal tlb_in : tlb_query_in_t;
signal tlb_out : tlb_query_out_t;
signal tlb_index_hit : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0);
signal tlb_va : word_t := (others => '-');
signal tlb_pa : word_t;
signal tlb_flags : tlb_flags_t;
signal tlb_hit : STD_LOGIC;
-- CPU control/data
signal cpu_en : STD_LOGIC := '0';
signal cpu_we : STD_LOGIC := '0';
signal cpu_addr : word_t := (others => '-');
signal cpu_be : unsigned(3 downto 0) := (others => '1');
signal cpu_din : word_t := X"BFC0_BABE";
signal cpu_dout : word_t;
signal cpu_rdy : STD_LOGIC;
-- Cache control
signal dcache_ctrl_in : cache_ctrl_t;
-- busmaster data
signal bus_din : word_t := (others => '-');
signal bus_din_rdy : std_logic := '0';
signal bus_din_vld : std_logic := '0';
signal bus_dout : word_t := (others => '-');
signal bus_dout_vld : std_logic := '0';
signal bus_dout_rdy : std_logic := '0';
-- busmaster command
signal bus_cmd_rdy : std_logic := '0';
signal bus_cmd_we : std_logic := '0';
signal bus_cmd_cycle_en : std_logic := '0';
signal bus_cmd : bm_cmd_t;
signal bus_cyc_complete : std_logic := '0';
signal cpu_din_reg : word_t;
signal cpu_din_vld : STD_LOGIC;
BEGIN
inst_tlb : entity work.tlb
GENERIC MAP
(
NUM_ENTRIES => TLB_NUM_ENTRIES
)
PORT MAP
(
-- System signals
rst => RST,
clk => CLK,
ce => ce,
index_in => index_in,
entry_we => entry_we,
entry_lo_in => entry_lo_in,
entry_hi_in => entry_hi_in,
index_out => index_out,
entry_re => entry_re,
entry_lo_out => entry_lo_out,
entry_hi_out => entry_hi_out,
tlb_query_in => tlb_in,
tlb_query_out => tlb_out
);
dcache_ctrl_in.inv_addr <= X"BEEF_BABE";
dcache_ctrl_in.inv_at <= '0';
dcache_ctrl_in.inv_all <= '0';
inst_dcache: entity work.dcache
GENERIC MAP
(
cache_size => 1024,
line_size => 8
)
PORT MAP
(
rst => RST,
clk => CLK,
-- CPU control/data
en => cpu_en,
we => cpu_we,
addr => cpu_addr,
be => cpu_be,
din => cpu_din,
dout => cpu_dout,
rdy => cpu_rdy,
-- Cache control
ctrl_in => dcache_ctrl_in,
tlb_query_in => tlb_out,
tlb_query_out => tlb_in,
-- busmaster data
bus_din => bus_din,
bus_din_rdy => bus_din_rdy,
bus_din_vld => bus_din_vld,
bus_dout => bus_dout,
bus_dout_vld => bus_dout_vld,
bus_dout_rdy => bus_dout_rdy,
-- busmaster command
bus_cmd_rdy => bus_cmd_rdy,
bus_cmd_we => bus_cmd_we,
bus_cmd_cycle_en => bus_cmd_cycle_en,
bus_cmd_out => bus_cmd,
bus_cyc_complete => bus_cyc_complete
);
inst_busmaster_sync : entity work.busmaster_sync
GENERIC MAP
(
DATA_WIDTH => DATA_WIDTH,
FIFO_DEPTH => 4
)
PORT MAP
(
-- System signals
rst => RST,
clk => CLK,
cmd_cycle_finished => bus_cyc_complete,
cmd_cycle_en => bus_cmd_cycle_en,
cmd_rdy => bus_cmd_rdy,
cmd_we => bus_cmd_we,
cmd_in => bus_cmd,
din_rdy => bus_dout_rdy,
din_we => bus_dout_vld,
din => bus_dout,
dout => bus_din,
dout_vld => bus_din_vld,
dout_re => bus_din_rdy,
-- JBUS Master signals
CYC_O => CYC_O,
STB_O => STB_O,
WE_O => WE_O,
SEL_O => SEL_O,
ACK_I => ACK_I,
SRDY_I => SRDY_I,
MRDY_O => MRDY_O,
ADDR_O => ADDR_O,
MDAT_I => MDAT_I,
MDAT_O => MDAT_O
);
inst_rom_wb: entity work.rom_wb
-- GENERIC MAP
-- (
-- NUM_WORDS => 256
-- )
PORT MAP
(
CLK_I => CLK,
RST_I => RST,
CYC_I => CYC_O,
STB_I => STB_O,
-- SEL_I => SEL_O,
WE_I => WE_O,
ACK_O => ACK_I,
SRDY_O => SRDY_I,
MRDY_I => MRDY_O,
ADDR_I => ADDR_O,
-- DAT_I => MDAT_O,
DAT_O => MDAT_I
);
cpu_din_register:
process(clk)
variable en2: std_logic;
begin
if rising_edge(clk) then
cpu_din_vld <= '0';
if en2 = '1' and cpu_rdy = '1' then
cpu_din_reg <= cpu_dout;
cpu_din_vld <= '1';
end if;
en2 := cpu_en;
end if;
end process;
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
CLK <= not CLK;
end process;
STIMULUS: process
variable result : unsigned(31 downto 0);
procedure cmd_entry_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
begin
index_in <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
entry_hi_in.vpn <= vpn;
entry_hi_in.asid <= asid;
entry_hi_in.g <= g;
entry_lo_in.pfn <= pfn;
entry_lo_in.n <= n;
entry_lo_in.d <= d;
entry_lo_in.v <= v;
entry_we <= '1';
wait until rising_edge(CLK);
entry_we <= '0';
end procedure cmd_entry_write;
procedure cpu_read(addr : unsigned) is
begin
cpu_we <= '0';
cpu_addr <= addr;
cpu_en <= '1';
wait until rising_edge(CLK) and cpu_rdy = '1';
cpu_en <= '0';
end procedure cpu_read;
procedure cpu_write(addr, data : unsigned) is
begin
cpu_we <= '1';
cpu_addr <= addr;
cpu_din <= data;
cpu_en <= '1';
wait until rising_edge(CLK) and cpu_rdy = '1';
cpu_en <= '0';
end procedure cpu_write;
begin
wait for 6*CLK_PERIOD;
RST <= '0';
wait for 60*CLK_PERIOD;
wait until rising_edge(CLK) and cpu_rdy = '1';
cmd_entry_write(0, "110000", X"0000_0", X"00DE_C", '0', '0', '0', '1');
cmd_entry_write(1, "110000", X"0000_1", X"11DE_C", '0', '0', '0', '1');
cmd_entry_write(2, "110000", X"0000_2", X"22DE_C", '0', '0', '0', '1');
cmd_entry_write(3, "110000", X"0000_3", X"33DE_C", '0', '0', '0', '1');
cmd_entry_write(4, "110000", X"0000_4", X"44DE_C", '0', '0', '0', '1');
cmd_entry_write(5, "110000", X"0000_5", X"55DE_C", '0', '0', '0', '1');
cmd_entry_write(6, "110000", X"0000_6", X"66DE_C", '0', '0', '0', '1');
cmd_entry_write(7, "110000", X"0000_7", X"77DE_C", '0', '0', '0', '1');
cpu_read(X"BFC0_0200");
cpu_read(X"BFC0_0180");
cpu_read(X"8000_0204");
cpu_read(X"8000_0300");
cpu_read(X"8000_0304");
cpu_read(X"8000_0308");
cpu_read(X"9000_0208");
cpu_read(X"9000_030C");
cpu_read(X"9100_0310");
cpu_read(X"9200_0314");
cpu_read(X"A000_020C");
cpu_read(X"A000_0318");
cpu_read(X"A100_031C");
cpu_read(X"A200_0320");
cpu_read(X"B000_0210");
cpu_read(X"B000_0324");
cpu_read(X"B000_0328");
cpu_read(X"B000_032C");
cpu_read(X"0000_0400");
cpu_read(X"0000_1420");
cpu_read(X"0000_2440");
cpu_read(X"0000_3460");
cpu_read(X"0000_4480");
cpu_read(X"0000_54A0");
cpu_read(X"0000_64C0");
cpu_read(X"0000_74E0");
cpu_read(X"0000_8500");
cpu_read(X"0000_9520");
cpu_read(X"0000_0400");
cpu_read(X"0000_1420");
cpu_read(X"0000_2440");
cpu_read(X"0000_3460");
cpu_read(X"0000_4480");
cpu_read(X"0000_54A0");
cpu_read(X"0000_64C0");
cpu_read(X"0000_74E0");
cpu_write(X"0000_0400", X"AAAA_AAAA");
-- cmd_entry_write(0, "110000", X"0000_0", X"40DE_F", '0', '0', '1', '1');
cpu_read(X"0000_0400");
cpu_read(X"0000_0410");
cpu_read(X"0000_0404");
cpu_read(X"0000_0408");
cpu_write(X"0000_0404", X"5555_5555");
cpu_read(X"0000_0404");
cpu_write(X"0000_0404", X"6666_6666");
cpu_read(X"0000_0434");
cpu_write(X"0000_0400", X"1111_1111");
cpu_write(X"0000_0404", X"2222_2222");
cpu_write(X"0000_0408", X"3333_3333");
cpu_write(X"0000_040C", X"4444_4444");
cpu_write(X"0000_0400", X"1111_1111");
cpu_write(X"0000_0404", X"2222_2222");
cpu_write(X"0000_0408", X"3333_3333");
cpu_write(X"0000_040C", X"4444_4444");
cpu_write(X"0000_0400", X"1111_1111");
cpu_write(X"0000_0404", X"2222_2222");
cpu_write(X"0000_0408", X"3333_3333");
cpu_write(X"0000_040C", X"4444_4444");
cpu_write(X"0000_0400", X"1111_1111");
cpu_write(X"0000_0404", X"2222_2222");
cpu_write(X"0000_0408", X"3333_3333");
cpu_write(X"0000_040C", X"4444_4444");
cpu_write(X"0000_0400", X"1111_1111");
cpu_write(X"0000_0404", X"2222_2222");
cpu_write(X"0000_0408", X"3333_3333");
cpu_write(X"0000_040C", X"4444_4444");
cpu_read(X"0000_0400");
wait;
end process;
END;
+363
View File
@@ -0,0 +1,363 @@
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.mips_types.all;
use work.mips_util_pkg.all;
use work.busmaster_types.all;
ENTITY tb_icache_tlb IS
END tb_icache_tlb;
ARCHITECTURE behavior OF tb_icache_tlb IS
constant DATA_WIDTH : integer := 32;
constant CLK_PERIOD : time := 10 ns;
constant TLB_NUM_ENTRIES : integer := 8;
signal CLK : std_logic := '1';
signal RST : std_logic := '1';
signal INT_O : std_logic;
signal CYC_O : std_logic;
signal STB_O : std_logic;
signal WE_O : std_logic;
signal SEL_O : unsigned(3 downto 0) := (others => '1');
signal ACK_I : std_logic := '0';
signal MRDY_O : std_logic := '1';
signal SRDY_I : std_logic := '0';
signal ADDR_O : unsigned(31 downto 0) := (others => '-');
signal MDAT_I : unsigned(31 downto 0) := (others => '-');
signal MDAT_O : unsigned(31 downto 0) := (others => '-');
signal ce : std_logic := '1';
signal index_in : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
signal entry_we : STD_LOGIC := '0';
signal entry_lo_in : tlb_entry_lo_t;
signal entry_hi_in : tlb_entry_hi_t;
signal index_out : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
signal entry_re : STD_LOGIC := '0';
signal entry_lo_out : tlb_entry_lo_t;
signal entry_hi_out : tlb_entry_hi_t;
signal tlb_in : tlb_query_in_t;
signal tlb_out : tlb_query_out_t;
signal tlb_index_hit : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0);
signal tlb_va : word_t := (others => '-');
signal tlb_pa : word_t;
signal tlb_flags : tlb_flags_t;
signal tlb_hit : STD_LOGIC;
-- CPU control/data
signal cpu_en : STD_LOGIC := '0';
signal cpu_we : STD_LOGIC := '0';
signal cpu_be : unsigned(3 downto 0) := (others => '1');
signal cpu_addr : word_t := (others => '-');
signal cpu_dout : word_t;
signal cpu_din : word_t := X"BFC0_BABE";
signal cpu_rdy : STD_LOGIC;
-- Cache control
signal icache_ctrl_in : cache_ctrl_t;
-- busmaster data
signal bus_din : word_t := (others => '-');
signal bus_din_rdy : std_logic := '0';
signal bus_din_vld : std_logic := '0';
signal bus_dout : word_t := (others => '-');
signal bus_dout_vld : std_logic := '0';
signal bus_dout_rdy : std_logic := '0';
-- busmaster command
signal bus_cmd_rdy : std_logic := '0';
signal bus_cmd_we : std_logic := '0';
signal bus_cmd_cycle_en : std_logic := '0';
signal bus_cmd : bm_cmd_t;
signal bus_cyc_complete : std_logic := '0';
signal cpu_din_reg : word_t;
signal cpu_din_vld : STD_LOGIC;
BEGIN
inst_tlb : entity work.tlb
GENERIC MAP
(
NUM_ENTRIES => TLB_NUM_ENTRIES
)
PORT MAP
(
-- System signals
rst => RST,
clk => CLK,
ce => ce,
index_in => index_in,
entry_we => entry_we,
entry_lo_in => entry_lo_in,
entry_hi_in => entry_hi_in,
index_out => index_out,
entry_re => entry_re,
entry_lo_out => entry_lo_out,
entry_hi_out => entry_hi_out,
tlb_query_in => tlb_in,
tlb_query_out => tlb_out
);
icache_ctrl_in.inv_addr <= X"BEEF_BABE";
icache_ctrl_in.inv_at <= '0';
icache_ctrl_in.inv_all <= '0';
inst_icache: entity work.icache
GENERIC MAP
(
cache_size => 1024,
line_size => 8
)
PORT MAP
(
rst => RST,
clk => CLK,
-- CPU control/data
en => cpu_en,
addr => cpu_addr,
dout => cpu_dout,
rdy => cpu_rdy,
-- Cache control
ctrl_in => icache_ctrl_in,
tlb_query_in => tlb_out,
tlb_query_out => tlb_in,
-- busmaster data
bus_din => bus_din,
bus_din_rdy => bus_din_rdy,
bus_din_vld => bus_din_vld,
-- busmaster command
bus_cmd_rdy => bus_cmd_rdy,
bus_cmd_we => bus_cmd_we,
bus_cmd_cycle_en => bus_cmd_cycle_en,
bus_cmd_out => bus_cmd,
bus_cyc_complete => bus_cyc_complete
);
inst_busmaster_sync : entity work.busmaster_sync
GENERIC MAP
(
DATA_WIDTH => DATA_WIDTH,
FIFO_DEPTH => 4
)
PORT MAP
(
-- System signals
rst => RST,
clk => CLK,
cmd_cycle_finished => bus_cyc_complete,
cmd_cycle_en => bus_cmd_cycle_en,
cmd_rdy => bus_cmd_rdy,
cmd_we => bus_cmd_we,
cmd_in => bus_cmd,
din_rdy => bus_dout_rdy,
din_we => bus_dout_vld,
din => bus_dout,
dout => bus_din,
dout_vld => bus_din_vld,
dout_re => bus_din_rdy,
-- JBUS Master signals
CYC_O => CYC_O,
STB_O => STB_O,
WE_O => WE_O,
SEL_O => SEL_O,
ACK_I => ACK_I,
SRDY_I => SRDY_I,
MRDY_O => MRDY_O,
ADDR_O => ADDR_O,
MDAT_I => MDAT_I,
MDAT_O => MDAT_O
);
inst_rom_wb: entity work.rom_wb
-- GENERIC MAP
-- (
-- NUM_WORDS => 256
-- )
PORT MAP
(
CLK_I => CLK,
RST_I => RST,
CYC_I => CYC_O,
STB_I => STB_O,
-- SEL_I => SEL_O,
WE_I => WE_O,
ACK_O => ACK_I,
SRDY_O => SRDY_I,
MRDY_I => MRDY_O,
ADDR_I => ADDR_O,
-- DAT_I => MDAT_O,
DAT_O => MDAT_I
);
cpu_din_register:
process(clk)
variable en2: std_logic;
begin
if rising_edge(clk) then
cpu_din_vld <= '0';
if en2 = '1' and cpu_rdy = '1' then
cpu_din_reg <= cpu_dout;
cpu_din_vld <= '1';
end if;
en2 := cpu_en;
end if;
end process;
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
CLK <= not CLK;
end process;
STIMULUS: process
variable result : unsigned(31 downto 0);
procedure cmd_entry_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
begin
index_in <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
entry_hi_in.vpn <= vpn;
entry_hi_in.asid <= asid;
entry_hi_in.g <= g;
entry_lo_in.pfn <= pfn;
entry_lo_in.n <= n;
entry_lo_in.d <= d;
entry_lo_in.v <= v;
entry_we <= '1';
wait until rising_edge(CLK);
entry_we <= '0';
end procedure cmd_entry_write;
procedure cpu_read(addr : unsigned) is
begin
cpu_we <= '0';
cpu_addr <= addr;
cpu_en <= '1';
wait until rising_edge(CLK) and cpu_rdy = '1';
cpu_en <= '0';
wait for 60*CLK_PERIOD;
wait until rising_edge(CLK);
end procedure cpu_read;
procedure cpu_write(addr, data : unsigned) is
begin
cpu_we <= '1';
cpu_addr <= addr;
cpu_din <= data;
cpu_en <= '1';
wait until rising_edge(CLK) and cpu_rdy = '1';
cpu_en <= '0';
wait for 60*CLK_PERIOD;
wait until rising_edge(CLK);
end procedure cpu_write;
begin
wait for 6*CLK_PERIOD;
RST <= '0';
wait for 60*CLK_PERIOD;
wait until rising_edge(CLK) and cpu_rdy = '1';
cmd_entry_write(0, "110000", X"0000_0", X"00DE_F", '0', '0', '0', '1');
cmd_entry_write(1, "110000", X"0000_1", X"11DE_F", '0', '0', '0', '1');
cmd_entry_write(2, "110000", X"0000_2", X"22DE_F", '0', '0', '0', '1');
cmd_entry_write(3, "110000", X"0000_3", X"33DE_F", '0', '0', '0', '1');
cmd_entry_write(4, "110000", X"0000_4", X"44DE_F", '0', '0', '0', '1');
cmd_entry_write(5, "110000", X"0000_5", X"55DE_F", '0', '0', '0', '1');
cmd_entry_write(6, "110000", X"0000_6", X"66DE_F", '0', '0', '0', '1');
cmd_entry_write(7, "110000", X"0000_7", X"77DE_F", '0', '0', '0', '1');
cpu_read(X"BFC0_0200");
cpu_read(X"BFC0_0180");
cpu_read(X"8000_0204");
cpu_read(X"8000_0300");
cpu_read(X"8000_0304");
cpu_read(X"8000_0308");
cpu_read(X"9000_0208");
cpu_read(X"9000_030C");
cpu_read(X"9100_0310");
cpu_read(X"9200_0314");
cpu_read(X"A000_020C");
cpu_read(X"A000_0318");
cpu_read(X"A100_031C");
cpu_read(X"A200_0320");
cpu_read(X"B000_0210");
cpu_read(X"B000_0324");
cpu_read(X"B000_0328");
cpu_read(X"B000_032C");
cpu_read(X"0000_0400");
cpu_read(X"0000_1420");
cpu_read(X"0000_2440");
cpu_read(X"0000_3460");
cpu_read(X"0000_4480");
cpu_read(X"0000_54A0");
cpu_read(X"0000_64C0");
cpu_read(X"0000_74E0");
cpu_read(X"0000_8500");
cpu_read(X"0000_9520");
cpu_read(X"0000_0400");
cpu_read(X"0000_1420");
cpu_read(X"0000_2440");
cpu_read(X"0000_3460");
cpu_read(X"0000_4480");
cpu_read(X"0000_54A0");
cpu_read(X"0000_64C0");
cpu_read(X"0000_74E0");
cpu_write(X"0000_0400", X"AAAA_AAAA");
-- cmd_entry_write(0, "110000", X"0000_0", X"40DE_F", '0', '0', '1', '1');
cpu_read(X"0000_0400");
cpu_read(X"0000_0410");
cpu_read(X"0000_0404");
cpu_read(X"0000_0408");
cpu_write(X"0000_0404", X"5555_5555");
cpu_read(X"0000_0404");
cpu_read(X"0000_0400");
wait;
end process;
END;
+211
View File
@@ -0,0 +1,211 @@
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
library work;
use work.mips_types.all;
use work.mips_util_pkg.all;
ENTITY tb_tlb IS
END tb_tlb;
ARCHITECTURE behavior OF tb_tlb IS
constant DATA_WIDTH : integer := 32;
constant CLK_PERIOD : time := 10 ns;
signal CLK_O : std_logic := '1';
signal RST_O : std_logic := '1';
signal ce : std_logic := '1';
signal tlb_rdy : std_logic;
signal tlb_ctrl_in : tlb_ctrl_in_t;
signal tlb_ctrl_out : tlb_ctrl_out_t;
signal tlb_query_in : tlb_query_in_t;
signal tlb_query_out : tlb_query_out_t;
BEGIN
inst_uut : entity work.tlb
GENERIC MAP
(
NUM_ENTRIES => TLB_NUM_ENTRIES,
CACHE_KSEG1 => false,
USE_TLB => true
)
PORT MAP
(
-- System signals
rst => RST_O,
clk => CLK_O,
ce => ce,
rdy => tlb_rdy,
ctrl_in => tlb_ctrl_in,
ctrl_out => tlb_ctrl_out,
query_in => tlb_query_in,
query_out => tlb_query_out
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
CLK_O <= not CLK_O;
end process;
STIMULUS: process
variable result : unsigned(31 downto 0);
procedure cmd_entry_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
begin
tlb_ctrl_in.entry_wr_idx <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
tlb_ctrl_in.entry_hi.vpn <= vpn;
tlb_ctrl_in.entry_hi.asid <= asid;
tlb_ctrl_in.entry_lo.pfn <= pfn;
tlb_ctrl_in.entry_lo.g <= g;
tlb_ctrl_in.entry_lo.n <= n;
tlb_ctrl_in.entry_lo.d <= d;
tlb_ctrl_in.entry_lo.v <= v;
tlb_ctrl_in.entry_we <= '1';
wait until rising_edge(CLK_O) and tlb_rdy = '1';
tlb_ctrl_in.entry_we <= '0';
end procedure cmd_entry_write;
procedure cmd_read_single(addr : unsigned) is
begin
end procedure cmd_read_single;
begin
tlb_ctrl_in.entry_we <= '0';
tlb_ctrl_in.entry_re <= '0';
tlb_query_in.vld <= '0';
tlb_query_in.write <= '0';
tlb_query_in.vaddr <= X"BFC0_CAFE";
wait for 6*CLK_PERIOD;
RST_O <= '0';
wait for 60*CLK_PERIOD;
wait until rising_edge(CLK_O) and tlb_rdy = '1';
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '1';
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '0';
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '1';
tlb_query_in.vaddr <= X"9FC0_CAFE";
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '0';
cmd_entry_write(0, "110000", X"0000_0", X"00DE_F", '0', '0', '0', '1');
cmd_entry_write(1, "110000", X"0000_1", X"01DE_F", '0', '0', '0', '1');
cmd_entry_write(2, "110000", X"0000_2", X"02DE_F", '0', '0', '0', '0');
cmd_entry_write(3, "110000", X"0000_3", X"43DE_F", '0', '0', '0', '1');
cmd_entry_write(4, "100000", X"0000_4", X"44DE_F", '0', '0', '0', '1');
cmd_entry_write(5, "110000", X"0000_5", X"65DE_F", '0', '0', '0', '1');
cmd_entry_write(6, "100000", X"0000_6", X"66DE_F", '1', '0', '0', '1');
cmd_entry_write(7, "110000", X"0000_7", X"67DE_F", '0', '0', '0', '1');
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '1';
tlb_query_in.vaddr <= X"8000_BABE";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"8000_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"8100_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"8200_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"9000_BABE";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"9000_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"9100_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"9200_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"A000_BABE";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"A000_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"A100_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"A200_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"B000_BABE";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"B000_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"B100_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"B200_1234";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= X"0000_0CAF";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
wait until rising_edge(CLK_O);
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '0';
cmd_entry_write(0, "110000", X"0000_0", X"40DE_F", '0', '0', '1', '1');
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '1';
tlb_query_in.vaddr <= X"0000_0CAF";
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '0';
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '1';
tlb_query_in.write <= '1';
tlb_query_in.vaddr <= X"0008_0CAF";
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '0';
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '1';
tlb_query_in.write <= '1';
tlb_query_in.vaddr <= X"0000_0CAF";
wait until rising_edge(CLK_O);
tlb_query_in.vld <= '0';
wait;
end process;
END;
+152 -12
View File
@@ -25,6 +25,7 @@
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
USE std.textio.ALL;
library work;
use work.mips_types.all;
@@ -41,8 +42,10 @@ ARCHITECTURE behavior OF tb_mips_top IS
constant CLK_PERIOD : time := 10 ns;
constant SRAM_ADDR_WIDTH : integer := 17; -- bits
constant FLASH_ADDR_WIDTH : integer := 17; -- bits
signal debug : chip_debug_t;
constant WITH_TLB : boolean := true;
constant KSEG_01_TRANSLATED : boolean := true;
signal debug : chip_debug_t;
signal tb_fin : STD_LOGIC := '0';
-- Master
signal nmi : STD_LOGIC := '0';
@@ -115,7 +118,43 @@ ARCHITECTURE behavior OF tb_mips_top IS
type word_array_t is array (natural range <>) of unsigned(31 downto 0);
signal sram_data : word_array_t(0 to 2**SRAM_ADDR_WIDTH-1);
signal flash_data : word_array_t(0 to 2**FLASH_ADDR_WIDTH-1);
subtype nibble_t is unsigned (3 downto 0);
function to_character(x : nibble_t) return character is
type cnv_tbl_t is array (0 to 15) of character;
variable cnv_tbl : cnv_tbl_t := "0123456789ABCDEF";
variable result : character;
begin
for i in nibble_t'low to nibble_t'high loop
result := '0';
if x(i) /= '0' and x(i) /= '1' then
result := 'X';
end if;
end loop;
if result = '0' then
result := cnv_tbl(to_integer(x));
end if;
return result;
end to_character;
function to_string(x : word_t ) return string is
variable result : string (1 to 8);
variable j : integer := 32;
variable nibble : nibble_t;
begin
for i in 1 to 8 loop
nibble := x(j-1 downto j-4);
j := j - 4;
result(i) := to_character(nibble);
end loop;
return result;
end to_string;
BEGIN
------------------------------------------------------------------
@@ -128,6 +167,46 @@ CLK_GEN: process
------------------------------------------------------------------
-- Memory mux
------------------------------------------------------------------
-- rom_u : Virtual = 0xBFC00000, Physical = 0x1FC00000
-- rom_c : Virtual = 0x9FC00000, Physical = 0x1FC00000
-- ram_u : Virtual = 0xA0000000, Physical = 0x00000000
-- ram_c : Virtual = 0x80000000, Physical = 0x00000000
-- flash_u : Virtual = 0xA4000000, Physical = 0x04000000
-- flash_c : Virtual = 0x88000000, Physical = 0x08000000
-- io_u : Virtual = 0xA8000000, Physical = 0x0C000000
-- io_c : Virtual = 0x88000000, Physical = 0x0C000000
gen_mem_mux_translate:
if KSEG_01_TRANSLATED = true generate
mem_mux:
process(ADDR_O)
begin
mem_area <= mem_dead;
flash_page_mode_en <= '0';
if ADDR_O(31 downto 28) = X"0" then
if ADDR_O(27 downto 26) = "00" then
mem_area <= mem_sram;
elsif ADDR_O(27 downto 26) = "01" then
mem_area <= mem_flash;
elsif ADDR_O(27 downto 26) = "10" then
mem_area <= mem_flash;
flash_page_mode_en <= '1';
elsif ADDR_O(27 downto 26) = "11" then
if ADDR_O(18 downto 16) = "000" then
mem_area <= mem_gpio;
elsif ADDR_O(18 downto 16) = "001" then
mem_area <= mem_uart;
end if;
end if;
elsif (ADDR_O(31 downto 28) = X"1" and ADDR_O(15) = '0') then
mem_area <= mem_rom;
end if;
end process;
end generate;
gen_mem_mux_non_translate:
if KSEG_01_TRANSLATED = false generate
mem_mux:
process(ADDR_O)
begin
@@ -152,6 +231,7 @@ mem_mux:
mem_area <= mem_sram;
end if;
end process;
end generate;
signal_mux:
process(mem_area, CYC_O)
@@ -199,8 +279,9 @@ signal_mux:
uut: entity work.mips_top
GENERIC MAP
(
icache_size => 1024, -- words
dcache_size => 1024 -- words
icache_size => 256, -- words
dcache_size => 256, -- words
WITH_TLB => WITH_TLB
)
PORT MAP
(
@@ -394,14 +475,16 @@ SRAM_WRITE:
end if;
end if;
end process;
------------------------------------------------------------------
FLASH_READ:
process(rst, flash_cs_n, flash_oe_n, flash_a)
type file_t is file of integer;
-- file load_flash : file_t open read_mode is "ucb.elf.flash.bin";
file load_flash : file_t open read_mode is "test_timer.elf.flash.bin";
-- file load_flash : file_t open read_mode is "test_dcache.flash.bin";
file load_flash : file_t open read_mode is "test_tlb_sim.elf.flash.bin";
-- file load_flash : file_t open read_mode is "test_exception_sim.elf.flash.bin";
-- file load_flash : file_t open read_mode is "test_timer.elf.flash.bin";
-- file load_flash : file_t open read_mode is "test_dcache_sim.elf.flash.bin";
-- file load_flash : file_t open read_mode is "dhry.flash.bin";
variable instr : integer;
variable index : natural;
variable temp : signed(31 downto 0);
@@ -437,6 +520,62 @@ FLASH_READ:
end if;
end process;
------------------------------------------------------------------
icache_trace_write:
process(clk)
type file_t is file of string;
file f : file_t open write_mode is "icache_trace.dat";
variable file_opened : std_logic;
variable saddr : string(1 to 8);
variable sdata : string(1 to 8);
begin
if rising_edge(clk) then
if rst = '1' then
file_opened := '1';
elsif file_opened = '1' then
if debug.imem_din_vld = '1' then
saddr := to_string(debug.imem_addr_reg);
sdata := to_string(debug.imem_din_reg);
write(f, saddr & " : " & sdata & CR);
end if;
else
file_close(f);
file_opened := '0';
end if;
end if;
end process;
------------------------------------------------------------------
dcache_trace_write:
process(clk)
type file_t is file of string;
file f : file_t open write_mode is "dcache_trace.dat";
variable file_opened : std_logic;
variable saddr : string(1 to 8);
variable sdata : string(1 to 8);
begin
if rising_edge(clk) then
if rst = '1' then
file_opened := '1';
elsif file_opened = '1' then
if debug.dmem_din_vld = '1' then
saddr := to_string(debug.dmem_addr_reg);
sdata := to_string(debug.dmem_din_reg);
write(f, saddr & " : " & sdata & " R" & CR);
elsif debug.dmem_dout_vld = '1' then
saddr := to_string(debug.dmem_addr_reg);
sdata := to_string(debug.dmem_dout_reg);
write(f, saddr & " : " & sdata & " W" & CR);
end if;
else
file_close(f);
file_opened := '0';
end if;
end if;
end process;
------------------------------------------------------------------
STIMULUS: process
@@ -446,12 +585,13 @@ STIMULUS: process
wait for 3*CLK_PERIOD;
wait until rising_edge(clk);
rst <= '0';
wait for 778254*CLK_PERIOD;
wait for 1200000*CLK_PERIOD;
wait until rising_edge(clk);
nmi <= '0';
wait for 3000*CLK_PERIOD;
tb_fin <= '1';
wait until rising_edge(clk);
nmi <= '0';
tb_fin <= '0';
wait;