From f5bf4fdb811a6b23517acafacc513b6f26162a62 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sat, 24 Aug 2013 10:31:18 +0000 Subject: [PATCH] - still try to add TLB 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@1019 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/CPUs/MIPS/src/core/icache.vhd | 4 +- lib/CPUs/MIPS/src/core/mips_bui.vhd | 23 +++--- lib/CPUs/MIPS/src/core/mips_pipeline.vhd | 91 +++++++++++++++++++++--- lib/CPUs/MIPS/src/core/mips_top.vhd | 49 +++++++------ lib/CPUs/MIPS/src/core/mips_types.vhd | 18 +++-- 5 files changed, 135 insertions(+), 50 deletions(-) diff --git a/lib/CPUs/MIPS/src/core/icache.vhd b/lib/CPUs/MIPS/src/core/icache.vhd index 2ae1326..7f75e06 100644 --- a/lib/CPUs/MIPS/src/core/icache.vhd +++ b/lib/CPUs/MIPS/src/core/icache.vhd @@ -463,14 +463,14 @@ cache_busy_state_fsm: else read_rdy <= '1'; if cache_req_rd = '1' then - if tlb_query_in.exc = '0' then +-- if tlb_query_in.exc = '0' then if tlb_query_in.flags.N = '1' or cache_hit = '0' then -- mem_fetch_req <= '1'; read_rdy <= '0'; single_read_set <= tlb_query_in.flags.N; cache_busy_state_next <= busy; end if; - end if; +-- end if; end if; end if; diff --git a/lib/CPUs/MIPS/src/core/mips_bui.vhd b/lib/CPUs/MIPS/src/core/mips_bui.vhd index d0af208..1bedee5 100644 --- a/lib/CPUs/MIPS/src/core/mips_bui.vhd +++ b/lib/CPUs/MIPS/src/core/mips_bui.vhd @@ -33,14 +33,15 @@ use work.busmaster_types.all; entity biu is Generic ( - ICACHE_SIZE : natural := 2048; -- words - ICACHE_LINE : natural := 8; -- words - DCACHE_SIZE : natural := 2048; -- words - DCACHE_LINE : natural := 8; -- words - WRITE_FIFO_SIZE : natural := 4; -- words - WITH_TLB : boolean := true; - ITLB_PIPE : boolean := false; - DTLB_PIPE : boolean := false + ICACHE_SIZE : natural := 2048; -- words + ICACHE_LINE : natural := 8; -- words + DCACHE_SIZE : natural := 2048; -- words + DCACHE_LINE : natural := 8; -- words + WRITE_FIFO_SIZE : natural := 4; -- words + WITH_TLB : boolean := true; + TRANSLATE_KSEG0_1 : boolean := true; + ITLB_PIPE : boolean := false; + DTLB_PIPE : boolean := false ); Port ( @@ -215,6 +216,7 @@ inst_i_tlb : entity work.tlb ( NUM_ENTRIES => TLB_NUM_ENTRIES, CACHE_KSEG1 => false, + TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1, USE_TLB => WITH_TLB, REGISTERED_OUTPUT => ITLB_PIPE ) @@ -279,8 +281,9 @@ inst_d_tlb : entity work.tlb GENERIC MAP ( NUM_ENTRIES => TLB_NUM_ENTRIES, - CACHE_KSEG1 => false, - USE_TLB => WITH_TLB, + CACHE_KSEG1 => false, + TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1, + USE_TLB => WITH_TLB, REGISTERED_OUTPUT => DTLB_PIPE ) PORT MAP diff --git a/lib/CPUs/MIPS/src/core/mips_pipeline.vhd b/lib/CPUs/MIPS/src/core/mips_pipeline.vhd index 6dc0c01..c1ec889 100644 --- a/lib/CPUs/MIPS/src/core/mips_pipeline.vhd +++ b/lib/CPUs/MIPS/src/core/mips_pipeline.vhd @@ -175,7 +175,6 @@ architecture Behavioral of pipeline is signal pc : pc_t; signal pc_alt : pc_t; - signal bcu_flags_alt : bcu_flags_t; -------------------------------------------------------------------------- begin @@ -185,7 +184,7 @@ begin cpu_run <= ce; -- Stall Detection Unit --------------------------------------------------- - sdu.ID_nop <= sdu.imem_dep or ctrl_in.exc_pending or ID_stage.exc or EX_stage.exc or MEM_stage.exc; + sdu.ID_nop <= sdu.imem_dep or ctrl_in.exc_pending or ID_stage.exc or EX_stage.exc or MEM_stage.exc; -- or pc_alt.branch_not_taken; sdu.EX_nop <= sdu.mul_dep or ID_stage.nop or ID_stage.exc; sdu.MEM_nop <= EX_stage.nop or EX_stage.exc; sdu.WB_nop <= sdu.dmem_dep or MEM_stage.exc or WB_stage.exc or ctrl_in.exc_pending; @@ -234,7 +233,7 @@ inst_muldiv: muldiv -------------------------------------------------------------------------- -- IF stage -------------------------------------------------------------------------- - imem_addr <= pc_alt.curr; + imem_addr <= pc.curr; pipe_rst <= stage_rst(0); @@ -406,8 +405,28 @@ proc_stage_branch_alt: end if; end process; +proc_stage_branch_not: + process(EX_stage) + begin + EX_stage.branch_not_taken <= '0'; + + case EX_stage.ctrl.bc_src is + + when bc_eq_ne => + EX_stage.branch_not_taken <= EX_stage.ctrl.branch and not(EX_stage.ctrl.bc_not xor EX_stage.bcu_flags.eq); + + when bc_lez_gtz => + EX_stage.branch_not_taken <= EX_stage.ctrl.branch and not(EX_stage.ctrl.bc_not xor (EX_stage.bcu_flags.eq or EX_stage.bcu_flags.ltz)); + + when bc_ltz_gez => + EX_stage.branch_not_taken <= EX_stage.ctrl.branch and not(EX_stage.ctrl.bc_not xor EX_stage.bcu_flags.ltz); + + when others => null; + end case; + end process; + proc_stage_pc_next_alt: - process(ctrl_in, sdu, ID_stage, pc_alt) + process(ctrl_in, sdu, pc_alt, ID_stage, EX_stage) begin pc_alt.nxt <= pc_alt.curr; if sdu.ID_stall = '0' then @@ -425,6 +444,28 @@ proc_stage_pc_next_alt: end if; end process; +-- always branch in ID and revert in EX +-- proc_stage_pc_next_alt: +-- process(ctrl_in, sdu, ID_stage, EX_stage, pc_alt) +-- begin +-- pc_alt.nxt <= pc_alt.curr; +-- if EX_stage.branch_not_taken = '1' then +-- pc_alt.nxt <= pc_alt.pc_branch_revert; +-- elsif sdu.ID_stall = '0' then +-- pc_alt.nxt <= ctrl_in.exc_vec; +-- if ctrl_in.exc_inject = '0' then +-- pc_alt.nxt <= pc_alt.plus4; +-- if ID_stage.ctrl.jump = '1' then +-- pc_alt.nxt <= ID_stage.jimm32; +-- elsif ID_stage.ctrl.jump_long = '1' then +-- pc_alt.nxt <= ID_stage.reg_a; +-- elsif D_stage.ctrl.branch = '1' then -- always take branch +-- pc_alt.nxt <= pc_alt.pc_branch; +-- end if; +-- end if; +-- end if; +-- end process; + proc_stage_pc_plus_4_alt: process(clk_2) begin @@ -433,19 +474,52 @@ proc_stage_pc_plus_4_alt: pc_alt.plus4 <= ctrl_in.exc_vec; elsif cpu_run = '1' then pc_alt.plus4 <= pc_alt.curr + 4; + end if; + end if; + end process; + +proc_stage_pc_branch_alt: + process(clk_2) + begin + if rising_edge(clk_2) then + if cpu_run = '1' then pc_alt.pc_branch <= pc_alt.curr + ID_stage.bimm18; end if; end if; end process; -proc_stage_pc_reg_alt: +proc_stage_pc_curr_alt: process(clk_1) begin if rising_edge(clk_1) then if rst = '1' then - pc_alt.curr <= ctrl_in.exc_vec; + pc_alt.curr <= ctrl_in.exc_vec; + pc_alt.last <= ctrl_in.exc_vec; elsif cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then - pc_alt.curr <= pc_alt.nxt; + pc_alt.last <= pc_alt.curr; + pc_alt.curr <= pc_alt.nxt; + end if; + end if; + end process; + +proc_stage_pc_revert_alt: + process(clk_1) + begin + if rising_edge(clk_1) then + if cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then + if ID_stage.ctrl.branch = '1' then + pc_alt.pc_branch_revert <= pc_alt.plus4; + end if; + end if; + end if; + end process; + +proc_stage_branch_not_taken_alt: + process(clk_1) + begin + if rising_edge(clk_1) then + if cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then + pc_alt.branch_not_taken <= EX_stage.branch_not_taken; end if; end if; end process; @@ -524,7 +598,7 @@ proc_stage_fwd_a: end process; proc_stage_fwd_b: - process(reg_b, hdu, EX_stage, MEM_stage, WB_stage, bcu_flags_alt) + process(reg_b, hdu, EX_stage, MEM_stage, WB_stage) variable data : word_t; begin data := reg_b; @@ -876,6 +950,7 @@ proc_stage_MEM_n: MEM_stage.events_in <= EX_stage.events; MEM_stage.reg_we <= EX_stage.reg_we; MEM_stage.ctrl <= EX_stage.ctrl; + MEM_stage.branch_not_taken <= EX_stage.branch_not_taken; if EX_stage.ctrl.dmem_en = '1' then MEM_stage.va <= EX_stage.va; end if; diff --git a/lib/CPUs/MIPS/src/core/mips_top.vhd b/lib/CPUs/MIPS/src/core/mips_top.vhd index 25bd9a1..a47a8ed 100644 --- a/lib/CPUs/MIPS/src/core/mips_top.vhd +++ b/lib/CPUs/MIPS/src/core/mips_top.vhd @@ -31,13 +31,14 @@ use work.mips_types.all; entity mips_top is Generic ( - icache_size : natural := 8192; -- words - icache_line : natural := 8; -- words - dcache_size : natural := 4096; -- words - dcache_line : natural := 8; -- words - WITH_TLB : boolean := true; - ITLB_PIPE : boolean := true; - DTLB_PIPE : boolean := true + icache_size : natural := 8192; -- words + icache_line : natural := 8; -- words + dcache_size : natural := 4096; -- words + dcache_line : natural := 8; -- words + WITH_TLB : boolean := false; + TRANSLATE_KSEG0_1 : boolean := false; + ITLB_PIPE : boolean := false; + DTLB_PIPE : boolean := false ); Port ( @@ -159,14 +160,15 @@ architecture rtl of mips_top is COMPONENT biu GENERIC ( - icache_size : natural; - icache_line : natural; - dcache_size : natural; - dcache_line : natural; - WRITE_FIFO_SIZE : natural; - WITH_TLB : boolean; - ITLB_PIPE : boolean; - DTLB_PIPE : boolean + icache_size : natural; + icache_line : natural; + dcache_size : natural; + dcache_line : natural; + WRITE_FIFO_SIZE : natural; + WITH_TLB : boolean; + TRANSLATE_KSEG0_1 : boolean; + ITLB_PIPE : boolean; + DTLB_PIPE : boolean ); PORT ( @@ -292,14 +294,15 @@ inst_cop: cop inst_biu: biu GENERIC MAP ( - icache_size => icache_size, -- words - icache_line => icache_line, -- words - dcache_size => dcache_size, -- words - dcache_line => dcache_line, -- words - WRITE_FIFO_SIZE => 4, - WITH_TLB => WITH_TLB, - ITLB_PIPE => ITLB_PIPE, - DTLB_PIPE => DTLB_PIPE + icache_size => icache_size, -- words + icache_line => icache_line, -- words + dcache_size => dcache_size, -- words + dcache_line => dcache_line, -- words + WRITE_FIFO_SIZE => 4, + WITH_TLB => WITH_TLB, + TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1, + ITLB_PIPE => ITLB_PIPE, + DTLB_PIPE => DTLB_PIPE ) PORT MAP ( diff --git a/lib/CPUs/MIPS/src/core/mips_types.vhd b/lib/CPUs/MIPS/src/core/mips_types.vhd index 3e096fd..7153a05 100644 --- a/lib/CPUs/MIPS/src/core/mips_types.vhd +++ b/lib/CPUs/MIPS/src/core/mips_types.vhd @@ -33,7 +33,7 @@ use work.mips_util_pkg.all; package mips_types is -- Revision of the CPU - constant REVISION : integer := 13; + constant REVISION : integer := 14; constant WORD_WIDTH : integer := 32; constant TLB_PAGE_SIZE : positive := 4096; constant TLB_NUM_ASIDS : positive := 64; @@ -173,12 +173,14 @@ package mips_types is type wptr_src_t is (wptr_src_imm, wptr_src_const); type pc_t is record - curr : word_t; - last : word_t; - nxt : word_t; - pc_branch : word_t; - branch_take : std_logic; - plus4 : word_t; + curr : word_t; + last : word_t; + nxt : word_t; + pc_branch : word_t; + pc_branch_revert : word_t; + branch_take : std_logic; + branch_not_taken : std_logic; + plus4 : word_t; end record; type alu_outsel_t is @@ -503,6 +505,7 @@ package mips_types is events_in : event_t; events : event_t; bcu_flags : bcu_flags_t; + branch_not_taken : std_logic; end record; type MEM_t is record @@ -523,6 +526,7 @@ package mips_types is events_in : event_t; events : event_t; bcu_flags : bcu_flags_t; + branch_not_taken : std_logic; end record; type WB_t is record