- 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
This commit is contained in:
2009-03-15 20:07:39 +00:00
parent 8282389078
commit cd8b53c3f3
+38 -31
View File
@@ -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;