From cd8b53c3f38e12a152795580b7f692d2c71c71ac Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sun, 15 Mar 2009 20:07:39 +0000 Subject: [PATCH] - added cache config to generic to create cache info in upper 16 bits PrID - unified control signals for later use with Copz - cleaned up 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/trunk@386 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/CPUs/MIPS/src/core/mips_cop.vhd | 69 ++++++++++++++++------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/lib/CPUs/MIPS/src/core/mips_cop.vhd b/lib/CPUs/MIPS/src/core/mips_cop.vhd index 434ab2c..c532865 100644 --- a/lib/CPUs/MIPS/src/core/mips_cop.vhd +++ b/lib/CPUs/MIPS/src/core/mips_cop.vhd @@ -29,16 +29,22 @@ use work.mips_types.all; use work.mips_instr.all; entity cop is + Generic + ( + icache_size : natural := 2048; -- words + icache_line : natural := 8; -- words + dcache_size : natural := 2048; -- words + dcache_line : natural := 8 -- words + ); Port ( rst : in STD_LOGIC; clk : in STD_LOGIC; - sdu : in sdu_t; - IR_valid : in STD_LOGIC; - IR : in word_t; - events : in event_t; - ctrl_in : in cop_ctrl_in_t; - ctrl_out : out cop_ctrl_out_t; + ir_en : in STD_LOGIC; + ir : in word_t; + ctrl_in : in cop0_ctrl_in_t; + ctrl_out : out cop0_ctrl_out_t; + reg_rd : out STD_LOGIC; din : in word_t; dout : out word_t ); @@ -68,7 +74,9 @@ architecture Behavioral of cop is signal eflags : exc_flags_t; signal exc_enable : STD_LOGIC; signal cop_EX_en : STD_LOGIC; - + signal icache_info : unsigned(7 downto 0); + signal dcache_info : unsigned(7 downto 0); + type cop_pipe_t is record din : word_t; rs : reg_ptr_t; @@ -99,41 +107,40 @@ architecture Behavioral of cop is -------------------------------------------------------------------------- begin + icache_info <= "00" & to_unsigned(lg2(icache_line), 3) & to_unsigned(lg2(icache_size)-8, 3); + dcache_info <= "00" & to_unsigned(lg2(dcache_line), 3) & to_unsigned(lg2(dcache_size)-8, 3); cop_pipe_ID.din <= din; - cop_pipe_ID.cs <= IR_valid; - cop_pipe_ID.rs <= extract_rs(IR); - cop_pipe_ID.rd <= extract_rd(IR); - cop_pipe_ID.func <= extract_func(IR); + cop_pipe_ID.cs <= ir_en; + cop_pipe_ID.rs <= extract_rs(ir); + cop_pipe_ID.rd <= extract_rd(ir); + cop_pipe_ID.func <= extract_func(ir); cop_pipe_ID.re <= cop_pipe_ID.cs when cop_pipe_ID.rs = "00000" else '0'; cop_pipe_ID.we <= cop_pipe_ID.cs when cop_pipe_ID.rs = "00100" else '0'; cop_EX_en <= exc_enable and not status_save; - ctrl_out.ee <= exc_enable; - ctrl_out.ec <= status_save; ctrl_out.RE <= status(25); ctrl_out.user_mode <= status(1); ctrl_out.int <= eflags.Int; - ctrl_out.cop_read <= cop_pipe_EX.cs and cop_pipe_EX.re after 1 ns; - ctrl_out.reg_write <= cop_pipe_ID.re after 1 ns; + reg_rd <= cop_pipe_ID.cs and cop_pipe_ID.re after 1 ns; im <= status(15 downto 8); cause <= bd & (30 downto 16 => '0') & ip & '0' & exc_code & "00"; - eflags.Ov <= events.alu_ovf or events.alu_uvf; - eflags.DAdEL <= events.data_load_err; - eflags.DAdES <= events.data_store_err; - eflags.IAdEL <= events.inst_load_err; - eflags.IAdEK <= events.inst_priv_addr and status(1); - eflags.Sys <= events.syscall; - eflags.Bp <= events.break; - eflags.RI <= events.illegal; + eflags.Ov <= ctrl_in.events.alu_ovf or ctrl_in.events.alu_uvf; + eflags.DAdEL <= ctrl_in.events.data_load_err; + eflags.DAdES <= ctrl_in.events.data_store_err; + eflags.IAdEL <= ctrl_in.events.inst_load_err; + eflags.IAdEK <= ctrl_in.events.inst_priv_addr and status(1); + eflags.Sys <= ctrl_in.events.syscall; + eflags.Bp <= ctrl_in.events.break; + eflags.RI <= ctrl_in.events.illegal; eflags.Int <= eval_int(ip) and status(0); exception <= eflags.Ov or eflags.Sys or eflags.Bp or eflags.RI or eflags.IAdEL or eflags.IAdEK or eflags.DAdEL or eflags.DAdES or eflags.Int after 1 ns; exception_state: - process(exc_state, ctrl_in, exception, sdu) + process(exc_state, ctrl_in, exception) begin exc_enable <= '0'; @@ -163,20 +170,20 @@ exception_state: when exc_commit_ID => ctrl_out.exc_pending <= '1'; ctrl_out.exc_commit <= '1'; - if sdu.ID_stall = '0' then + if ctrl_in.sdu.ID_stall = '0' then exc_staten <= exc_commit_EX; end if; when exc_commit_EX => ctrl_out.exc_pending <= '1'; ctrl_out.exc_commit <= '1'; - if sdu.EX_stall = '0' then + if ctrl_in.sdu.EX_stall = '0' then exc_staten <= exc_commit_MEM; end if; when exc_commit_MEM => ctrl_out.exc_pending <= '1'; - if sdu.MEM_stall = '0' then + if ctrl_in.sdu.MEM_stall = '0' then epc_reg_we <= '1'; exc_staten <= exc_idle; end if; @@ -282,7 +289,7 @@ cop_ip_reg_write: elsif ip_reg_we = '1' then ip(1 downto 0) <= cop_pipe_EX.din(9 downto 8) and im(1 downto 0); end if; - ip(7 downto 2) <= events.Int and im(7 downto 2); + ip(7 downto 2) <= ctrl_in.events.Int and im(7 downto 2); end if; end process; @@ -306,7 +313,7 @@ cop_pipe: cop_pipe_EX.we <= '0'; cop_pipe_EX.re <= '0'; else - if sdu.EX_stall = '0' then + if ctrl_in.sdu.EX_stall = '0' then cop_pipe_EX <= cop_pipe_ID; end if; end if; @@ -317,7 +324,7 @@ cop_register_read: process(clk) variable reg : word_t; begin - if rising_edge(clk) and cop_pipe_ID.re = '1' and sdu.ID_stall = '0' then + if rising_edge(clk) and cop_pipe_ID.re = '1' and ctrl_in.sdu.ID_stall = '0' then case cop_pipe_ID.rd is when "01000" => -- BadVAddr reg := BadVAddr; @@ -332,7 +339,7 @@ cop_register_read: reg := epc; when "01111" => -- PRId (Processor Revision Register) - reg := X"000002" & to_unsigned(REVISION ,8); + reg := dcache_info & icache_info & X"02" & to_unsigned(REVISION ,8); when "11111" => -- test_reg reg := test_reg;