core_debug: Stop logging 256 cycles after trigger
[microwatt.git] / writeback.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 library work;
6 use work.common.all;
7 use work.crhelpers.all;
8
9 entity writeback is
10 port (
11 clk : in std_ulogic;
12
13 e_in : in Execute1ToWritebackType;
14 l_in : in Loadstore1ToWritebackType;
15 fp_in : in FPUToWritebackType;
16
17 w_out : out WritebackToRegisterFileType;
18 c_out : out WritebackToCrFileType;
19
20 complete_out : out std_ulogic
21 );
22 end entity writeback;
23
24 architecture behaviour of writeback is
25 begin
26 writeback_0: process(clk)
27 variable x : std_ulogic_vector(0 downto 0);
28 variable y : std_ulogic_vector(0 downto 0);
29 variable w : std_ulogic_vector(0 downto 0);
30 begin
31 if rising_edge(clk) then
32 -- Do consistency checks only on the clock edge
33 x(0) := e_in.valid;
34 y(0) := l_in.valid;
35 w(0) := fp_in.valid;
36 assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) +
37 to_integer(unsigned(w))) <= 1 severity failure;
38
39 x(0) := e_in.write_enable or e_in.exc_write_enable;
40 y(0) := l_in.write_enable;
41 w(0) := fp_in.write_enable;
42 assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) +
43 to_integer(unsigned(w))) <= 1 severity failure;
44
45 w(0) := e_in.write_cr_enable;
46 x(0) := (e_in.write_enable and e_in.rc);
47 y(0) := fp_in.write_cr_enable;
48 assert (to_integer(unsigned(w)) + to_integer(unsigned(x)) +
49 to_integer(unsigned(y))) <= 1 severity failure;
50 end if;
51 end process;
52
53 writeback_1: process(all)
54 variable cf: std_ulogic_vector(3 downto 0);
55 variable zero : std_ulogic;
56 variable sign : std_ulogic;
57 variable scf : std_ulogic_vector(3 downto 0);
58 begin
59 w_out <= WritebackToRegisterFileInit;
60 c_out <= WritebackToCrFileInit;
61
62 complete_out <= '0';
63 if e_in.valid = '1' or l_in.valid = '1' or fp_in.valid = '1' then
64 complete_out <= '1';
65 end if;
66
67 if e_in.exc_write_enable = '1' then
68 w_out.write_reg <= e_in.exc_write_reg;
69 w_out.write_data <= e_in.exc_write_data;
70 w_out.write_enable <= '1';
71 else
72 if e_in.write_enable = '1' then
73 w_out.write_reg <= e_in.write_reg;
74 w_out.write_data <= e_in.write_data;
75 w_out.write_enable <= '1';
76 end if;
77
78 if e_in.write_cr_enable = '1' then
79 c_out.write_cr_enable <= '1';
80 c_out.write_cr_mask <= e_in.write_cr_mask;
81 c_out.write_cr_data <= e_in.write_cr_data;
82 end if;
83
84 if e_in.write_xerc_enable = '1' then
85 c_out.write_xerc_enable <= '1';
86 c_out.write_xerc_data <= e_in.xerc;
87 end if;
88
89 if fp_in.write_enable = '1' then
90 w_out.write_reg <= fp_in.write_reg;
91 w_out.write_data <= fp_in.write_data;
92 w_out.write_enable <= '1';
93 end if;
94
95 if fp_in.write_cr_enable = '1' then
96 c_out.write_cr_enable <= '1';
97 c_out.write_cr_mask <= fp_in.write_cr_mask;
98 c_out.write_cr_data <= fp_in.write_cr_data;
99 end if;
100
101 if l_in.write_enable = '1' then
102 w_out.write_reg <= l_in.write_reg;
103 w_out.write_data <= l_in.write_data;
104 w_out.write_enable <= '1';
105 end if;
106
107 if l_in.rc = '1' then
108 -- st*cx. instructions
109 scf(3) := '0';
110 scf(2) := '0';
111 scf(1) := l_in.store_done;
112 scf(0) := l_in.xerc.so;
113 c_out.write_cr_enable <= '1';
114 c_out.write_cr_mask <= num_to_fxm(0);
115 c_out.write_cr_data(31 downto 28) <= scf;
116 end if;
117
118 -- Perform CR0 update for RC forms
119 -- Note that loads never have a form with an RC bit, therefore this can test e_in.write_data
120 if e_in.rc = '1' and e_in.write_enable = '1' then
121 zero := not (or e_in.write_data(31 downto 0));
122 if e_in.mode_32bit = '0' then
123 sign := e_in.write_data(63);
124 zero := zero and not (or e_in.write_data(63 downto 32));
125 else
126 sign := e_in.write_data(31);
127 end if;
128 c_out.write_cr_enable <= '1';
129 c_out.write_cr_mask <= num_to_fxm(0);
130 cf(3) := sign;
131 cf(2) := not sign and not zero;
132 cf(1) := zero;
133 cf(0) := e_in.xerc.so;
134 c_out.write_cr_data(31 downto 28) <= cf;
135 end if;
136 end if;
137 end process;
138 end;