- reworked exception stuff
- removed int-port (it's now in cop) 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@425 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -34,7 +34,6 @@ entity pipeline is
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
int : in unsigned(5 downto 0);
|
||||
imem_err : in STD_LOGIC;
|
||||
imem_rdy : in STD_LOGIC;
|
||||
imem_en : out STD_LOGIC;
|
||||
@@ -171,6 +170,8 @@ architecture Behavioral of pipeline is
|
||||
signal bcu_flags : bcu_flags_t;
|
||||
signal vaddr : word_t;
|
||||
signal dmem_src : word_t;
|
||||
signal stage_rst : unsigned(3 downto 0);
|
||||
signal pipe_rst : STD_LOGIC;
|
||||
|
||||
attribute ram_style : string;
|
||||
|
||||
@@ -187,13 +188,13 @@ begin
|
||||
cpu_run <= ce;
|
||||
|
||||
-- Stall Detection Unit ---------------------------------------------------
|
||||
sdu.ID_nop <= sdu.imem_dep or c0_ctrl_in.exc_pending or EX_stage.exc or MEM_stage.exc;
|
||||
sdu.ID_nop <= sdu.imem_dep or c0_ctrl_in.exc_pending or ID_stage.exc 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;
|
||||
|
||||
sdu.stall_all <= sdu.dmem_dep;
|
||||
sdu.ID_stall <= sdu.stall_all or sdu.imem_dep or sdu.mul_dep or ID_stage.exc;
|
||||
sdu.ID_stall <= sdu.stall_all or sdu.imem_dep or sdu.mul_dep or c0_ctrl_in.exc_exit;
|
||||
sdu.EX_stall <= sdu.stall_all;
|
||||
sdu.MEM_stall <= sdu.stall_all;
|
||||
sdu.WB_stall <= '0';
|
||||
@@ -210,10 +211,12 @@ begin
|
||||
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.imem_addr <= EX_stage.epc;
|
||||
c0_ctrl_out.dmem_addr <= MEM_stage.va;
|
||||
c0_ctrl_out.sdu <= sdu;
|
||||
c0_ctrl_out.events <= MEM_stage.events;
|
||||
c0_ctrl_out.events <= WB_stage.events;
|
||||
c0_ctrl_out.exc_req <= MEM_stage.exc;
|
||||
c0_ctrl_out.exc_ack <= WB_stage.exc;
|
||||
cop_ir <= ID_stage.IR;
|
||||
cop_ir_en <= ID_stage.ctrl.cop_instr_en;
|
||||
cop_dout <= MEM_stage.data;
|
||||
@@ -242,10 +245,24 @@ inst_muldiv: muldiv
|
||||
--------------------------------------------------------------------------
|
||||
imem_addr <= pc.curr;
|
||||
|
||||
pipe_rst <= stage_rst(0);
|
||||
|
||||
proc_stage_reset:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if rst = '1' then
|
||||
stage_rst <= (others => '1');
|
||||
else
|
||||
stage_rst <= stage_rst(stage_rst'left-1 downto 0) & '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_pc:
|
||||
process(pc, c0_ctrl_in)
|
||||
begin
|
||||
if pc.is_branch and c0_ctrl_in.exc_pending = '0' then
|
||||
if pc.is_branch then
|
||||
pc.curr <= pc.pc_branch after 2 ns;
|
||||
else
|
||||
pc.curr <= pc.nxt after 2 ns;
|
||||
@@ -266,17 +283,15 @@ proc_stage_pc_next:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
c0_ctrl_out.exc_left <= '0';
|
||||
if rst = '1' then
|
||||
if pipe_rst = '1' then
|
||||
pc.nxt <= RESET_VECTOR;
|
||||
pc.last <= RESET_VECTOR;
|
||||
branch_ce <= '1';
|
||||
else
|
||||
branch_ce <= '0';
|
||||
if c0_ctrl_in.exc_commit = '1' then
|
||||
branch_ce <= c0_ctrl_in.exc_pending;
|
||||
if c0_ctrl_in.exc_inject = '1' then
|
||||
pc.nxt <= c0_ctrl_in.exc_vec;
|
||||
elsif sdu.ID_stall = '0' then
|
||||
c0_ctrl_out.exc_left <= c0_ctrl_in.exc_exit;
|
||||
branch_ce <= '1';
|
||||
pc.last <= pc.curr;
|
||||
if ID_stage.ctrl.jump = '1' then
|
||||
@@ -342,8 +357,8 @@ proc_ID_except:
|
||||
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 c0_ctrl_in.user_mode;
|
||||
ID_stage.events.inst_load_err <= not c0_ctrl_in.exc_pending and (pc.nxt(1) or pc.nxt(0));
|
||||
ID_stage.events.inst_priv_addr <= not c0_ctrl_in.exc_pending and (pc.nxt(word_t'left) and c0_ctrl_in.user_mode);
|
||||
end process;
|
||||
|
||||
proc_stage_hdu:
|
||||
@@ -459,7 +474,7 @@ proc_stage_ID_EX_1:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if rst = '1' then
|
||||
if stage_rst(1) = '1' then
|
||||
EX_stage.op <= NOP;
|
||||
EX_stage.IR <= (others => '0');
|
||||
EX_stage.ctrl <= ctrl_lines_default;
|
||||
@@ -477,13 +492,12 @@ proc_stage_ID_EX_1:
|
||||
EX_stage.nop <= sdu.EX_nop;
|
||||
EX_stage.IR <= ID_stage.IR;
|
||||
EX_stage.pcn <= ID_stage.pcn;
|
||||
EX_stage.epc <= ID_stage.epc;
|
||||
if sdu.EX_nop = '1' then
|
||||
EX_stage.op <= NOP;
|
||||
EX_stage.IR <= (others => '0');
|
||||
EX_stage.ctrl <= ctrl_lines_default;
|
||||
EX_stage.reg_write <= '0';
|
||||
else
|
||||
EX_stage.epc <= ID_stage.epc;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@@ -518,7 +532,7 @@ proc_stage_EX_mem_except:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if rst = '1' then
|
||||
if pipe_rst = '1' then
|
||||
dmem_en <= '0';
|
||||
elsif sdu.EX_stall = '0' then
|
||||
EX_events_mem <= events_clr;
|
||||
@@ -715,7 +729,7 @@ proc_stage_MEM_n:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if rst = '1' then
|
||||
if stage_rst(2) = '1' then
|
||||
MEM_stage.op <= NOP;
|
||||
MEM_stage.wreg_we <= '0';
|
||||
MEM_stage.ctrl <= ctrl_lines_default;
|
||||
@@ -726,7 +740,9 @@ proc_stage_MEM_n:
|
||||
MEM_stage.op <= EX_stage.op;
|
||||
MEM_stage.wreg_we <= EX_stage.wreg_we;
|
||||
MEM_stage.ctrl <= EX_stage.ctrl;
|
||||
MEM_stage.va <= EX_stage.va;
|
||||
if EX_stage.ctrl.dmem_en = '1' then
|
||||
MEM_stage.va <= EX_stage.va;
|
||||
end if;
|
||||
MEM_stage.pa_off <= EX_stage.pa_off;
|
||||
MEM_stage.reg_wptr <= EX_stage.reg_wptr;
|
||||
MEM_stage.nop <= sdu.MEM_nop;
|
||||
@@ -760,7 +776,7 @@ proc_stage_MEM_mux:
|
||||
data := MEM_stage.ex_result;
|
||||
be := load_be(MEM_stage.pa_off, MEM_stage.ctrl.align_left, MEM_stage.ctrl.byte_en_byp);
|
||||
if MEM_stage.ctrl.reg_link = '1' then
|
||||
data := MEM_stage.pcn + 4;
|
||||
data := MEM_stage.epc + 8;
|
||||
elsif MEM_stage.ctrl.dmem_en = '1' then
|
||||
temp1 := load_shift(dmem_din, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp);
|
||||
temp2 := load_sign_ext(temp1, MEM_stage.ctrl.sign_ext_byp, MEM_stage.ctrl.load_signed, MEM_stage.ctrl.word2_en, MEM_stage.ctrl.word4_en);
|
||||
@@ -782,13 +798,13 @@ proc_stage_MEM_mux:
|
||||
end process;
|
||||
|
||||
proc_stage_MEM_except:
|
||||
process(MEM_stage, int)
|
||||
process(MEM_stage, c0_ctrl_in)
|
||||
begin
|
||||
MEM_stage.events <= MEM_stage.events_in;
|
||||
MEM_stage.events.Int <= int;
|
||||
MEM_stage.events.Int <= c0_ctrl_in.int;
|
||||
end process;
|
||||
|
||||
MEM_stage.exc <= c0_ctrl_in.int or event_is_active(MEM_stage.events_in);
|
||||
MEM_stage.exc <= event_is_active(MEM_stage.events);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- WB stage
|
||||
@@ -797,22 +813,29 @@ proc_stage_WB_p:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if rst = '1' then
|
||||
if stage_rst(3) = '1' then
|
||||
WB_stage.op <= NOP;
|
||||
WB_stage.wreg_we <= '1';
|
||||
WB_stage.reg_wptr <= (others => '0');
|
||||
WB_stage.data <= (others => '0');
|
||||
WB_stage.events <= events_clr;
|
||||
elsif sdu.WB_stall = '0' then
|
||||
WB_stage.op <= MEM_stage.op;
|
||||
WB_stage.wreg_we <= MEM_stage.wreg_we;
|
||||
WB_stage.reg_wptr <= MEM_stage.reg_wptr;
|
||||
WB_stage.data <= MEM_stage.data;
|
||||
WB_stage.exc <= '0';
|
||||
if sdu.stall_all = '0' then
|
||||
WB_stage.exc <= MEM_stage.exc;
|
||||
if MEM_stage.exc = '1' then
|
||||
WB_stage.events <= MEM_stage.events;
|
||||
end if;
|
||||
end if;
|
||||
WB_stage.nop <= sdu.WB_nop;
|
||||
if sdu.WB_nop = '1' then
|
||||
WB_stage.op <= NOP;
|
||||
WB_stage.wreg_we <= '0';
|
||||
else
|
||||
WB_stage.epc <= MEM_stage.epc;
|
||||
WB_stage.bd <= MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
||||
end if;
|
||||
end if;
|
||||
|
||||
Reference in New Issue
Block a user