2 use ieee.std_logic_1164.all;
9 EX1_BYPASS : boolean := true;
10 PIPELINE_DEPTH : natural := 3
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;
25 gpr_write_valid_in : in std_ulogic;
26 gpr_write_in : in gspr_index_t;
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 execute_next_tag : in instr_tag_t;
38 execute_next_cr_tag : in instr_tag_t;
40 cr_read_in : in std_ulogic;
41 cr_write_in : in std_ulogic;
43 valid_out : out std_ulogic;
44 stall_out : out std_ulogic;
45 stopped_out : out std_ulogic;
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;
52 instr_tag_out : out instr_tag_t
56 architecture rtl of control is
57 type state_type is (IDLE, WAIT_FOR_PREV_TO_COMPLETE, WAIT_FOR_CURR_TO_COMPLETE);
59 type reg_internal_type is record
61 outstanding : integer range -1 to PIPELINE_DEPTH+2;
63 constant reg_internal_init : reg_internal_type := (state => IDLE, outstanding => 0);
65 signal r_int, rin_int : reg_internal_type := reg_internal_init;
67 signal gpr_write_valid : std_ulogic := '0';
68 signal cr_write_valid : std_ulogic := '0';
70 type tag_register is record
77 type tag_regs_array is array(tag_number_t) of tag_register;
78 signal tag_regs : tag_regs_array;
80 signal instr_tag : instr_tag_t;
82 signal gpr_tag_stall : std_ulogic;
83 signal cr_tag_stall : std_ulogic;
85 signal curr_tag : tag_number_t;
86 signal next_tag : tag_number_t;
88 signal curr_cr_tag : tag_number_t;
91 control0: process(clk)
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;
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';
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";
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";
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);
128 curr_tag <= next_tag;
129 if cr_write_valid = '1' then
130 curr_cr_tag <= instr_tag.tag;
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;
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;
157 if tag_match(tag_a, complete_in) then
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;
167 if tag_match(tag_b, complete_in) then
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;
177 if tag_match(tag_c, complete_in) then
182 if EX1_BYPASS and tag_match(execute_next_tag, tag_a) then
186 if EX1_BYPASS and tag_match(execute_next_tag, tag_b) then
190 if EX1_BYPASS and tag_match(execute_next_tag, tag_c) then
194 gpr_bypass_a <= byp_a;
195 gpr_bypass_b <= byp_b;
196 gpr_bypass_c <= byp_c;
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);
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;
208 next_tag <= incr_tag;
209 instr_tag_out <= instr_tag;
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
218 if EX1_BYPASS and tag_match(execute_next_cr_tag, tag_cr) then
223 cr_tag_stall <= tag_cr.valid and not byp_cr;
226 control1 : process(all)
227 variable v_int : reg_internal_type;
228 variable valid_tmp : std_ulogic;
229 variable stall_tmp : std_ulogic;
234 valid_tmp := valid_in and not flush_in;
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;
242 if r_int.outstanding >= PIPELINE_DEPTH + 1 then
248 v_int := reg_internal_init;
252 -- Handle debugger stop
254 if stop_mark_in = '1' and v_int.outstanding = 0 then
258 -- state machine to handle instructions that must be single
259 -- through the pipeline.
262 if valid_tmp = '1' then
263 if (sgl_pipe_in = '1') then
264 if v_int.outstanding /= 0 then
265 v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
268 -- send insn out and wait on it to complete
269 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
272 -- let it go out if there are no GPR or CR hazards
273 stall_tmp := gpr_tag_stall or cr_tag_stall;
277 when WAIT_FOR_PREV_TO_COMPLETE =>
278 if v_int.outstanding = 0 then
279 -- send insn out and wait on it to complete
280 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
285 when WAIT_FOR_CURR_TO_COMPLETE =>
286 if v_int.outstanding = 0 then
288 -- XXX Don't replicate this
289 if valid_tmp = '1' then
290 if (sgl_pipe_in = '1') then
291 if v_int.outstanding /= 0 then
292 v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
295 -- send insn out and wait on it to complete
296 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
299 -- let it go out if there are no GPR or CR hazards
300 stall_tmp := gpr_tag_stall or cr_tag_stall;
308 if stall_tmp = '1' then
312 gpr_write_valid <= gpr_write_valid_in and valid_tmp;
313 cr_write_valid <= cr_write_in and valid_tmp;
315 if valid_tmp = '1' and deferred = '0' then
316 v_int.outstanding := v_int.outstanding + 1;
320 valid_out <= valid_tmp;
321 stall_out <= stall_tmp or deferred;