Merge pull request #265 from antonblanchard/another-spi-rxtx-reset-issu
[microwatt.git] / fetch1.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library work;
6 use work.common.all;
7
8 entity fetch1 is
9 generic(
10 RESET_ADDRESS : std_logic_vector(63 downto 0) := (others => '0');
11 ALT_RESET_ADDRESS : std_logic_vector(63 downto 0) := (others => '0')
12 );
13 port(
14 clk : in std_ulogic;
15 rst : in std_ulogic;
16
17 -- Control inputs:
18 stall_in : in std_ulogic;
19 flush_in : in std_ulogic;
20 stop_in : in std_ulogic;
21 alt_reset_in : in std_ulogic;
22
23 -- redirect from execution unit
24 e_in : in Execute1ToFetch1Type;
25
26 -- redirect from decode1
27 d_in : in Decode1ToFetch1Type;
28
29 -- Request to icache
30 i_out : out Fetch1ToIcacheType;
31
32 -- outputs to logger
33 log_out : out std_ulogic_vector(42 downto 0)
34 );
35 end entity fetch1;
36
37 architecture behaviour of fetch1 is
38 type reg_internal_t is record
39 mode_32bit: std_ulogic;
40 end record;
41 signal r, r_next : Fetch1ToIcacheType;
42 signal r_int, r_next_int : reg_internal_t;
43 signal log_nia : std_ulogic_vector(42 downto 0);
44 begin
45
46 regs : process(clk)
47 begin
48 if rising_edge(clk) then
49 log_nia <= r.nia(63) & r.nia(43 downto 2);
50 if r /= r_next then
51 report "fetch1 rst:" & std_ulogic'image(rst) &
52 " IR:" & std_ulogic'image(r_next.virt_mode) &
53 " P:" & std_ulogic'image(r_next.priv_mode) &
54 " E:" & std_ulogic'image(r_next.big_endian) &
55 " 32:" & std_ulogic'image(r_next_int.mode_32bit) &
56 " R:" & std_ulogic'image(e_in.redirect) & std_ulogic'image(d_in.redirect) &
57 " S:" & std_ulogic'image(stall_in) &
58 " T:" & std_ulogic'image(stop_in) &
59 " nia:" & to_hstring(r_next.nia) &
60 " SM:" & std_ulogic'image(r_next.stop_mark);
61 end if;
62 r <= r_next;
63 r_int <= r_next_int;
64 end if;
65 end process;
66 log_out <= log_nia;
67
68 comb : process(all)
69 variable v : Fetch1ToIcacheType;
70 variable v_int : reg_internal_t;
71 begin
72 v := r;
73 v_int := r_int;
74 v.sequential := '0';
75
76 if rst = '1' then
77 if alt_reset_in = '1' then
78 v.nia := ALT_RESET_ADDRESS;
79 else
80 v.nia := RESET_ADDRESS;
81 end if;
82 v.virt_mode := '0';
83 v.priv_mode := '1';
84 v.big_endian := '0';
85 v_int.mode_32bit := '0';
86 elsif e_in.redirect = '1' then
87 v.nia := e_in.redirect_nia(63 downto 2) & "00";
88 if e_in.mode_32bit = '1' then
89 v.nia(63 downto 32) := (others => '0');
90 end if;
91 v.virt_mode := e_in.virt_mode;
92 v.priv_mode := e_in.priv_mode;
93 v.big_endian := e_in.big_endian;
94 v_int.mode_32bit := e_in.mode_32bit;
95 elsif d_in.redirect = '1' then
96 v.nia := d_in.redirect_nia(63 downto 2) & "00";
97 if r_int.mode_32bit = '1' then
98 v.nia(63 downto 32) := (others => '0');
99 end if;
100 elsif stall_in = '0' then
101
102 -- If the last NIA value went down with a stop mark, it didn't get
103 -- executed, and hence we shouldn't increment NIA.
104 if r.stop_mark = '0' then
105 if r_int.mode_32bit = '0' then
106 v.nia := std_ulogic_vector(unsigned(r.nia) + 4);
107 else
108 v.nia := x"00000000" & std_ulogic_vector(unsigned(r.nia(31 downto 0)) + 4);
109 end if;
110 v.sequential := '1';
111 end if;
112 end if;
113
114 v.req := not rst and not stop_in;
115 v.stop_mark := stop_in;
116
117 r_next <= v;
118 r_next_int <= v_int;
119
120 -- Update outputs to the icache
121 i_out <= r;
122
123 end process;
124
125 end architecture behaviour;