- 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:
2009-04-11 08:30:41 +00:00
parent a94fb20d4f
commit ae50048039
+48 -25
View File
@@ -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;