- 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;
|
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;
|
||||||
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.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;
|
||||||
|
|||||||
Reference in New Issue
Block a user