2 use ieee.std_logic_1164.all;
9 PIPELINE_DEPTH : natural := 2
15 complete_in : in instr_tag_t;
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;
24 gpr_write_valid_in : in std_ulogic;
25 gpr_write_in : in gspr_index_t;
26 gpr_bypassable : in std_ulogic;
28 gpr_a_read_valid_in : in std_ulogic;
29 gpr_a_read_in : in gspr_index_t;
31 gpr_b_read_valid_in : in std_ulogic;
32 gpr_b_read_in : in gspr_index_t;
34 gpr_c_read_valid_in : in std_ulogic;
35 gpr_c_read_in : in gspr_index_t;
37 cr_read_in : in std_ulogic;
38 cr_write_in : in std_ulogic;
39 cr_bypassable : in std_ulogic;
41 valid_out : out std_ulogic;
42 stall_out : out std_ulogic;
43 stopped_out : out std_ulogic;
45 gpr_bypass_a : out std_ulogic;
46 gpr_bypass_b : out std_ulogic;
47 gpr_bypass_c : out std_ulogic;
48 cr_bypass : out std_ulogic;
50 instr_tag_out : out instr_tag_t
54 architecture rtl of control is
55 type state_type is (IDLE, WAIT_FOR_PREV_TO_COMPLETE, WAIT_FOR_CURR_TO_COMPLETE);
57 type reg_internal_type is record
59 outstanding : integer range -1 to PIPELINE_DEPTH+2;
61 constant reg_internal_init : reg_internal_type := (state => IDLE, outstanding => 0);
63 signal r_int, rin_int : reg_internal_type := reg_internal_init;
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;
70 signal gpr_write_valid : std_ulogic := '0';
71 signal cr_write_valid : std_ulogic := '0';
73 type tag_register is record
79 type tag_regs_array is array(tag_number_t) of tag_register;
80 signal tag_regs : tag_regs_array;
82 signal instr_tag : instr_tag_t;
84 signal gpr_tag_a : instr_tag_t;
85 signal gpr_tag_b : instr_tag_t;
86 signal gpr_tag_c : instr_tag_t;
87 signal gpr_tag_stall : std_ulogic;
89 signal curr_tag : tag_number_t;
90 signal next_tag : tag_number_t;
92 function tag_match(tag1 : instr_tag_t; tag2 : instr_tag_t) return boolean is
94 return tag1.valid = '1' and tag2.valid = '1' and tag1.tag = tag2.tag;
98 cr_hazard0: entity work.cr_hazard
100 PIPELINE_DEPTH => PIPELINE_DEPTH
105 deferred => deferred,
106 complete_in => complete_in.valid,
107 flush_in => flush_in,
108 issuing => valid_out,
110 cr_read_in => cr_read_in,
111 cr_write_in => cr_write_valid,
112 bypassable => cr_bypassable,
114 stall_out => cr_stall_out,
115 use_bypass => cr_bypass
122 control0: process(clk)
124 if rising_edge(clk) then
125 assert rin_int.outstanding >= 0 and rin_int.outstanding <= (PIPELINE_DEPTH+1)
126 report "Outstanding bad " & integer'image(rin_int.outstanding) severity failure;
128 for i in tag_number_t loop
129 if rst = '1' or flush_in = '1' then
130 tag_regs(i).wr_gpr <= '0';
132 if complete_in.valid = '1' and i = complete_in.tag then
133 tag_regs(i).wr_gpr <= '0';
134 report "tag " & integer'image(i) & " not valid";
136 if gpr_write_valid = '1' and tag_regs(i).reg = gpr_write_in then
137 tag_regs(i).recent <= '0';
138 if tag_regs(i).recent = '1' and tag_regs(i).wr_gpr = '1' then
139 report "tag " & integer'image(i) & " not recent";
142 if instr_tag.valid = '1' and i = instr_tag.tag then
143 tag_regs(i).wr_gpr <= gpr_write_valid;
144 tag_regs(i).reg <= gpr_write_in;
145 tag_regs(i).recent <= gpr_write_valid;
146 if gpr_write_valid = '1' then
147 report "tag " & integer'image(i) & " valid for gpr " & to_hstring(gpr_write_in);
155 curr_tag <= next_tag;
160 control_hazards : process(all)
161 variable gpr_stall : std_ulogic;
162 variable tag_a : instr_tag_t;
163 variable tag_b : instr_tag_t;
164 variable tag_c : instr_tag_t;
165 variable tag_s : instr_tag_t;
166 variable tag_t : instr_tag_t;
167 variable incr_tag : tag_number_t;
169 tag_a := instr_tag_init;
170 for i in tag_number_t loop
171 if tag_regs(i).wr_gpr = '1' and tag_regs(i).recent = '1' and tag_regs(i).reg = gpr_a_read_in then
172 tag_a.valid := gpr_a_read_valid_in;
176 if tag_match(tag_a, complete_in) then
179 tag_b := instr_tag_init;
180 for i in tag_number_t loop
181 if tag_regs(i).wr_gpr = '1' and tag_regs(i).recent = '1' and tag_regs(i).reg = gpr_b_read_in then
182 tag_b.valid := gpr_b_read_valid_in;
186 if tag_match(tag_b, complete_in) then
189 tag_c := instr_tag_init;
190 for i in tag_number_t loop
191 if tag_regs(i).wr_gpr = '1' and tag_regs(i).recent = '1' and tag_regs(i).reg = gpr_c_read_in then
192 tag_c.valid := gpr_c_read_valid_in;
196 if tag_match(tag_c, complete_in) then
202 gpr_tag_stall <= tag_a.valid or tag_b.valid or tag_c.valid;
204 incr_tag := curr_tag;
205 instr_tag.tag <= curr_tag;
206 instr_tag.valid <= valid_out and not deferred;
207 if instr_tag.valid = '1' then
208 incr_tag := (curr_tag + 1) mod TAG_COUNT;
210 next_tag <= incr_tag;
211 instr_tag_out <= instr_tag;
214 control1 : process(all)
215 variable v_int : reg_internal_type;
216 variable valid_tmp : std_ulogic;
217 variable stall_tmp : std_ulogic;
222 valid_tmp := valid_in and not flush_in;
225 if flush_in = '1' then
226 -- expect to see complete_in next cycle
227 v_int.outstanding := 1;
228 elsif complete_in.valid = '1' then
229 v_int.outstanding := r_int.outstanding - 1;
233 v_int := reg_internal_init;
237 -- Handle debugger stop
239 if stop_mark_in = '1' and v_int.outstanding = 0 then
243 -- state machine to handle instructions that must be single
244 -- through the pipeline.
247 if valid_tmp = '1' then
248 if (sgl_pipe_in = '1') then
249 if v_int.outstanding /= 0 then
250 v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
253 -- send insn out and wait on it to complete
254 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
257 -- let it go out if there are no GPR or CR hazards
258 stall_tmp := gpr_tag_stall or cr_stall_out;
262 when WAIT_FOR_PREV_TO_COMPLETE =>
263 if v_int.outstanding = 0 then
264 -- send insn out and wait on it to complete
265 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
270 when WAIT_FOR_CURR_TO_COMPLETE =>
271 if v_int.outstanding = 0 then
273 -- XXX Don't replicate this
274 if valid_tmp = '1' then
275 if (sgl_pipe_in = '1') then
276 if v_int.outstanding /= 0 then
277 v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
280 -- send insn out and wait on it to complete
281 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
284 -- let it go out if there are no GPR or CR hazards
285 stall_tmp := gpr_tag_stall or cr_stall_out;
293 if stall_tmp = '1' then
297 gpr_write_valid <= gpr_write_valid_in and valid_tmp;
298 cr_write_valid <= cr_write_in and valid_tmp;
300 if valid_tmp = '1' and deferred = '0' then
301 v_int.outstanding := v_int.outstanding + 1;
305 valid_out <= valid_tmp;
306 stall_out <= stall_tmp or deferred;