Add a divider unit and a testbench for it
[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 d_in : in DividerToWritebackType;
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_1: process(all)
27 variable x : std_ulogic_vector(0 downto 0);
28 variable y : std_ulogic_vector(0 downto 0);
29 variable z : std_ulogic_vector(0 downto 0);
30 variable w : std_ulogic_vector(0 downto 0);
31 begin
32 x := "" & e_in.valid;
33 y := "" & l_in.valid;
34 z := "" & m_in.valid;
35 w := "" & d_in.valid;
36 assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) + to_integer(unsigned(z)) + to_integer(unsigned(w))) <= 1 severity failure;
37
38 x := "" & e_in.write_enable;
39 y := "" & l_in.write_enable;
40 z := "" & m_in.write_reg_enable;
41 w := "" & d_in.write_reg_enable;
42 assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) + to_integer(unsigned(z)) + to_integer(unsigned(w))) <= 1 severity failure;
43
44 x := "" & e_in.write_cr_enable;
45 y := "" & m_in.write_cr_enable;
46 z := "" & d_in.write_cr_enable;
47 assert (to_integer(unsigned(x)) + to_integer(unsigned(y)) + to_integer(unsigned(z))) <= 1 severity failure;
48
49 w_out <= WritebackToRegisterFileInit;
50 c_out <= WritebackToCrFileInit;
51
52 complete_out <= '0';
53 if e_in.valid = '1' or l_in.valid = '1' or m_in.valid = '1' or d_in.valid = '1' then
54 complete_out <= '1';
55 end if;
56
57 if e_in.write_enable = '1' then
58 w_out.write_reg <= e_in.write_reg;
59 w_out.write_data <= e_in.write_data;
60 w_out.write_enable <= '1';
61 end if;
62
63 if e_in.write_cr_enable = '1' then
64 c_out.write_cr_enable <= '1';
65 c_out.write_cr_mask <= e_in.write_cr_mask;
66 c_out.write_cr_data <= e_in.write_cr_data;
67 end if;
68
69 if l_in.write_enable = '1' then
70 w_out.write_reg <= l_in.write_reg;
71 w_out.write_data <= l_in.write_data;
72 w_out.write_enable <= '1';
73 end if;
74
75 if m_in.write_reg_enable = '1' then
76 w_out.write_enable <= '1';
77 w_out.write_reg <= m_in.write_reg_nr;
78 w_out.write_data <= m_in.write_reg_data;
79 end if;
80
81 if m_in.write_cr_enable = '1' then
82 c_out.write_cr_enable <= '1';
83 c_out.write_cr_mask <= m_in.write_cr_mask;
84 c_out.write_cr_data <= m_in.write_cr_data;
85 end if;
86
87 if d_in.write_reg_enable = '1' then
88 w_out.write_enable <= '1';
89 w_out.write_reg <= d_in.write_reg_nr;
90 w_out.write_data <= d_in.write_reg_data;
91 end if;
92
93 if d_in.write_cr_enable = '1' then
94 c_out.write_cr_enable <= '1';
95 c_out.write_cr_mask <= d_in.write_cr_mask;
96 c_out.write_cr_data <= d_in.write_cr_data;
97 end if;
98 end process;
99 end;