123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- library ieee;
- use ieee.std_logic_1164.all;
- use work.core_pkg.all;
- use work.mem_pkg.all;
- use work.op_pkg.all;
- entity pipeline is
- port (
- clk : in std_logic;
- res_n : in std_logic;
- -- instruction interface
- mem_i_out : out mem_out_type;
- mem_i_in : in mem_in_type;
- -- data interface
- mem_d_out : out mem_out_type;
- mem_d_in : in mem_in_type
- );
- end entity;
- architecture impl of pipeline is
- type pipeline_ctrl_t is record
- stall : std_logic;
- flush : std_logic;
- stall_fetch : std_logic;
- stall_dec : std_logic;
- stall_exec : std_logic;
- stall_mem : std_logic;
- stall_wb : std_logic;
- flush_fetch : std_logic;
- flush_dec : std_logic;
- flush_exec : std_logic;
- flush_mem : std_logic;
- flush_wb : std_logic;
- end record;
- signal ctrl : pipeline_ctrl_t;
- type fetch_t is record
- -- to control
- mem_busy : std_logic;
- pcsrc : std_logic;
- pc_in : pc_type;
- pc_out : pc_type;
- instr : instr_type;
- end record;
- signal fetch : fetch_t;
- type decode_t is record
- -- from fetch
- pc_in : pc_type;
- instr : instr_type;
- -- from writeback
- reg_write : reg_write_type;
- -- towards next stages
- pc_out : pc_type;
- exec_op : exec_op_type;
- mem_op : mem_op_type;
- wb_op : wb_op_type;
- -- exceptions
- exc_dec : std_logic;
- end record;
- signal decode : decode_t;
- type exec_t is record
- -- from DEC
- op : exec_op_type;
- pc_in : pc_type;
- -- to MEM
- pc_old_out : pc_type;
- pc_new_out : pc_type;
- aluresult : data_type;
- wrdata : data_type;
- zero : std_logic;
- memop_in : mem_op_type;
- memop_out : mem_op_type;
- wbop_in : wb_op_type;
- wbop_out : wb_op_type;
- -- FWD
- exec_op : exec_op_type;
- reg_write_mem : reg_write_type;
- reg_write_wr : reg_write_type;
- end record;
- signal exec : exec_t;
- type mem_t is record
- -- to Ctrl
- mem_busy : std_logic;
- -- from EXEC
- mem_op : mem_op_type;
- wbop_in : wb_op_type;
- pc_new_in : pc_type;
- pc_old_in : pc_type;
- aluresult_in : data_type;
- wrdata : data_type;
- zero : std_logic;
- -- to EXEC (forwarding)
- reg_write : reg_write_type;
- -- to FETCH
- pc_new_out : pc_type;
- pcsrc : std_logic;
- -- to WB
- wbop_out : wb_op_type;
- pc_old_out : pc_type;
- aluresult_out : data_type;
- memresult : data_type;
- -- exceptions
- exc_load : std_logic;
- exc_store : std_logic;
- end record;
- signal mem : mem_t;
- type wb_t is record
- -- from MEM
- op : wb_op_type;
- aluresult : data_type;
- memresult : data_type;
- pc_old_in : pc_type;
- -- to FWD and DEC
- reg_write : reg_write_type;
- end record;
- signal wb : wb_t;
-
- signal cntrl_res_n, cntrl_res_n_next : std_logic := '0';
- begin
- -- synchronous
- res_cntrl : process(clk, res_n)
- begin
- if res_n = '0' then
- cntrl_res_n_next <= '0';
- else
- cntrl_res_n_next <= '1';
- end if;
- if rising_edge(clk) then
- cntrl_res_n <= cntrl_res_n_next;
- end if;
- end process;
- -- concurrent
- ctrl.stall <= fetch.mem_busy or mem.mem_busy or not cntrl_res_n;
- ctrl.flush <= '0';
- -- structural
- -- STAGE 1
- fetch_inst : entity work.fetch
- port map (
- clk => clk,
- res_n => res_n,
- stall => ctrl.stall or ctrl.stall_fetch,
- flush => ctrl.flush or ctrl.flush_fetch,
- -- to control
- mem_busy => fetch.mem_busy,
- pcsrc => fetch.pcsrc,
- pc_in => fetch.pc_in,
- pc_out => fetch.pc_out,
- instr => fetch.instr,
- -- memory controller interface
- mem_out => mem_i_out,
- mem_in => mem_i_in
- );
-
- fetch.pcsrc <= mem.pcsrc;
- fetch.pc_in <= mem.pc_new_out;
- -- STAGE 2
- decode_inst : entity work.decode
- port map (
- clk => clk,
- res_n => res_n,
- stall => ctrl.stall or ctrl.stall_dec,
- flush => ctrl.flush or ctrl.flush_dec,
- -- from fetch
- pc_in => decode.pc_in,
- instr => decode.instr,
- -- from writeback
- reg_write => decode.reg_write,
- -- towards next stages
- pc_out => decode.pc_out,
- exec_op => decode.exec_op,
- mem_op => decode.mem_op,
- wb_op => decode.wb_op,
- -- exceptions
- exc_dec => decode.exc_dec
- );
- decode.pc_in <= fetch.pc_out;
- decode.instr <= fetch.instr;
- decode.reg_write <= wb.reg_write;
- -- STAGE 3
- execute_inst : entity work.exec
- port map (
- clk => clk,
- res_n => res_n,
- stall => ctrl.stall or ctrl.stall_exec,
- flush => ctrl.flush or ctrl.flush_exec,
- -- from DEC
- op => exec.op,
- pc_in => exec.pc_in,
- -- to MEM
- pc_old_out => exec.pc_old_out,
- pc_new_out => exec.pc_new_out,
- aluresult => exec.aluresult,
- wrdata => exec.wrdata,
- zero => exec.zero,
- memop_in => exec.memop_in,
- memop_out => exec.memop_out,
- wbop_in => exec.wbop_in,
- wbop_out => exec.wbop_out,
- -- FWD
- exec_op => exec.exec_op,
- reg_write_mem => exec.reg_write_mem,
- reg_write_wr => exec.reg_write_wr
- );
- exec.pc_in <= decode.pc_out;
- exec.op <= decode.exec_op;
- exec.memop_in <= decode.mem_op;
- exec.wbop_in <= decode.wb_op;
- exec.reg_write_mem <= mem.reg_write;
- exec.reg_write_wr <= wb.reg_write;
- -- STAGE 4
- memory_inst : entity work.mem
- port map (
- clk => clk,
- res_n => res_n,
- stall => ctrl.stall or ctrl.stall_mem,
- flush => ctrl.flush or ctrl.flush_mem,
- -- to Ctrl
- mem_busy => mem.mem_busy,
- -- from EXEC
- mem_op => mem.mem_op,
- wbop_in => mem.wbop_in,
- pc_new_in => mem.pc_new_in,
- pc_old_in => mem.pc_old_in,
- aluresult_in => mem.aluresult_in,
- wrdata => mem.wrdata,
- zero => mem.zero,
- -- to EXEC (forwarding)
- reg_write => mem.reg_write,
- -- to FETCH
- pc_new_out => mem.pc_new_out,
- pcsrc => mem.pcsrc,
- -- to WB
- wbop_out => mem.wbop_out,
- pc_old_out => mem.pc_old_out,
- aluresult_out => mem.aluresult_out,
- memresult => mem.memresult,
- -- memory controller interface
- mem_out => mem_d_out,
- mem_in => mem_d_in,
- -- exceptions
- exc_load => mem.exc_load,
- exc_store => mem.exc_store
- );
- -- to MEM
- mem.pc_old_in <= exec.pc_old_out;
- mem.pc_new_in <= exec.pc_new_out;
- mem.aluresult_in <= exec.aluresult;
- mem.wrdata <= exec.wrdata;
- mem.zero <= exec.zero;
- mem.mem_op <= exec.memop_out;
- mem.wbop_in <= exec.wbop_out;
- -- STAGE 5
- writeback_inst : entity work.wb
- port map (
- clk => clk,
- res_n => res_n,
- stall => ctrl.stall or ctrl.stall_wb,
- flush => ctrl.flush or ctrl.flush_wb,
- -- from MEM
- op => wb.op,
- aluresult => wb.aluresult,
- memresult => wb.memresult,
- pc_old_in => wb.pc_old_in,
- -- to FWD and DEC
- reg_write => wb.reg_write
- );
- wb.op <= mem.wbop_out;
- wb.aluresult <= mem.aluresult_out;
- wb.memresult <= mem.memresult;
- wb.pc_old_in <= mem.pc_old_out;
-
- -- CTRL
- ctrl_inst : entity work.ctrl
- port map (
- clk => clk,
- res_n => res_n,
- stall => ctrl.stall,
-
- stall_fetch => ctrl.stall_fetch,
- stall_dec => ctrl.stall_dec,
- stall_exec => ctrl.stall_exec,
- stall_mem => ctrl.stall_mem,
- stall_wb => ctrl.stall_wb,
-
- flush_fetch => ctrl.flush_fetch,
- flush_dec => ctrl.flush_dec,
- flush_exec => ctrl.flush_exec,
- flush_mem => ctrl.flush_mem,
- flush_wb => ctrl.flush_wb,
-
- wb_op_exec => exec.wbop_out,
- exec_op_dec => decode.exec_op,
- pcsrc_in => mem.pcsrc,
- pcsrc_out => open
- );
-
- end architecture;
|