mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-28 20:41:15 +00:00
Handle the CR as a single field with per nibble enables. Forward any writes in the same cycle. If this proves to be an issue for timing, we may want to revisit this in the future. For now, it keeps things simple. Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
90 lines
2.2 KiB
VHDL
90 lines
2.2 KiB
VHDL
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
|
|
library work;
|
|
use work.common.all;
|
|
|
|
entity writeback is
|
|
port (
|
|
clk : in std_ulogic;
|
|
|
|
e_in : in Execute2ToWritebackType;
|
|
l_in : in Loadstore2ToWritebackType;
|
|
m_in : in MultiplyToWritebackType;
|
|
|
|
w_out : out WritebackToRegisterFileType;
|
|
c_out : out WritebackToCrFileType;
|
|
|
|
complete_out : out std_ulogic
|
|
);
|
|
end entity writeback;
|
|
|
|
architecture behaviour of writeback is
|
|
signal e : Execute2ToWritebackType;
|
|
signal l : Loadstore2ToWritebackType;
|
|
signal m : MultiplyToWritebackType;
|
|
signal w_tmp : WritebackToRegisterFileType;
|
|
signal c_tmp : WritebackToCrFileType;
|
|
begin
|
|
writeback_0: process(clk)
|
|
begin
|
|
if rising_edge(clk) then
|
|
e <= e_in;
|
|
l <= l_in;
|
|
m <= m_in;
|
|
end if;
|
|
end process;
|
|
|
|
w_out <= w_tmp;
|
|
c_out <= c_tmp;
|
|
|
|
complete_out <= '1' when e.valid or l.valid or m.valid else '0';
|
|
|
|
writeback_1: process(all)
|
|
begin
|
|
--assert (unsigned(w.valid) + unsigned(l.valid) + unsigned(m.valid)) <= 1;
|
|
--assert not(w.write_enable = '1' and l.write_enable = '1');
|
|
|
|
w_tmp <= WritebackToRegisterFileInit;
|
|
c_tmp <= WritebackToCrFileInit;
|
|
|
|
if e.valid = '1' then
|
|
if e.write_enable = '1' then
|
|
w_tmp.write_reg <= e.write_reg;
|
|
w_tmp.write_data <= e.write_data;
|
|
w_tmp.write_enable <= '1';
|
|
end if;
|
|
|
|
if e.write_cr_enable = '1' then
|
|
c_tmp.write_cr_enable <= '1';
|
|
c_tmp.write_cr_mask <= e.write_cr_mask;
|
|
c_tmp.write_cr_data <= e.write_cr_data;
|
|
end if;
|
|
end if;
|
|
|
|
if l.valid = '1' and l.write_enable = '1' then
|
|
w_tmp.write_reg <= l.write_reg;
|
|
w_tmp.write_data <= l.write_data;
|
|
w_tmp.write_enable <= '1';
|
|
end if;
|
|
if l.valid = '1' and l.write_enable2 = '1' then
|
|
w_tmp.write_reg2 <= l.write_reg2;
|
|
w_tmp.write_data2 <= l.write_data2;
|
|
w_tmp.write_enable2 <= '1';
|
|
end if;
|
|
|
|
if m.valid = '1' then
|
|
if m.write_reg_enable = '1' then
|
|
w_tmp.write_enable <= '1';
|
|
w_tmp.write_reg <= m.write_reg_nr;
|
|
w_tmp.write_data <= m.write_reg_data;
|
|
end if;
|
|
if m.write_cr_enable = '1' then
|
|
c_tmp.write_cr_enable <= '1';
|
|
c_tmp.write_cr_mask <= m.write_cr_mask;
|
|
c_tmp.write_cr_data <= m.write_cr_data;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
end;
|