1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.numeric_std.all;
- use work.core_pkg.all;
- use work.op_pkg.all;
- use work.mem_pkg.all;
- entity fetch is
- port (
- clk : in std_logic;
- res_n : in std_logic;
- stall : in std_logic;
- flush : in std_logic;
- -- to control
- mem_busy : out std_logic;
- pcsrc : in std_logic;
- pc_in : in pc_type;
- pc_out : out pc_type := (others => '0');
- instr : out instr_type;
- -- memory controller interface
- mem_out : out mem_out_type;
- mem_in : in mem_in_type
- );
- end entity;
- architecture rtl of fetch is
- signal pc_out_next : pc_type := (others => '0');
- begin
- -- concurrent
- mem_busy <= mem_in.busy;
- mem_out.address(ADDR_WIDTH - 1 downto 0) <= pc_out_next(PC_WIDTH - 1 downto PC_WIDTH - ADDR_WIDTH);
- mem_out.rd <= '1';
- mem_out.wr <= '0';
- mem_out.byteena <= "1111";
- mem_out.wrdata <= (others => '0');
- instr(31 downto 24) <= NOP_INST(31 downto 24) when flush = '1' else mem_in.rddata(7 downto 0);
- instr(23 downto 16) <= NOP_INST(23 downto 16) when flush = '1' else mem_in.rddata(15 downto 8);
- instr(15 downto 8) <= NOP_INST(15 downto 8) when flush = '1' else mem_in.rddata(23 downto 16);
- instr(7 downto 0) <= NOP_INST(7 downto 0) when flush = '1' else mem_in.rddata(31 downto 24);
- -- sequential
- sync : process(clk, res_n)
- begin
- if res_n = '0' then
- pc_out <= (others => '0'); --initialize to -4
- elsif rising_edge(clk) then
- pc_out <= pc_out_next;
- end if;
- end process;
- async : process(all)
- begin
- pc_out_next <= pc_out;
- -- assumes instruction has the same length as mem data
- -- only change pc
- if stall = '0' and pcsrc = '1' then
- -- use pc_in
- pc_out_next <= pc_in;
- elsif stall = '0' and pcsrc = '0' then
- -- use pc_out + 4 (bytes)
- pc_out_next <= std_logic_vector(unsigned(pc_out) + x"4");
- end if;
- end process;
-
- end architecture;
|