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 flush_in : in std_ulogic;
19 deferred : in std_ulogic;
20 serialize : in std_ulogic;
21 stop_mark_in : in std_ulogic;
23 gpr_write_valid_in : in std_ulogic;
24 gpr_write_in : in gspr_index_t;
26 gpr_a_read_valid_in : in std_ulogic;
27 gpr_a_read_in : in gspr_index_t;
29 gpr_b_read_valid_in : in std_ulogic;
30 gpr_b_read_in : in gspr_index_t;
32 gpr_c_read_valid_in : in std_ulogic;
33 gpr_c_read_in : in gspr_index_t;
35 execute_next_tag : in instr_tag_t;
36 execute_next_cr_tag : in instr_tag_t;
37 execute2_next_tag : in instr_tag_t;
38 execute2_next_cr_tag : in instr_tag_t;
40 cr_read_in : in std_ulogic;
41 cr_write_in : in std_ulogic;
42 ov_read_in : in std_ulogic;
43 ov_write_in : in std_ulogic;
45 valid_out : out std_ulogic;
46 stopped_out : out std_ulogic;
48 gpr_bypass_a : out std_ulogic_vector(1 downto 0);
49 gpr_bypass_b : out std_ulogic_vector(1 downto 0);
50 gpr_bypass_c : out std_ulogic_vector(1 downto 0);
51 cr_bypass : out std_ulogic_vector(1 downto 0);
53 instr_tag_out : out instr_tag_t
57 architecture rtl of control is
58 signal gpr_write_valid : std_ulogic;
59 signal cr_write_valid : std_ulogic;
60 signal ov_write_valid : std_ulogic;
62 type tag_register is record
71 type tag_regs_array is array(tag_number_t) of tag_register;
72 signal tag_regs : tag_regs_array;
74 signal instr_tag : instr_tag_t;
76 signal gpr_tag_stall : std_ulogic;
77 signal cr_tag_stall : std_ulogic;
78 signal ov_tag_stall : std_ulogic;
79 signal serial_stall : std_ulogic;
81 signal curr_tag : tag_number_t;
82 signal next_tag : tag_number_t;
84 signal curr_cr_tag : tag_number_t;
85 signal curr_ov_tag : tag_number_t;
86 signal prev_tag : tag_number_t;
89 control0: process(clk)
91 if rising_edge(clk) then
92 for i in tag_number_t loop
93 if rst = '1' or flush_in = '1' then
94 tag_regs(i).wr_gpr <= '0';
95 tag_regs(i).wr_cr <= '0';
96 tag_regs(i).wr_ov <= '0';
97 tag_regs(i).valid <= '0';
99 if complete_in.valid = '1' and i = complete_in.tag then
100 assert tag_regs(i).valid = '1' report "spurious completion" severity failure;
101 tag_regs(i).wr_gpr <= '0';
102 tag_regs(i).wr_cr <= '0';
103 tag_regs(i).wr_ov <= '0';
104 tag_regs(i).valid <= '0';
105 report "tag " & integer'image(i) & " not valid";
107 if instr_tag.valid = '1' and gpr_write_valid = '1' and
108 tag_regs(i).reg = gpr_write_in then
109 tag_regs(i).recent <= '0';
110 if tag_regs(i).recent = '1' and tag_regs(i).wr_gpr = '1' then
111 report "tag " & integer'image(i) & " not recent";
114 if instr_tag.valid = '1' and i = instr_tag.tag then
115 tag_regs(i).wr_gpr <= gpr_write_valid;
116 tag_regs(i).reg <= gpr_write_in;
117 tag_regs(i).recent <= gpr_write_valid;
118 tag_regs(i).wr_cr <= cr_write_valid;
119 tag_regs(i).wr_ov <= ov_write_valid;
120 tag_regs(i).valid <= '1';
121 if gpr_write_valid = '1' then
122 report "tag " & integer'image(i) & " valid for gpr " & to_hstring(gpr_write_in);
133 curr_tag <= next_tag;
134 if instr_tag.valid = '1' and cr_write_valid = '1' then
135 curr_cr_tag <= instr_tag.tag;
137 if instr_tag.valid = '1' and ov_write_valid = '1' then
138 curr_ov_tag <= instr_tag.tag;
140 if valid_out = '1' then
141 prev_tag <= instr_tag.tag;
147 control_hazards : process(all)
148 variable gpr_stall : std_ulogic;
149 variable tag_a : instr_tag_t;
150 variable tag_b : instr_tag_t;
151 variable tag_c : instr_tag_t;
152 variable tag_s : instr_tag_t;
153 variable tag_t : instr_tag_t;
154 variable incr_tag : tag_number_t;
155 variable byp_a : std_ulogic_vector(1 downto 0);
156 variable byp_b : std_ulogic_vector(1 downto 0);
157 variable byp_c : std_ulogic_vector(1 downto 0);
158 variable tag_cr : instr_tag_t;
159 variable byp_cr : std_ulogic_vector(1 downto 0);
160 variable tag_ov : instr_tag_t;
161 variable tag_prev : instr_tag_t;
163 tag_a := instr_tag_init;
164 for i in tag_number_t loop
165 if tag_regs(i).wr_gpr = '1' and tag_regs(i).recent = '1' and tag_regs(i).reg = gpr_a_read_in then
166 tag_a.valid := gpr_a_read_valid_in;
170 tag_b := 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_b_read_in then
173 tag_b.valid := gpr_b_read_valid_in;
177 tag_c := instr_tag_init;
178 for i in tag_number_t loop
179 if tag_regs(i).wr_gpr = '1' and tag_regs(i).recent = '1' and tag_regs(i).reg = gpr_c_read_in then
180 tag_c.valid := gpr_c_read_valid_in;
186 if EX1_BYPASS and tag_match(execute_next_tag, tag_a) then
188 elsif EX1_BYPASS and tag_match(execute2_next_tag, tag_a) then
190 elsif tag_match(complete_in, tag_a) then
194 if EX1_BYPASS and tag_match(execute_next_tag, tag_b) then
196 elsif EX1_BYPASS and tag_match(execute2_next_tag, tag_b) then
198 elsif tag_match(complete_in, tag_b) then
202 if EX1_BYPASS and tag_match(execute_next_tag, tag_c) then
204 elsif EX1_BYPASS and tag_match(execute2_next_tag, tag_c) then
206 elsif tag_match(complete_in, tag_c) then
210 gpr_bypass_a <= byp_a;
211 gpr_bypass_b <= byp_b;
212 gpr_bypass_c <= byp_c;
214 gpr_tag_stall <= (tag_a.valid and not (or (byp_a))) or
215 (tag_b.valid and not (or (byp_b))) or
216 (tag_c.valid and not (or (byp_c)));
218 incr_tag := curr_tag;
219 instr_tag.tag <= curr_tag;
220 instr_tag.valid <= valid_out and not deferred;
221 if instr_tag.valid = '1' then
222 incr_tag := (curr_tag + 1) mod TAG_COUNT;
224 next_tag <= incr_tag;
225 instr_tag_out <= instr_tag;
228 tag_cr.tag := curr_cr_tag;
229 tag_cr.valid := cr_read_in and tag_regs(curr_cr_tag).wr_cr;
230 if tag_match(tag_cr, complete_in) then
234 if EX1_BYPASS and tag_match(execute_next_cr_tag, tag_cr) then
236 elsif EX1_BYPASS and tag_match(execute2_next_cr_tag, tag_cr) then
241 cr_tag_stall <= tag_cr.valid and not byp_cr(1);
244 tag_ov.tag := curr_ov_tag;
245 tag_ov.valid := ov_read_in and tag_regs(curr_ov_tag).wr_ov;
246 if tag_match(tag_ov, complete_in) then
249 ov_tag_stall <= tag_ov.valid;
251 tag_prev.tag := prev_tag;
252 tag_prev.valid := tag_regs(prev_tag).valid;
253 if tag_match(tag_prev, complete_in) then
254 tag_prev.valid := '0';
256 serial_stall <= tag_prev.valid;
259 control1 : process(all)
260 variable valid_tmp : std_ulogic;
263 valid_tmp := valid_in and not flush_in;
266 gpr_write_valid <= '0';
267 cr_write_valid <= '0';
271 -- Handle debugger stop
272 stopped_out <= stop_mark_in and not serial_stall;
274 -- Don't let it go out if there are GPR or CR hazards
275 -- or we are waiting for the previous instruction to complete
276 if (gpr_tag_stall or cr_tag_stall or ov_tag_stall or
277 (serialize and serial_stall)) = '1' then
281 gpr_write_valid <= gpr_write_valid_in and valid_tmp;
282 cr_write_valid <= cr_write_in and valid_tmp;
283 ov_write_valid <= ov_write_in and valid_tmp;
286 valid_out <= valid_tmp;