bring ulx3s frequency down to 12.5 mhz
[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 EX1_BYPASS : boolean := true;
10 PIPELINE_DEPTH : natural := 2
11 );
12 port (
13 clk : in std_ulogic;
14 rst : in std_ulogic;
15
16 complete_in : in instr_tag_t;
17 valid_in : in std_ulogic;
18 repeated : in std_ulogic;
19 flush_in : in std_ulogic;
20 busy_in : in std_ulogic;
21 deferred : in std_ulogic;
22 sgl_pipe_in : in std_ulogic;
23 stop_mark_in : in std_ulogic;
24
25 gpr_write_valid_in : in std_ulogic;
26 gpr_write_in : in gspr_index_t;
27
28 gpr_a_read_valid_in : in std_ulogic;
29 gpr_a_read_in : in gspr_index_t;
30
31 gpr_b_read_valid_in : in std_ulogic;
32 gpr_b_read_in : in gspr_index_t;
33
34 gpr_c_read_valid_in : in std_ulogic;
35 gpr_c_read_in : in gspr_index_t;
36
37 execute_next_tag : in instr_tag_t;
38 execute_next_cr_tag : in instr_tag_t;
39
40 cr_read_in : in std_ulogic;
41 cr_write_in : 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 instr_tag_out : out instr_tag_t
53 );
54 end entity control;
55
56 architecture rtl of control is
57 type state_type is (IDLE, WAIT_FOR_PREV_TO_COMPLETE, WAIT_FOR_CURR_TO_COMPLETE);
58
59 type reg_internal_type is record
60 state : state_type;
61 outstanding : integer range -1 to PIPELINE_DEPTH+2;
62 end record;
63 constant reg_internal_init : reg_internal_type := (state => IDLE, outstanding => 0);
64
65 signal r_int, rin_int : reg_internal_type := reg_internal_init;
66
67 signal gpr_write_valid : std_ulogic := '0';
68 signal cr_write_valid : std_ulogic := '0';
69
70 type tag_register is record
71 wr_gpr : std_ulogic;
72 reg : gspr_index_t;
73 recent : std_ulogic;
74 wr_cr : std_ulogic;
75 end record;
76
77 type tag_regs_array is array(tag_number_t) of tag_register;
78 signal tag_regs : tag_regs_array;
79
80 signal instr_tag : instr_tag_t;
81
82 signal gpr_tag_stall : std_ulogic;
83 signal cr_tag_stall : std_ulogic;
84
85 signal curr_tag : tag_number_t;
86 signal next_tag : tag_number_t;
87
88 signal curr_cr_tag : tag_number_t;
89
90 begin
91 control0: process(clk)
92 begin
93 if rising_edge(clk) then
94 assert rin_int.outstanding >= 0 and rin_int.outstanding <= (PIPELINE_DEPTH+1)
95 report "Outstanding bad " & integer'image(rin_int.outstanding) severity failure;
96 r_int <= rin_int;
97 for i in tag_number_t loop
98 if rst = '1' or flush_in = '1' then
99 tag_regs(i).wr_gpr <= '0';
100 tag_regs(i).wr_cr <= '0';
101 else
102 if complete_in.valid = '1' and i = complete_in.tag then
103 tag_regs(i).wr_gpr <= '0';
104 tag_regs(i).wr_cr <= '0';
105 report "tag " & integer'image(i) & " not valid";
106 end if;
107 if gpr_write_valid = '1' and tag_regs(i).reg = gpr_write_in then
108 tag_regs(i).recent <= '0';
109 if tag_regs(i).recent = '1' and tag_regs(i).wr_gpr = '1' then
110 report "tag " & integer'image(i) & " not recent";
111 end if;
112 end if;
113 if instr_tag.valid = '1' and i = instr_tag.tag then
114 tag_regs(i).wr_gpr <= gpr_write_valid;
115 tag_regs(i).reg <= gpr_write_in;
116 tag_regs(i).recent <= gpr_write_valid;
117 tag_regs(i).wr_cr <= cr_write_valid;
118 if gpr_write_valid = '1' then
119 report "tag " & integer'image(i) & " valid for gpr " & to_hstring(gpr_write_in);
120 end if;
121 end if;
122 end if;
123 end loop;
124 if rst = '1' then
125 curr_tag <= 0;
126 curr_cr_tag <= 0;
127 else
128 curr_tag <= next_tag;
129 if cr_write_valid = '1' then
130 curr_cr_tag <= instr_tag.tag;
131 end if;
132 end if;
133 end if;
134 end process;
135
136 control_hazards : process(all)
137 variable gpr_stall : std_ulogic;
138 variable tag_a : instr_tag_t;
139 variable tag_b : instr_tag_t;
140 variable tag_c : instr_tag_t;
141 variable tag_s : instr_tag_t;
142 variable tag_t : instr_tag_t;
143 variable incr_tag : tag_number_t;
144 variable byp_a : std_ulogic;
145 variable byp_b : std_ulogic;
146 variable byp_c : std_ulogic;
147 variable tag_cr : instr_tag_t;
148 variable byp_cr : std_ulogic;
149 begin
150 tag_a := instr_tag_init;
151 for i in tag_number_t loop
152 if tag_regs(i).wr_gpr = '1' and tag_regs(i).recent = '1' and tag_regs(i).reg = gpr_a_read_in then
153 tag_a.valid := gpr_a_read_valid_in;
154 tag_a.tag := i;
155 end if;
156 end loop;
157 if tag_match(tag_a, complete_in) then
158 tag_a.valid := '0';
159 end if;
160 tag_b := instr_tag_init;
161 for i in tag_number_t loop
162 if tag_regs(i).wr_gpr = '1' and tag_regs(i).recent = '1' and tag_regs(i).reg = gpr_b_read_in then
163 tag_b.valid := gpr_b_read_valid_in;
164 tag_b.tag := i;
165 end if;
166 end loop;
167 if tag_match(tag_b, complete_in) then
168 tag_b.valid := '0';
169 end if;
170 tag_c := instr_tag_init;
171 for i in tag_number_t loop
172 if tag_regs(i).wr_gpr = '1' and tag_regs(i).recent = '1' and tag_regs(i).reg = gpr_c_read_in then
173 tag_c.valid := gpr_c_read_valid_in;
174 tag_c.tag := i;
175 end if;
176 end loop;
177 if tag_match(tag_c, complete_in) then
178 tag_c.valid := '0';
179 end if;
180
181 byp_a := '0';
182 if EX1_BYPASS and tag_match(execute_next_tag, tag_a) then
183 byp_a := '1';
184 end if;
185 byp_b := '0';
186 if EX1_BYPASS and tag_match(execute_next_tag, tag_b) then
187 byp_b := '1';
188 end if;
189 byp_c := '0';
190 if EX1_BYPASS and tag_match(execute_next_tag, tag_c) then
191 byp_c := '1';
192 end if;
193
194 gpr_bypass_a <= byp_a;
195 gpr_bypass_b <= byp_b;
196 gpr_bypass_c <= byp_c;
197
198 gpr_tag_stall <= (tag_a.valid and not byp_a) or
199 (tag_b.valid and not byp_b) or
200 (tag_c.valid and not byp_c);
201
202 incr_tag := curr_tag;
203 instr_tag.tag <= curr_tag;
204 instr_tag.valid <= valid_out and not deferred;
205 if instr_tag.valid = '1' then
206 incr_tag := (curr_tag + 1) mod TAG_COUNT;
207 end if;
208 next_tag <= incr_tag;
209 instr_tag_out <= instr_tag;
210
211 -- CR hazards
212 tag_cr.tag := curr_cr_tag;
213 tag_cr.valid := cr_read_in and tag_regs(curr_cr_tag).wr_cr;
214 if tag_match(tag_cr, complete_in) then
215 tag_cr.valid := '0';
216 end if;
217 byp_cr := '0';
218 if EX1_BYPASS and tag_match(execute_next_cr_tag, tag_cr) then
219 byp_cr := '1';
220 end if;
221
222 cr_bypass <= byp_cr;
223 cr_tag_stall <= tag_cr.valid and not byp_cr;
224 end process;
225
226 control1 : process(all)
227 variable v_int : reg_internal_type;
228 variable valid_tmp : std_ulogic;
229 variable stall_tmp : std_ulogic;
230 begin
231 v_int := r_int;
232
233 -- asynchronous
234 valid_tmp := valid_in and not flush_in;
235 stall_tmp := '0';
236
237 if flush_in = '1' then
238 v_int.outstanding := 0;
239 elsif complete_in.valid = '1' then
240 v_int.outstanding := r_int.outstanding - 1;
241 end if;
242
243 if rst = '1' then
244 v_int := reg_internal_init;
245 valid_tmp := '0';
246 end if;
247
248 -- Handle debugger stop
249 stopped_out <= '0';
250 if stop_mark_in = '1' and v_int.outstanding = 0 then
251 stopped_out <= '1';
252 end if;
253
254 -- state machine to handle instructions that must be single
255 -- through the pipeline.
256 case r_int.state is
257 when IDLE =>
258 if valid_tmp = '1' then
259 if (sgl_pipe_in = '1') then
260 if v_int.outstanding /= 0 then
261 v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
262 stall_tmp := '1';
263 else
264 -- send insn out and wait on it to complete
265 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
266 end if;
267 else
268 -- let it go out if there are no GPR or CR hazards
269 stall_tmp := gpr_tag_stall or cr_tag_stall;
270 end if;
271 end if;
272
273 when WAIT_FOR_PREV_TO_COMPLETE =>
274 if v_int.outstanding = 0 then
275 -- send insn out and wait on it to complete
276 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
277 else
278 stall_tmp := '1';
279 end if;
280
281 when WAIT_FOR_CURR_TO_COMPLETE =>
282 if v_int.outstanding = 0 then
283 v_int.state := IDLE;
284 -- XXX Don't replicate this
285 if valid_tmp = '1' then
286 if (sgl_pipe_in = '1') then
287 if v_int.outstanding /= 0 then
288 v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
289 stall_tmp := '1';
290 else
291 -- send insn out and wait on it to complete
292 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
293 end if;
294 else
295 -- let it go out if there are no GPR or CR hazards
296 stall_tmp := gpr_tag_stall or cr_tag_stall;
297 end if;
298 end if;
299 else
300 stall_tmp := '1';
301 end if;
302 end case;
303
304 if stall_tmp = '1' then
305 valid_tmp := '0';
306 end if;
307
308 gpr_write_valid <= gpr_write_valid_in and valid_tmp;
309 cr_write_valid <= cr_write_in and valid_tmp;
310
311 if valid_tmp = '1' and deferred = '0' then
312 v_int.outstanding := v_int.outstanding + 1;
313 end if;
314
315 -- update outputs
316 valid_out <= valid_tmp;
317 stall_out <= stall_tmp or deferred;
318
319 -- update registers
320 rin_int <= v_int;
321 end process;
322 end;