- 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:
@@ -29,16 +29,22 @@ use work.mips_types.all;
|
|||||||
use work.mips_instr.all;
|
use work.mips_instr.all;
|
||||||
|
|
||||||
entity cop is
|
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
|
Port
|
||||||
(
|
(
|
||||||
rst : in STD_LOGIC;
|
rst : in STD_LOGIC;
|
||||||
clk : in STD_LOGIC;
|
clk : in STD_LOGIC;
|
||||||
sdu : in sdu_t;
|
ir_en : in STD_LOGIC;
|
||||||
IR_valid : in STD_LOGIC;
|
ir : in word_t;
|
||||||
IR : in word_t;
|
ctrl_in : in cop0_ctrl_in_t;
|
||||||
events : in event_t;
|
ctrl_out : out cop0_ctrl_out_t;
|
||||||
ctrl_in : in cop_ctrl_in_t;
|
reg_rd : out STD_LOGIC;
|
||||||
ctrl_out : out cop_ctrl_out_t;
|
|
||||||
din : in word_t;
|
din : in word_t;
|
||||||
dout : out word_t
|
dout : out word_t
|
||||||
);
|
);
|
||||||
@@ -68,6 +74,8 @@ architecture Behavioral of cop is
|
|||||||
signal eflags : exc_flags_t;
|
signal eflags : exc_flags_t;
|
||||||
signal exc_enable : STD_LOGIC;
|
signal exc_enable : STD_LOGIC;
|
||||||
signal cop_EX_en : 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
|
type cop_pipe_t is record
|
||||||
din : word_t;
|
din : word_t;
|
||||||
@@ -99,41 +107,40 @@ architecture Behavioral of cop is
|
|||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
begin
|
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.din <= din;
|
||||||
cop_pipe_ID.cs <= IR_valid;
|
cop_pipe_ID.cs <= ir_en;
|
||||||
cop_pipe_ID.rs <= extract_rs(IR);
|
cop_pipe_ID.rs <= extract_rs(ir);
|
||||||
cop_pipe_ID.rd <= extract_rd(IR);
|
cop_pipe_ID.rd <= extract_rd(ir);
|
||||||
cop_pipe_ID.func <= extract_func(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.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_pipe_ID.we <= cop_pipe_ID.cs when cop_pipe_ID.rs = "00100" else '0';
|
||||||
cop_EX_en <= exc_enable and not status_save;
|
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.RE <= status(25);
|
||||||
ctrl_out.user_mode <= status(1);
|
ctrl_out.user_mode <= status(1);
|
||||||
ctrl_out.int <= eflags.Int;
|
ctrl_out.int <= eflags.Int;
|
||||||
|
|
||||||
ctrl_out.cop_read <= cop_pipe_EX.cs and cop_pipe_EX.re after 1 ns;
|
reg_rd <= cop_pipe_ID.cs and cop_pipe_ID.re after 1 ns;
|
||||||
ctrl_out.reg_write <= cop_pipe_ID.re after 1 ns;
|
|
||||||
|
|
||||||
im <= status(15 downto 8);
|
im <= status(15 downto 8);
|
||||||
cause <= bd & (30 downto 16 => '0') & ip & '0' & exc_code & "00";
|
cause <= bd & (30 downto 16 => '0') & ip & '0' & exc_code & "00";
|
||||||
|
|
||||||
eflags.Ov <= events.alu_ovf or events.alu_uvf;
|
eflags.Ov <= ctrl_in.events.alu_ovf or ctrl_in.events.alu_uvf;
|
||||||
eflags.DAdEL <= events.data_load_err;
|
eflags.DAdEL <= ctrl_in.events.data_load_err;
|
||||||
eflags.DAdES <= events.data_store_err;
|
eflags.DAdES <= ctrl_in.events.data_store_err;
|
||||||
eflags.IAdEL <= events.inst_load_err;
|
eflags.IAdEL <= ctrl_in.events.inst_load_err;
|
||||||
eflags.IAdEK <= events.inst_priv_addr and status(1);
|
eflags.IAdEK <= ctrl_in.events.inst_priv_addr and status(1);
|
||||||
eflags.Sys <= events.syscall;
|
eflags.Sys <= ctrl_in.events.syscall;
|
||||||
eflags.Bp <= events.break;
|
eflags.Bp <= ctrl_in.events.break;
|
||||||
eflags.RI <= events.illegal;
|
eflags.RI <= ctrl_in.events.illegal;
|
||||||
eflags.Int <= eval_int(ip) and status(0);
|
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 <= 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:
|
exception_state:
|
||||||
process(exc_state, ctrl_in, exception, sdu)
|
process(exc_state, ctrl_in, exception)
|
||||||
begin
|
begin
|
||||||
|
|
||||||
exc_enable <= '0';
|
exc_enable <= '0';
|
||||||
@@ -163,20 +170,20 @@ exception_state:
|
|||||||
when exc_commit_ID =>
|
when exc_commit_ID =>
|
||||||
ctrl_out.exc_pending <= '1';
|
ctrl_out.exc_pending <= '1';
|
||||||
ctrl_out.exc_commit <= '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;
|
exc_staten <= exc_commit_EX;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
when exc_commit_EX =>
|
when exc_commit_EX =>
|
||||||
ctrl_out.exc_pending <= '1';
|
ctrl_out.exc_pending <= '1';
|
||||||
ctrl_out.exc_commit <= '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;
|
exc_staten <= exc_commit_MEM;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
when exc_commit_MEM =>
|
when exc_commit_MEM =>
|
||||||
ctrl_out.exc_pending <= '1';
|
ctrl_out.exc_pending <= '1';
|
||||||
if sdu.MEM_stall = '0' then
|
if ctrl_in.sdu.MEM_stall = '0' then
|
||||||
epc_reg_we <= '1';
|
epc_reg_we <= '1';
|
||||||
exc_staten <= exc_idle;
|
exc_staten <= exc_idle;
|
||||||
end if;
|
end if;
|
||||||
@@ -282,7 +289,7 @@ cop_ip_reg_write:
|
|||||||
elsif ip_reg_we = '1' then
|
elsif ip_reg_we = '1' then
|
||||||
ip(1 downto 0) <= cop_pipe_EX.din(9 downto 8) and im(1 downto 0);
|
ip(1 downto 0) <= cop_pipe_EX.din(9 downto 8) and im(1 downto 0);
|
||||||
end if;
|
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 if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
@@ -306,7 +313,7 @@ cop_pipe:
|
|||||||
cop_pipe_EX.we <= '0';
|
cop_pipe_EX.we <= '0';
|
||||||
cop_pipe_EX.re <= '0';
|
cop_pipe_EX.re <= '0';
|
||||||
else
|
else
|
||||||
if sdu.EX_stall = '0' then
|
if ctrl_in.sdu.EX_stall = '0' then
|
||||||
cop_pipe_EX <= cop_pipe_ID;
|
cop_pipe_EX <= cop_pipe_ID;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
@@ -317,7 +324,7 @@ cop_register_read:
|
|||||||
process(clk)
|
process(clk)
|
||||||
variable reg : word_t;
|
variable reg : word_t;
|
||||||
begin
|
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
|
case cop_pipe_ID.rd is
|
||||||
when "01000" => -- BadVAddr
|
when "01000" => -- BadVAddr
|
||||||
reg := BadVAddr;
|
reg := BadVAddr;
|
||||||
@@ -332,7 +339,7 @@ cop_register_read:
|
|||||||
reg := epc;
|
reg := epc;
|
||||||
|
|
||||||
when "01111" => -- PRId (Processor Revision Register)
|
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
|
when "11111" => -- test_reg
|
||||||
reg := test_reg;
|
reg := test_reg;
|
||||||
|
|||||||
Reference in New Issue
Block a user