fetch1: Fix debug stop
[microwatt.git] / control.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3
4 library work;
5 use work.common.all;
6
7 entity control is
8 generic (
9 PIPELINE_DEPTH : natural := 2
10 );
11 port (
12 clk : in std_ulogic;
13 rst : in std_ulogic;
14
15 complete_in : in std_ulogic;
16 valid_in : in std_ulogic;
17 flush_in : in std_ulogic;
18 busy_in : in std_ulogic;
19 deferred : in std_ulogic;
20 sgl_pipe_in : in std_ulogic;
21 stop_mark_in : in std_ulogic;
22
23 gpr_write_valid_in : in std_ulogic;
24 gpr_write_in : in gspr_index_t;
25 gpr_bypassable : in std_ulogic;
26
27 update_gpr_write_valid : in std_ulogic;
28 update_gpr_write_reg : in gspr_index_t;
29
30 gpr_a_read_valid_in : in std_ulogic;
31 gpr_a_read_in : in gspr_index_t;
32
33 gpr_b_read_valid_in : in std_ulogic;
34 gpr_b_read_in : in gspr_index_t;
35
36 gpr_c_read_valid_in : in std_ulogic;
37 gpr_c_read_in : in gspr_index_t;
38
39 cr_read_in : in std_ulogic;
40 cr_write_in : in std_ulogic;
41 cr_bypassable : in std_ulogic;
42
43 valid_out : out std_ulogic;
44 stall_out : out std_ulogic;
45 stopped_out : out std_ulogic;
46
47 gpr_bypass_a : out std_ulogic;
48 gpr_bypass_b : out std_ulogic;
49 gpr_bypass_c : out std_ulogic;
50 cr_bypass : out std_ulogic
51 );
52 end entity control;
53
54 architecture rtl of control is
55 type state_type is (IDLE, WAIT_FOR_PREV_TO_COMPLETE, WAIT_FOR_CURR_TO_COMPLETE);
56
57 type reg_internal_type is record
58 state : state_type;
59 outstanding : integer range -1 to PIPELINE_DEPTH+2;
60 end record;
61 constant reg_internal_init : reg_internal_type := (state => IDLE, outstanding => 0);
62
63 signal r_int, rin_int : reg_internal_type := reg_internal_init;
64
65 signal stall_a_out : std_ulogic;
66 signal stall_b_out : std_ulogic;
67 signal stall_c_out : std_ulogic;
68 signal cr_stall_out : std_ulogic;
69
70 signal gpr_write_valid : std_ulogic := '0';
71 signal cr_write_valid : std_ulogic := '0';
72
73 begin
74 gpr_hazard0: entity work.gpr_hazard
75 generic map (
76 PIPELINE_DEPTH => PIPELINE_DEPTH
77 )
78 port map (
79 clk => clk,
80 busy_in => busy_in,
81 deferred => deferred,
82 complete_in => complete_in,
83 flush_in => flush_in,
84 issuing => valid_out,
85
86 gpr_write_valid_in => gpr_write_valid,
87 gpr_write_in => gpr_write_in,
88 bypass_avail => gpr_bypassable,
89 gpr_read_valid_in => gpr_a_read_valid_in,
90 gpr_read_in => gpr_a_read_in,
91
92 ugpr_write_valid => update_gpr_write_valid,
93 ugpr_write_reg => update_gpr_write_reg,
94
95 stall_out => stall_a_out,
96 use_bypass => gpr_bypass_a
97 );
98
99 gpr_hazard1: entity work.gpr_hazard
100 generic map (
101 PIPELINE_DEPTH => PIPELINE_DEPTH
102 )
103 port map (
104 clk => clk,
105 busy_in => busy_in,
106 deferred => deferred,
107 complete_in => complete_in,
108 flush_in => flush_in,
109 issuing => valid_out,
110
111 gpr_write_valid_in => gpr_write_valid,
112 gpr_write_in => gpr_write_in,
113 bypass_avail => gpr_bypassable,
114 gpr_read_valid_in => gpr_b_read_valid_in,
115 gpr_read_in => gpr_b_read_in,
116
117 ugpr_write_valid => update_gpr_write_valid,
118 ugpr_write_reg => update_gpr_write_reg,
119
120 stall_out => stall_b_out,
121 use_bypass => gpr_bypass_b
122 );
123
124 gpr_hazard2: entity work.gpr_hazard
125 generic map (
126 PIPELINE_DEPTH => PIPELINE_DEPTH
127 )
128 port map (
129 clk => clk,
130 busy_in => busy_in,
131 deferred => deferred,
132 complete_in => complete_in,
133 flush_in => flush_in,
134 issuing => valid_out,
135
136 gpr_write_valid_in => gpr_write_valid,
137 gpr_write_in => gpr_write_in,
138 bypass_avail => gpr_bypassable,
139 gpr_read_valid_in => gpr_c_read_valid_in,
140 gpr_read_in => gpr_c_read_in,
141
142 ugpr_write_valid => update_gpr_write_valid,
143 ugpr_write_reg => update_gpr_write_reg,
144
145 stall_out => stall_c_out,
146 use_bypass => gpr_bypass_c
147 );
148
149 cr_hazard0: entity work.cr_hazard
150 generic map (
151 PIPELINE_DEPTH => PIPELINE_DEPTH
152 )
153 port map (
154 clk => clk,
155 busy_in => busy_in,
156 deferred => deferred,
157 complete_in => complete_in,
158 flush_in => flush_in,
159 issuing => valid_out,
160
161 cr_read_in => cr_read_in,
162 cr_write_in => cr_write_valid,
163 bypassable => cr_bypassable,
164
165 stall_out => cr_stall_out,
166 use_bypass => cr_bypass
167 );
168
169 control0: process(clk)
170 begin
171 if rising_edge(clk) then
172 assert rin_int.outstanding >= 0 and rin_int.outstanding <= (PIPELINE_DEPTH+1)
173 report "Outstanding bad " & integer'image(rin_int.outstanding) severity failure;
174 r_int <= rin_int;
175 end if;
176 end process;
177
178 control1 : process(all)
179 variable v_int : reg_internal_type;
180 variable valid_tmp : std_ulogic;
181 variable stall_tmp : std_ulogic;
182 begin
183 v_int := r_int;
184
185 -- asynchronous
186 valid_tmp := valid_in and not flush_in;
187 stall_tmp := '0';
188
189 if flush_in = '1' then
190 -- expect to see complete_in next cycle
191 v_int.outstanding := 1;
192 elsif complete_in = '1' then
193 v_int.outstanding := r_int.outstanding - 1;
194 end if;
195
196 if rst = '1' then
197 v_int := reg_internal_init;
198 valid_tmp := '0';
199 end if;
200
201 -- Handle debugger stop
202 stopped_out <= '0';
203 if stop_mark_in = '1' and v_int.outstanding = 0 then
204 stopped_out <= '1';
205 end if;
206
207 -- state machine to handle instructions that must be single
208 -- through the pipeline.
209 case r_int.state is
210 when IDLE =>
211 if valid_tmp = '1' then
212 if (sgl_pipe_in = '1') then
213 if v_int.outstanding /= 0 then
214 v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
215 stall_tmp := '1';
216 else
217 -- send insn out and wait on it to complete
218 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
219 end if;
220 else
221 -- let it go out if there are no GPR hazards
222 stall_tmp := stall_a_out or stall_b_out or stall_c_out or cr_stall_out;
223 end if;
224 end if;
225
226 when WAIT_FOR_PREV_TO_COMPLETE =>
227 if v_int.outstanding = 0 then
228 -- send insn out and wait on it to complete
229 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
230 else
231 stall_tmp := '1';
232 end if;
233
234 when WAIT_FOR_CURR_TO_COMPLETE =>
235 if v_int.outstanding = 0 then
236 v_int.state := IDLE;
237 -- XXX Don't replicate this
238 if valid_tmp = '1' then
239 if (sgl_pipe_in = '1') then
240 if v_int.outstanding /= 0 then
241 v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
242 stall_tmp := '1';
243 else
244 -- send insn out and wait on it to complete
245 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
246 end if;
247 else
248 -- let it go out if there are no GPR hazards
249 stall_tmp := stall_a_out or stall_b_out or stall_c_out or cr_stall_out;
250 end if;
251 end if;
252 else
253 stall_tmp := '1';
254 end if;
255 end case;
256
257 if stall_tmp = '1' then
258 valid_tmp := '0';
259 end if;
260
261 if valid_tmp = '1' then
262 if deferred = '0' then
263 v_int.outstanding := v_int.outstanding + 1;
264 end if;
265 gpr_write_valid <= gpr_write_valid_in;
266 cr_write_valid <= cr_write_in;
267 else
268 gpr_write_valid <= '0';
269 cr_write_valid <= '0';
270 end if;
271
272 -- update outputs
273 valid_out <= valid_tmp;
274 stall_out <= stall_tmp or deferred;
275
276 -- update registers
277 rin_int <= v_int;
278 end process;
279 end;