- 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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user