- 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
+47 -24
View File
@@ -34,7 +34,6 @@ entity pipeline is
rst : in STD_LOGIC; rst : in STD_LOGIC;
clk : in STD_LOGIC; clk : in STD_LOGIC;
ce : in STD_LOGIC; ce : in STD_LOGIC;
int : in unsigned(5 downto 0);
imem_err : in STD_LOGIC; imem_err : in STD_LOGIC;
imem_rdy : in STD_LOGIC; imem_rdy : in STD_LOGIC;
imem_en : out STD_LOGIC; imem_en : out STD_LOGIC;
@@ -171,6 +170,8 @@ architecture Behavioral of pipeline is
signal bcu_flags : bcu_flags_t; signal bcu_flags : bcu_flags_t;
signal vaddr : word_t; signal vaddr : word_t;
signal dmem_src : word_t; signal dmem_src : word_t;
signal stage_rst : unsigned(3 downto 0);
signal pipe_rst : STD_LOGIC;
attribute ram_style : string; attribute ram_style : string;
@@ -187,13 +188,13 @@ begin
cpu_run <= ce; cpu_run <= ce;
-- Stall Detection Unit --------------------------------------------------- -- 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.EX_nop <= sdu.mul_dep or ID_stage.nop or ID_stage.exc;
sdu.MEM_nop <= EX_stage.nop or EX_stage.exc; sdu.MEM_nop <= EX_stage.nop or EX_stage.exc;
sdu.WB_nop <= sdu.dmem_dep or MEM_stage.nop; sdu.WB_nop <= sdu.dmem_dep or MEM_stage.nop;
sdu.stall_all <= sdu.dmem_dep; 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.EX_stall <= sdu.stall_all;
sdu.MEM_stall <= sdu.stall_all; sdu.MEM_stall <= sdu.stall_all;
sdu.WB_stall <= '0'; sdu.WB_stall <= '0';
@@ -210,10 +211,12 @@ begin
c0_ctrl_out.bd_wb <= WB_stage.bd; c0_ctrl_out.bd_wb <= WB_stage.bd;
c0_ctrl_out.epc_mem <= MEM_stage.pcn; c0_ctrl_out.epc_mem <= MEM_stage.pcn;
c0_ctrl_out.epc_wb <= MEM_stage.epc; 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.dmem_addr <= MEM_stage.va;
c0_ctrl_out.sdu <= sdu; 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 <= ID_stage.IR;
cop_ir_en <= ID_stage.ctrl.cop_instr_en; cop_ir_en <= ID_stage.ctrl.cop_instr_en;
cop_dout <= MEM_stage.data; cop_dout <= MEM_stage.data;
@@ -242,10 +245,24 @@ inst_muldiv: muldiv
-------------------------------------------------------------------------- --------------------------------------------------------------------------
imem_addr <= pc.curr; 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: proc_stage_pc:
process(pc, c0_ctrl_in) process(pc, c0_ctrl_in)
begin 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; pc.curr <= pc.pc_branch after 2 ns;
else else
pc.curr <= pc.nxt after 2 ns; pc.curr <= pc.nxt after 2 ns;
@@ -266,17 +283,15 @@ proc_stage_pc_next:
process(clk_1) process(clk_1)
begin begin
if rising_edge(clk_1) then if rising_edge(clk_1) then
c0_ctrl_out.exc_left <= '0'; if pipe_rst = '1' then
if rst = '1' then
pc.nxt <= RESET_VECTOR; pc.nxt <= RESET_VECTOR;
pc.last <= RESET_VECTOR; pc.last <= RESET_VECTOR;
branch_ce <= '1'; branch_ce <= '1';
else else
branch_ce <= '0'; branch_ce <= c0_ctrl_in.exc_pending;
if c0_ctrl_in.exc_commit = '1' then if c0_ctrl_in.exc_inject = '1' then
pc.nxt <= c0_ctrl_in.exc_vec; pc.nxt <= c0_ctrl_in.exc_vec;
elsif sdu.ID_stall = '0' then elsif sdu.ID_stall = '0' then
c0_ctrl_out.exc_left <= c0_ctrl_in.exc_exit;
branch_ce <= '1'; branch_ce <= '1';
pc.last <= pc.curr; pc.last <= pc.curr;
if ID_stage.ctrl.jump = '1' then if ID_stage.ctrl.jump = '1' then
@@ -342,8 +357,8 @@ proc_ID_except:
process(ID_stage, c0_ctrl_in, pc) process(ID_stage, c0_ctrl_in, pc)
begin begin
ID_stage.events <= events_clr; ID_stage.events <= events_clr;
ID_stage.events.inst_load_err <= pc.nxt(1) or pc.nxt(0); 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 <= pc.nxt(word_t'left) and c0_ctrl_in.user_mode; 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; end process;
proc_stage_hdu: proc_stage_hdu:
@@ -459,7 +474,7 @@ proc_stage_ID_EX_1:
process(clk_1) process(clk_1)
begin begin
if rising_edge(clk_1) then if rising_edge(clk_1) then
if rst = '1' then if stage_rst(1) = '1' then
EX_stage.op <= NOP; EX_stage.op <= NOP;
EX_stage.IR <= (others => '0'); EX_stage.IR <= (others => '0');
EX_stage.ctrl <= ctrl_lines_default; EX_stage.ctrl <= ctrl_lines_default;
@@ -477,13 +492,12 @@ proc_stage_ID_EX_1:
EX_stage.nop <= sdu.EX_nop; EX_stage.nop <= sdu.EX_nop;
EX_stage.IR <= ID_stage.IR; EX_stage.IR <= ID_stage.IR;
EX_stage.pcn <= ID_stage.pcn; EX_stage.pcn <= ID_stage.pcn;
EX_stage.epc <= ID_stage.epc;
if sdu.EX_nop = '1' then if sdu.EX_nop = '1' then
EX_stage.op <= NOP; EX_stage.op <= NOP;
EX_stage.IR <= (others => '0'); EX_stage.IR <= (others => '0');
EX_stage.ctrl <= ctrl_lines_default; EX_stage.ctrl <= ctrl_lines_default;
EX_stage.reg_write <= '0'; EX_stage.reg_write <= '0';
else
EX_stage.epc <= ID_stage.epc;
end if; end if;
end if; end if;
end if; end if;
@@ -518,7 +532,7 @@ proc_stage_EX_mem_except:
process(clk_1) process(clk_1)
begin begin
if rising_edge(clk_1) then if rising_edge(clk_1) then
if rst = '1' then if pipe_rst = '1' then
dmem_en <= '0'; dmem_en <= '0';
elsif sdu.EX_stall = '0' then elsif sdu.EX_stall = '0' then
EX_events_mem <= events_clr; EX_events_mem <= events_clr;
@@ -715,7 +729,7 @@ proc_stage_MEM_n:
process(clk_1) process(clk_1)
begin begin
if rising_edge(clk_1) then if rising_edge(clk_1) then
if rst = '1' then if stage_rst(2) = '1' then
MEM_stage.op <= NOP; MEM_stage.op <= NOP;
MEM_stage.wreg_we <= '0'; MEM_stage.wreg_we <= '0';
MEM_stage.ctrl <= ctrl_lines_default; MEM_stage.ctrl <= ctrl_lines_default;
@@ -726,7 +740,9 @@ proc_stage_MEM_n:
MEM_stage.op <= EX_stage.op; MEM_stage.op <= EX_stage.op;
MEM_stage.wreg_we <= EX_stage.wreg_we; MEM_stage.wreg_we <= EX_stage.wreg_we;
MEM_stage.ctrl <= EX_stage.ctrl; MEM_stage.ctrl <= EX_stage.ctrl;
if EX_stage.ctrl.dmem_en = '1' then
MEM_stage.va <= EX_stage.va; MEM_stage.va <= EX_stage.va;
end if;
MEM_stage.pa_off <= EX_stage.pa_off; MEM_stage.pa_off <= EX_stage.pa_off;
MEM_stage.reg_wptr <= EX_stage.reg_wptr; MEM_stage.reg_wptr <= EX_stage.reg_wptr;
MEM_stage.nop <= sdu.MEM_nop; MEM_stage.nop <= sdu.MEM_nop;
@@ -760,7 +776,7 @@ proc_stage_MEM_mux:
data := MEM_stage.ex_result; data := MEM_stage.ex_result;
be := load_be(MEM_stage.pa_off, MEM_stage.ctrl.align_left, MEM_stage.ctrl.byte_en_byp); 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 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 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); 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); 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; end process;
proc_stage_MEM_except: proc_stage_MEM_except:
process(MEM_stage, int) process(MEM_stage, c0_ctrl_in)
begin begin
MEM_stage.events <= MEM_stage.events_in; MEM_stage.events <= MEM_stage.events_in;
MEM_stage.events.Int <= int; MEM_stage.events.Int <= c0_ctrl_in.int;
end process; 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 -- WB stage
@@ -797,22 +813,29 @@ proc_stage_WB_p:
process(clk_1) process(clk_1)
begin begin
if rising_edge(clk_1) then if rising_edge(clk_1) then
if rst = '1' then if stage_rst(3) = '1' then
WB_stage.op <= NOP; WB_stage.op <= NOP;
WB_stage.wreg_we <= '1'; WB_stage.wreg_we <= '1';
WB_stage.reg_wptr <= (others => '0'); WB_stage.reg_wptr <= (others => '0');
WB_stage.data <= (others => '0'); WB_stage.data <= (others => '0');
WB_stage.events <= events_clr;
elsif sdu.WB_stall = '0' then elsif sdu.WB_stall = '0' then
WB_stage.op <= MEM_stage.op; WB_stage.op <= MEM_stage.op;
WB_stage.wreg_we <= MEM_stage.wreg_we; WB_stage.wreg_we <= MEM_stage.wreg_we;
WB_stage.reg_wptr <= MEM_stage.reg_wptr; WB_stage.reg_wptr <= MEM_stage.reg_wptr;
WB_stage.data <= MEM_stage.data; 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; WB_stage.nop <= sdu.WB_nop;
if sdu.WB_nop = '1' then if sdu.WB_nop = '1' then
WB_stage.op <= NOP; WB_stage.op <= NOP;
WB_stage.wreg_we <= '0'; WB_stage.wreg_we <= '0';
else 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 WB_stage.bd <= MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
end if; end if;
end if; end if;