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