- added instructions 'lwc0' and 'swc0' for testing (which are usually invalid)
- due to cop_reg_we in MEM_Stage, the output register is removed (timing is slightly degraded). The reg pointer is delayed instead by one cycle - test-reg is now writable in user mode regardles of cop0 usability. 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@406 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -77,8 +77,11 @@ architecture Behavioral of cop is
|
||||
signal dcache_info : unsigned(7 downto 0);
|
||||
|
||||
type cop_pipe_t is record
|
||||
opc : opcode_t;
|
||||
reg_ptr : reg_ptr_t;
|
||||
rs : reg_ptr_t;
|
||||
rd : reg_ptr_t;
|
||||
rt : reg_ptr_t;
|
||||
func : func_t;
|
||||
we : std_logic;
|
||||
re : std_logic;
|
||||
@@ -108,17 +111,21 @@ 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.cs <= ir_en;
|
||||
cop_pipe_ID.opc <= extract_opc(ir);
|
||||
cop_pipe_ID.rs <= extract_rs(ir);
|
||||
cop_pipe_ID.rd <= extract_rd(ir);
|
||||
cop_pipe_ID.rt <= extract_rt(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_pipe_ID.re <= cop_pipe_ID.cs when (cop_pipe_ID.opc = "111000" or cop_pipe_ID.rs = "00000") else '0';
|
||||
cop_pipe_ID.we <= cop_pipe_ID.cs when (cop_pipe_ID.opc = "110000" or cop_pipe_ID.rs = "00100") else '0';
|
||||
cop_EX_en <= exc_enable and not status_save;
|
||||
|
||||
ctrl_out.RE <= status(25);
|
||||
ctrl_out.user_mode <= status(1);
|
||||
ctrl_out.int <= eflags.Int;
|
||||
|
||||
|
||||
cop_pipe_ID.reg_ptr <= cop_pipe_ID.rd when cop_pipe_ID.opc = "010000" else cop_pipe_ID.rt;
|
||||
|
||||
im <= status(15 downto 8);
|
||||
cause <= bd & (30 downto 16 => '0') & ip & '0' & exc_code & "00";
|
||||
|
||||
@@ -307,44 +314,40 @@ cop_pipe:
|
||||
cop_pipe_EX.cs <= '0';
|
||||
cop_pipe_EX.we <= '0';
|
||||
cop_pipe_EX.re <= '0';
|
||||
else
|
||||
if ctrl_in.sdu.stall_all = '0' then
|
||||
cop_pipe_EX <= cop_pipe_ID;
|
||||
end if;
|
||||
elsif ctrl_in.sdu.stall_all = '0' then
|
||||
cop_pipe_EX <= cop_pipe_ID;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cop_register_read:
|
||||
process(clk)
|
||||
process(cop_pipe_EX, BadVAddr, status, cause, epc, dcache_info, icache_info, test_reg)
|
||||
variable reg : word_t;
|
||||
begin
|
||||
if rising_edge(clk) and cop_pipe_ID.re = '1' and ctrl_in.sdu.stall_all = '0' then
|
||||
case cop_pipe_ID.rd is
|
||||
when "01000" => -- BadVAddr
|
||||
reg := BadVAddr;
|
||||
case cop_pipe_EX.reg_ptr is
|
||||
when "01000" => -- BadVAddr
|
||||
reg := BadVAddr;
|
||||
|
||||
when "01100" => -- Status
|
||||
reg := status;
|
||||
when "01100" => -- Status
|
||||
reg := status;
|
||||
|
||||
when "01101" => -- Cause
|
||||
reg := cause;
|
||||
when "01101" => -- Cause
|
||||
reg := cause;
|
||||
|
||||
when "01110" => -- EPC (Exception Program Counter)
|
||||
reg := epc;
|
||||
when "01110" => -- EPC (Exception Program Counter)
|
||||
reg := epc;
|
||||
|
||||
when "01111" => -- PRId (Processor Revision Register)
|
||||
reg := dcache_info & icache_info & X"02" & to_unsigned(REVISION ,8);
|
||||
when "01111" => -- PRId (Processor Revision Register)
|
||||
reg := dcache_info & icache_info & X"02" & to_unsigned(REVISION ,8);
|
||||
|
||||
when "11111" => -- test_reg
|
||||
reg := test_reg;
|
||||
when "11111" => -- test_reg
|
||||
reg := test_reg;
|
||||
|
||||
when others =>
|
||||
reg := (others => '-');
|
||||
when others =>
|
||||
reg := (others => '-');
|
||||
|
||||
end case;
|
||||
dout <= reg after 1 ns;
|
||||
end if;
|
||||
end case;
|
||||
dout <= reg after 2 ns;
|
||||
end process;
|
||||
|
||||
cop_we_gen:
|
||||
@@ -355,20 +358,20 @@ cop_we_gen:
|
||||
test_reg_we <= '0';
|
||||
stat_reg_we <= '0';
|
||||
ip_reg_we <= '0';
|
||||
else
|
||||
elsif ctrl_in.sdu.stall_all = '0' then
|
||||
test_reg_we <= '0';
|
||||
stat_reg_we <= '0';
|
||||
ip_reg_we <= '0';
|
||||
if (cop_EX_en and cop_pipe_EX.we) = '1' then
|
||||
|
||||
case cop_pipe_EX.rd is
|
||||
case cop_pipe_EX.reg_ptr is
|
||||
|
||||
when "01100" =>
|
||||
stat_reg_we <= not status(1) or status(28);
|
||||
when "01101" =>
|
||||
ip_reg_we <= not status(1) or status(28);
|
||||
when "11111" =>
|
||||
test_reg_we <= not status(1) or status(28);
|
||||
test_reg_we <= '1'; -- not status(1) or status(28);
|
||||
when others => null;
|
||||
|
||||
end case;
|
||||
@@ -384,7 +387,7 @@ cop_test_reg_write:
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
test_reg <= (others => '0');
|
||||
else --if ce = '1' then
|
||||
elsif ctrl_in.sdu.WB_nop = '0' then
|
||||
if test_reg_we = '1' then
|
||||
test_reg <= din;
|
||||
end if;
|
||||
@@ -406,9 +409,11 @@ cop_status_reg_write:
|
||||
elsif status_rest = '1' then
|
||||
status(1 downto 0) <= status(3 downto 2);
|
||||
status(3 downto 2) <= status(5 downto 4);
|
||||
elsif stat_reg_we = '1' then
|
||||
status <= din;
|
||||
end if;
|
||||
elsif ctrl_in.sdu.WB_nop = '0' then
|
||||
if stat_reg_we = '1' then
|
||||
status <= din;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
Reference in New Issue
Block a user