2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
7 use work.crhelpers.all;
14 e_in : in Execute1ToWritebackType;
15 l_in : in Loadstore1ToWritebackType;
16 fp_in : in FPUToWritebackType;
18 w_out : out WritebackToRegisterFileType;
19 c_out : out WritebackToCrFileType;
20 f_out : out WritebackToFetch1Type;
22 flush_out : out std_ulogic;
23 interrupt_out: out std_ulogic;
24 complete_out : out instr_tag_t
28 architecture behaviour of writeback is
29 type irq_state_t is (WRITE_SRR0, WRITE_SRR1);
31 type reg_type is record
33 srr1 : std_ulogic_vector(63 downto 0);
36 signal r, rin : reg_type;
39 writeback_0: process(clk)
40 variable x : std_ulogic_vector(0 downto 0);
41 variable y : std_ulogic_vector(0 downto 0);
42 variable w : std_ulogic_vector(0 downto 0);
44 if rising_edge(clk) then
46 r.state <= WRITE_SRR0;
47 r.srr1 <= (others => '0');
52 -- Do consistency checks only on the clock edge
56 assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) +
57 to_integer(unsigned(w))) <= 1 severity failure;
59 x(0) := e_in.write_enable;
60 y(0) := l_in.write_enable;
61 w(0) := fp_in.write_enable;
62 assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) +
63 to_integer(unsigned(w))) <= 1 severity failure;
65 w(0) := e_in.write_cr_enable;
66 x(0) := (e_in.write_enable and e_in.rc);
67 y(0) := fp_in.write_cr_enable;
68 assert (to_integer(unsigned(w)) + to_integer(unsigned(x)) +
69 to_integer(unsigned(y))) <= 1 severity failure;
71 assert not (e_in.valid = '1' and e_in.instr_tag.valid = '0') severity failure;
72 assert not (l_in.valid = '1' and l_in.instr_tag.valid = '0') severity failure;
73 assert not (fp_in.valid = '1' and fp_in.instr_tag.valid = '0') severity failure;
77 writeback_1: process(all)
78 variable v : reg_type;
79 variable f : WritebackToFetch1Type;
80 variable cf: std_ulogic_vector(3 downto 0);
81 variable zero : std_ulogic;
82 variable sign : std_ulogic;
83 variable scf : std_ulogic_vector(3 downto 0);
84 variable vec : integer range 0 to 16#fff#;
86 w_out <= WritebackToRegisterFileInit;
87 c_out <= WritebackToCrFileInit;
88 f := WritebackToFetch1Init;
93 complete_out <= instr_tag_init;
94 if e_in.valid = '1' then
95 complete_out <= e_in.instr_tag;
96 elsif l_in.valid = '1' then
97 complete_out <= l_in.instr_tag;
98 elsif fp_in.valid = '1' then
99 complete_out <= fp_in.instr_tag;
102 if r.state = WRITE_SRR1 then
103 w_out.write_reg <= fast_spr_num(SPR_SRR1);
104 w_out.write_data <= r.srr1;
105 w_out.write_enable <= '1';
106 interrupt_out <= '1';
107 v.state := WRITE_SRR0;
109 elsif e_in.interrupt = '1' then
110 w_out.write_reg <= fast_spr_num(SPR_SRR0);
111 w_out.write_data <= e_in.last_nia;
112 w_out.write_enable <= '1';
113 v.state := WRITE_SRR1;
114 v.srr1(63 downto 32) := e_in.msr(63 downto 32);
115 v.srr1(31 downto 0) := e_in.msr(31 downto 0) or e_in.srr1;
116 vec := e_in.intr_vec;
118 elsif l_in.interrupt = '1' then
119 w_out.write_reg <= fast_spr_num(SPR_SRR0);
120 w_out.write_data <= l_in.srr0;
121 w_out.write_enable <= '1';
122 v.state := WRITE_SRR1;
123 v.srr1(63 downto 32) := e_in.msr(63 downto 32);
124 v.srr1(31 downto 0) := e_in.msr(31 downto 0) or l_in.srr1;
125 vec := l_in.intr_vec;
128 if e_in.write_enable = '1' then
129 w_out.write_reg <= e_in.write_reg;
130 w_out.write_data <= e_in.write_data;
131 w_out.write_enable <= '1';
134 if e_in.write_cr_enable = '1' then
135 c_out.write_cr_enable <= '1';
136 c_out.write_cr_mask <= e_in.write_cr_mask;
137 c_out.write_cr_data <= e_in.write_cr_data;
140 if e_in.write_xerc_enable = '1' then
141 c_out.write_xerc_enable <= '1';
142 c_out.write_xerc_data <= e_in.xerc;
145 if fp_in.write_enable = '1' then
146 w_out.write_reg <= fp_in.write_reg;
147 w_out.write_data <= fp_in.write_data;
148 w_out.write_enable <= '1';
151 if fp_in.write_cr_enable = '1' then
152 c_out.write_cr_enable <= '1';
153 c_out.write_cr_mask <= fp_in.write_cr_mask;
154 c_out.write_cr_data <= fp_in.write_cr_data;
157 if l_in.write_enable = '1' then
158 w_out.write_reg <= l_in.write_reg;
159 w_out.write_data <= l_in.write_data;
160 w_out.write_enable <= '1';
163 if l_in.rc = '1' then
164 -- st*cx. instructions
167 scf(1) := l_in.store_done;
168 scf(0) := l_in.xerc.so;
169 c_out.write_cr_enable <= '1';
170 c_out.write_cr_mask <= num_to_fxm(0);
171 c_out.write_cr_data(31 downto 28) <= scf;
174 -- Perform CR0 update for RC forms
175 -- Note that loads never have a form with an RC bit, therefore this can test e_in.write_data
176 if e_in.rc = '1' and e_in.write_enable = '1' then
177 zero := not (or e_in.write_data(31 downto 0));
178 if e_in.mode_32bit = '0' then
179 sign := e_in.write_data(63);
180 zero := zero and not (or e_in.write_data(63 downto 32));
182 sign := e_in.write_data(31);
184 c_out.write_cr_enable <= '1';
185 c_out.write_cr_mask <= num_to_fxm(0);
187 cf(2) := not sign and not zero;
189 cf(0) := e_in.xerc.so;
190 c_out.write_cr_data(31 downto 28) <= cf;
195 f.redirect := e_in.redirect;
196 f.br_nia := e_in.last_nia;
197 f.br_last := e_in.br_last;
198 f.br_taken := e_in.br_taken;
199 if e_in.interrupt = '1' or l_in.interrupt = '1' then
202 f.redirect_nia := std_ulogic_vector(to_unsigned(vec, 64));
205 -- XXX need an interrupt LE bit here, e.g. from LPCR
209 if e_in.abs_br = '1' then
210 f.redirect_nia := e_in.br_offset;
212 f.redirect_nia := std_ulogic_vector(unsigned(e_in.last_nia) + unsigned(e_in.br_offset));
214 -- send MSR[IR], ~MSR[PR], ~MSR[LE] and ~MSR[SF] up to fetch1
215 f.virt_mode := e_in.redir_mode(3);
216 f.priv_mode := e_in.redir_mode(2);
217 f.big_endian := e_in.redir_mode(1);
218 f.mode_32bit := e_in.redir_mode(0);
222 flush_out <= f_out.redirect;