2 use ieee.std_logic_1164.all;
9 PIPELINE_DEPTH : natural := 2
15 complete_in : in std_ulogic;
16 valid_in : in std_ulogic;
17 flush_in : in std_ulogic;
18 stall_in : in std_ulogic;
19 sgl_pipe_in : in std_ulogic;
20 stop_mark_in : in std_ulogic;
22 gpr_write_valid_in : in std_ulogic;
23 gpr_write_in : in gspr_index_t;
25 gpr_a_read_valid_in : in std_ulogic;
26 gpr_a_read_in : in gspr_index_t;
28 gpr_b_read_valid_in : in std_ulogic;
29 gpr_b_read_in : in gspr_index_t;
31 gpr_c_read_valid_in : in std_ulogic;
32 gpr_c_read_in : in gpr_index_t;
34 cr_read_in : in std_ulogic;
35 cr_write_in : in std_ulogic;
37 valid_out : out std_ulogic;
38 stall_out : out std_ulogic;
39 stopped_out : out std_ulogic
43 architecture rtl of control is
44 type state_type is (IDLE, WAIT_FOR_PREV_TO_COMPLETE, WAIT_FOR_CURR_TO_COMPLETE);
46 type reg_internal_type is record
48 outstanding : integer range -1 to PIPELINE_DEPTH+2;
50 constant reg_internal_init : reg_internal_type := (state => IDLE, outstanding => 0);
52 signal r_int, rin_int : reg_internal_type := reg_internal_init;
54 signal stall_a_out : std_ulogic;
55 signal stall_b_out : std_ulogic;
56 signal stall_c_out : std_ulogic;
57 signal cr_stall_out : std_ulogic;
59 signal gpr_write_valid : std_ulogic := '0';
60 signal cr_write_valid : std_ulogic := '0';
62 signal gpr_c_read_in_fmt : std_ulogic_vector(5 downto 0);
64 gpr_hazard0: entity work.gpr_hazard
66 PIPELINE_DEPTH => PIPELINE_DEPTH
72 gpr_write_valid_in => gpr_write_valid,
73 gpr_write_in => gpr_write_in,
74 gpr_read_valid_in => gpr_a_read_valid_in,
75 gpr_read_in => gpr_a_read_in,
77 stall_out => stall_a_out
80 gpr_hazard1: entity work.gpr_hazard
82 PIPELINE_DEPTH => PIPELINE_DEPTH
88 gpr_write_valid_in => gpr_write_valid,
89 gpr_write_in => gpr_write_in,
90 gpr_read_valid_in => gpr_b_read_valid_in,
91 gpr_read_in => gpr_b_read_in,
93 stall_out => stall_b_out
96 gpr_c_read_in_fmt <= "0" & gpr_c_read_in;
98 gpr_hazard2: entity work.gpr_hazard
100 PIPELINE_DEPTH => PIPELINE_DEPTH
104 stall_in => stall_in,
106 gpr_write_valid_in => gpr_write_valid,
107 gpr_write_in => gpr_write_in,
108 gpr_read_valid_in => gpr_c_read_valid_in,
109 gpr_read_in => gpr_c_read_in_fmt,
111 stall_out => stall_c_out
114 cr_hazard0: entity work.cr_hazard
116 PIPELINE_DEPTH => PIPELINE_DEPTH
120 stall_in => stall_in,
122 cr_read_in => cr_read_in,
123 cr_write_in => cr_write_valid,
125 stall_out => cr_stall_out
128 control0: process(clk)
130 if rising_edge(clk) then
131 assert r_int.outstanding >= 0 and r_int.outstanding <= (PIPELINE_DEPTH+1) report "Outstanding bad " & integer'image(r_int.outstanding) severity failure;
136 control1 : process(all)
137 variable v_int : reg_internal_type;
138 variable valid_tmp : std_ulogic;
139 variable stall_tmp : std_ulogic;
144 valid_tmp := valid_in and not flush_in and not stall_in;
145 stall_tmp := stall_in;
147 if complete_in = '1' then
148 v_int.outstanding := r_int.outstanding - 1;
151 -- Handle debugger stop
153 if stop_mark_in = '1' and v_int.outstanding = 0 then
157 -- state machine to handle instructions that must be single
158 -- through the pipeline.
161 if valid_tmp = '1' then
162 if (sgl_pipe_in = '1') then
163 if v_int.outstanding /= 0 then
164 v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
167 -- send insn out and wait on it to complete
168 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
171 -- let it go out if there are no GPR hazards
172 stall_tmp := stall_a_out or stall_b_out or stall_c_out or cr_stall_out;
176 when WAIT_FOR_PREV_TO_COMPLETE =>
177 if v_int.outstanding = 0 then
178 -- send insn out and wait on it to complete
179 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
184 when WAIT_FOR_CURR_TO_COMPLETE =>
185 if v_int.outstanding = 0 then
187 -- XXX Don't replicate this
188 if valid_tmp = '1' then
189 if (sgl_pipe_in = '1') then
190 if v_int.outstanding /= 0 then
191 v_int.state := WAIT_FOR_PREV_TO_COMPLETE;
194 -- send insn out and wait on it to complete
195 v_int.state := WAIT_FOR_CURR_TO_COMPLETE;
198 -- let it go out if there are no GPR hazards
199 stall_tmp := stall_a_out or stall_b_out or stall_c_out or cr_stall_out;
207 if stall_tmp = '1' then
211 if valid_tmp = '1' then
212 v_int.outstanding := v_int.outstanding + 1;
213 gpr_write_valid <= gpr_write_valid_in;
214 cr_write_valid <= cr_write_in;
216 gpr_write_valid <= '0';
217 cr_write_valid <= '0';
222 v_int.outstanding := 0;
227 valid_out <= valid_tmp;
228 stall_out <= stall_tmp;