Exit if we try to write more than one GPR or CR in a cycle
[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
8 entity writeback is
9 port (
10 clk : in std_ulogic;
11
12 e_in : in Execute2ToWritebackType;
13 l_in : in Loadstore2ToWritebackType;
14 m_in : in MultiplyToWritebackType;
15
16 w_out : out WritebackToRegisterFileType;
17 c_out : out WritebackToCrFileType;
18
19 complete_out : out std_ulogic
20 );
21 end entity writeback;
22
23 architecture behaviour of writeback is
24 type reg_internal_type is record
25 complete : std_ulogic;
26 end record;
27 type reg_type is record
28 w : WritebackToRegisterFileType;
29 c : WritebackToCrFileType;
30 end record;
31 signal r, rin : reg_type;
32 signal r_int, rin_int : reg_internal_type;
33 begin
34 writeback_0: process(clk)
35 begin
36 if rising_edge(clk) then
37 r <= rin;
38 r_int <= rin_int;
39 end if;
40 end process;
41
42 writeback_1: process(all)
43 variable x: std_ulogic_vector(0 downto 0);
44 variable y: std_ulogic_vector(0 downto 0);
45 variable z: std_ulogic_vector(0 downto 0);
46 variable v : reg_type;
47 variable v_int : reg_internal_type;
48 begin
49 v := r;
50 v_int := r_int;
51
52 x := "" & e_in.valid;
53 y := "" & l_in.valid;
54 z := "" & m_in.valid;
55 assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) + to_integer(unsigned(z))) <= 1 severity failure;
56
57 x := "" & e_in.write_enable;
58 y := "" & l_in.write_enable;
59 z := "" & m_in.write_reg_enable;
60 assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) + to_integer(unsigned(z))) <= 1 severity failure;
61
62 assert not(e_in.write_cr_enable = '1' and m_in.write_cr_enable = '1');
63
64 v.w := WritebackToRegisterFileInit;
65 v.c := WritebackToCrFileInit;
66
67 v_int.complete := '0';
68 if e_in.valid = '1' or l_in.valid = '1' or m_in.valid = '1' then
69 v_int.complete := '1';
70 end if;
71
72 if e_in.write_enable = '1' then
73 v.w.write_reg := e_in.write_reg;
74 v.w.write_data := e_in.write_data;
75 v.w.write_enable := '1';
76 end if;
77
78 if e_in.write_cr_enable = '1' then
79 v.c.write_cr_enable := '1';
80 v.c.write_cr_mask := e_in.write_cr_mask;
81 v.c.write_cr_data := e_in.write_cr_data;
82 end if;
83
84 if l_in.write_enable = '1' then
85 v.w.write_reg := l_in.write_reg;
86 v.w.write_data := l_in.write_data;
87 v.w.write_enable := '1';
88 end if;
89
90 if m_in.write_reg_enable = '1' then
91 v.w.write_enable := '1';
92 v.w.write_reg := m_in.write_reg_nr;
93 v.w.write_data := m_in.write_reg_data;
94 end if;
95
96 if m_in.write_cr_enable = '1' then
97 v.c.write_cr_enable := '1';
98 v.c.write_cr_mask := m_in.write_cr_mask;
99 v.c.write_cr_data := m_in.write_cr_data;
100 end if;
101
102 -- Update registers
103 rin <= v;
104 rin_int <= v_int;
105
106 -- Update outputs
107 complete_out <= r_int.complete;
108 w_out <= r.w;
109 c_out <= r.c;
110 end process;
111 end;