- removed cop0

- added interface for external cop0 and copz
- reworked cop_read and cop_write signals.
  Using only cop_read which is delay in pipeline


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@389 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2009-03-15 20:11:47 +00:00
parent b44d2ba1f9
commit ae421c7a15
+41 -63
View File
@@ -47,7 +47,15 @@ entity pipeline is
dmem_be : out unsigned(3 downto 0);
dmem_addr : out word_t;
dmem_din : in word_t;
dmem_dout : out word_t
dmem_dout : out word_t;
cop_ir : out word_t;
cop_ir_en : out STD_LOGIC;
cop_reg_rd : in STD_LOGIC;
cop_din : in word_t;
cop_dout : out word_t;
c0_ctrl_out : out cop0_ctrl_in_t;
c0_ctrl_in : in cop0_ctrl_out_t
);
end pipeline;
@@ -129,23 +137,6 @@ architecture Behavioral of pipeline is
);
END COMPONENT;
--------------------------------------------------------------------------
COMPONENT cop is
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;
din : in word_t;
dout : out word_t
);
END COMPONENT;
--------------------------------------------------------------------------
COMPONENT muldiv is
Port
@@ -179,10 +170,6 @@ architecture Behavioral of pipeline is
signal ctrl_lines : ctrl_lines_t;
signal branch_ce : STD_LOGIC;
signal cpu_run : STD_LOGIC;
signal cop_ctrl : cop_ctrl_in_t;
signal cop_stat : cop_ctrl_out_t;
signal cop_din : word_t;
signal cop_dout : word_t;
signal alu_result : word_t;
signal mul_result : word_t;
signal mul_busy : STD_LOGIC;
@@ -211,7 +198,7 @@ begin
cpu_run <= ce;
-- Stall Detection Unit ---------------------------------------------------
sdu.ID_nop <= sdu.imem_dep or cop_stat.exc_pending or EX_stage.exc or MEM_stage.exc;
sdu.ID_nop <= sdu.imem_dep or c0_ctrl_in.exc_pending or EX_stage.exc or MEM_stage.exc;
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.nop;
@@ -225,7 +212,20 @@ begin
sdu.imem_dep <= not imem_rdy;
sdu.dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
---------------------------------------------------------------------------
imem_en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or cop_stat.exc_commit);
imem_en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or c0_ctrl_in.exc_commit);
--------------------------------------------------------------------------
-- Coprocessor assignments
--------------------------------------------------------------------------
c0_ctrl_out.bd_wb <= WB_stage.bd;
c0_ctrl_out.epc_mem <= MEM_stage.pcn;
c0_ctrl_out.epc_wb <= MEM_stage.epc;
c0_ctrl_out.imem_addr <= pc.nxt;
c0_ctrl_out.dmem_addr <= MEM_stage.va;
c0_ctrl_out.sdu <= sdu;
c0_ctrl_out.events <= MEM_stage.events;
cop_ir <= ID_stage.IR;
cop_ir_en <= ID_stage.ctrl.cop_instr_en;
--------------------------------------------------------------------------
-- Muldiv
@@ -246,42 +246,18 @@ inst_muldiv: muldiv
dout => mul_result
);
--------------------------------------------------------------------------
-- Coprocessor
--------------------------------------------------------------------------
inst_cop: cop
PORT MAP
(
rst => rst,
clk => clk,
sdu => sdu,
events => MEM_stage.events,
IR_valid => ID_stage.ctrl.cop_instr_en,
IR => ID_stage.IR,
ctrl_in => cop_ctrl,
ctrl_out => cop_stat,
dout => cop_dout,
din => cop_din
);
cop_ctrl.bd_wb <= WB_stage.bd;
cop_ctrl.epc_mem <= MEM_stage.pcn;
cop_ctrl.epc_wb <= MEM_stage.epc;
cop_ctrl.imem_addr <= pc.nxt;
cop_ctrl.dmem_addr <= MEM_stage.va;
--------------------------------------------------------------------------
-- IF stage
--------------------------------------------------------------------------
imem_addr <= pc.curr;
proc_stage_pc:
process(pc, rst, cop_stat)
process(pc, rst, c0_ctrl_in)
begin
if rst = '1' then
pc.curr <= RESET_VECTOR after 2 ns;
else
if pc.is_branch and cop_stat.exc_pending = '0' then
if pc.is_branch and c0_ctrl_in.exc_pending = '0' then
pc.curr <= pc.pc_branch after 2 ns;
else
pc.curr <= pc.nxt after 2 ns;
@@ -303,17 +279,17 @@ proc_stage_pc_next:
process(clk_1)
begin
if rising_edge(clk_1) then
cop_ctrl.exc_left <= '0';
c0_ctrl_out.exc_left <= '0';
if rst = '1' then
pc.nxt <= pc.curr;
pc.last <= pc.curr;
branch_ce <= '1';
else
branch_ce <= '0';
if cop_stat.exc_commit = '1' then
pc.nxt <= cop_stat.exc_vec;
if c0_ctrl_in.exc_commit = '1' then
pc.nxt <= c0_ctrl_in.exc_vec;
elsif sdu.ID_stall = '0' then
cop_ctrl.exc_left <= cop_stat.exc_exit;
c0_ctrl_out.exc_left <= c0_ctrl_in.exc_exit;
branch_ce <= '1';
pc.last <= pc.curr;
if ID_stage.ctrl.jump = '1' then
@@ -370,17 +346,18 @@ proc_stage_branch:
ID_stage.reg_a_rptr <= extract_rs(ID_stage.IR);
ID_stage.reg_b_rptr <= extract_rt(ID_stage.IR);
ID_stage.ctrl <= ctrl_lines;
ID_stage.reg_write <= ID_stage.ctrl.reg_write or cop_stat.reg_write;
ID_stage.reg_write <= ID_stage.ctrl.reg_write;
ID_stage.cop_read <= cop_reg_rd;
ID_stage.epc <= pc.last;
ID_stage.exc <= event_is_active(ID_stage.events); -- Todo: works
ID_stage.nop <= sdu.ID_nop;
proc_ID_except:
process(ID_stage, cop_stat, pc)
process(ID_stage, c0_ctrl_in, pc)
begin
ID_stage.events <= events_clr;
ID_stage.events.inst_load_err <= pc.nxt(1) or pc.nxt(0);
ID_stage.events.inst_priv_addr <= pc.nxt(word_t'left) and cop_stat.user_mode;
ID_stage.events.inst_priv_addr <= pc.nxt(word_t'left) and c0_ctrl_in.user_mode;
end process;
proc_stage_hdu:
@@ -518,7 +495,8 @@ proc_stage_ID_EX_1:
EX_stage.events_in <= ID_stage.events;
EX_stage.op <= ID_stage.op;
EX_stage.ctrl <= ID_stage.ctrl;
EX_stage.reg_write <= ID_stage.reg_write;
EX_stage.reg_write <= ID_stage.reg_write or ID_stage.cop_read;
EX_stage.cop_read <= ID_stage.cop_read;
EX_stage.nop <= sdu.EX_nop;
EX_stage.IR <= ID_stage.IR;
EX_stage.pcn <= ID_stage.pcn;
@@ -594,7 +572,7 @@ proc_stage_DMEM_ADDR:
if rising_edge(clk_1) then
if sdu.EX_stall = '0' then
EX_stage.va <= vaddr;
if cop_stat.RE = '1' then
if c0_ctrl_in.RE = '1' then
EX_stage.pa_off <= not vaddr(1 downto 0);
else
EX_stage.pa_off <= vaddr(1 downto 0);
@@ -606,7 +584,7 @@ proc_stage_DMEM_ADDR:
dmem_we <= EX_stage.ctrl.dmem_we;
dmem_dout <= store_shift(EX_stage.reg_b, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp) after 1ns;
dmem_addr <= EX_stage.va;
cop_din <= EX_stage.reg_b;
cop_dout <= EX_stage.reg_b;
EX_stage.events <= EX_events_instr or EX_events_mem or EX_events_alu or EX_stage.events_in;
EX_stage.exc <= event_is_active(EX_stage.events);
@@ -779,8 +757,8 @@ proc_stage_MEM_n:
MEM_stage.ex_result <= EX_stage.reg_b;
else
MEM_stage.ex_result <= EX_stage.result;
if cop_stat.cop_read = '1' then
MEM_stage.ex_result <= cop_dout;
if EX_stage.cop_read = '1' then
MEM_stage.ex_result <= cop_din;
end if;
end if;
if sdu.MEM_nop = '1' then
@@ -833,7 +811,7 @@ proc_stage_MEM_except:
MEM_stage.events.Int <= int;
end process;
MEM_stage.exc <= cop_stat.int or event_is_active(MEM_stage.events_in);
MEM_stage.exc <= c0_ctrl_in.int or event_is_active(MEM_stage.events_in);
--------------------------------------------------------------------------
-- WB stage