2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
7 use work.wishbone_types.all;
14 stall_in : in std_ulogic;
15 stall_out : out std_ulogic;
17 flush_in : in std_ulogic;
19 -- instruction memory interface
20 wishbone_in : in wishbone_slave_out;
21 wishbone_out : out wishbone_master_out;
23 f_in : in Fetch1ToFetch2Type;
25 f_out : out Fetch2ToDecode1Type
29 architecture behaviour of fetch2 is
30 type state_type is (IDLE, JUST_IDLE, WAIT_ACK, WAIT_ACK_THROWAWAY);
32 type reg_internal_type is record
34 nia : std_ulogic_vector(63 downto 0);
35 w : wishbone_master_out;
37 cache : std_ulogic_vector(63 downto 0);
38 tag : std_ulogic_vector(60 downto 0);
39 tag_valid : std_ulogic;
42 function wishbone_fetch(nia : std_ulogic_vector(63 downto 0)) return wishbone_master_out is
43 variable w : wishbone_master_out;
45 assert nia(2 downto 0) = "000";
48 w.dat := (others => '0');
57 signal r, rin : Fetch2ToDecode1Type;
58 signal r_int, rin_int : reg_internal_type;
62 if rising_edge(clk) then
63 -- Output state remains unchanged on stall, unless we are flushing
64 if rst = '1' or flush_in = '1' or stall_in = '0' then
72 variable v : Fetch2ToDecode1Type;
73 variable v_int : reg_internal_type;
82 when IDLE | JUST_IDLE =>
85 if (v_int.tag_valid = '1') and (v_int.tag = f_in.nia(63 downto 3)) then
87 if f_in.nia(2) = '0' then
88 v.insn := v_int.cache(31 downto 0);
90 v.insn := v_int.cache(63 downto 32);
93 v_int.state := WAIT_ACK;
94 v_int.nia := f_in.nia;
95 v_int.w := wishbone_fetch(f_in.nia(63 downto 3) & "000");
99 if wishbone_in.ack = '1' then
101 v_int.w := wishbone_master_out_init;
102 v_int.cache := wishbone_in.dat;
103 v_int.tag := v_int.nia(63 downto 3);
104 v_int.tag_valid := '1';
107 if v_int.nia(2) = '0' then
108 v.insn := v_int.cache(31 downto 0);
110 v.insn := v_int.cache(63 downto 32);
114 when WAIT_ACK_THROWAWAY =>
115 if wishbone_in.ack = '1' then
116 -- Should we put the returned data in the cache? We went to the
117 -- trouble of fetching it and it might be useful in the future
119 v_int.w := wishbone_master_out_init;
121 -- We need to stall fetch1 for one more cycle, so transition through JUST_IDLE
122 v_int.state := JUST_IDLE;
127 if v_int.state /= IDLE then
131 if flush_in = '1' then
134 -- Throw away in flight data
135 if v_int.state = WAIT_ACK then
136 v_int.state := WAIT_ACK_THROWAWAY;
141 v := Fetch2ToDecode1Init;
144 v_int.nia := (others => '0');
145 v_int.w := wishbone_master_out_init;
146 v_int.cache := (others => '0');
147 v_int.tag := (others => '0');
148 v_int.tag_valid := '0';
157 wishbone_out <= r_int.w;
159 end architecture behaviour;