decode1: Mark ALU ops using carry as pipelined
[microwatt.git] / gpr_hazard.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 entity gpr_hazard is
6 generic (
7 PIPELINE_DEPTH : natural := 2
8 );
9 port(
10 clk : in std_logic;
11
12 gpr_write_valid_in : in std_ulogic;
13 gpr_write_in : in std_ulogic_vector(4 downto 0);
14 gpr_read_valid_in : in std_ulogic;
15 gpr_read_in : in std_ulogic_vector(4 downto 0);
16
17 stall_out : out std_ulogic
18 );
19 end entity gpr_hazard;
20 architecture behaviour of gpr_hazard is
21 type pipeline_entry_type is record
22 valid : std_ulogic;
23 gpr : std_ulogic_vector(4 downto 0);
24 end record;
25 constant pipeline_entry_init : pipeline_entry_type := (valid => '0', gpr => (others => '0'));
26
27 type pipeline_t is array(0 to PIPELINE_DEPTH-1) of pipeline_entry_type;
28 constant pipeline_t_init : pipeline_t := (others => pipeline_entry_init);
29
30 signal r, rin : pipeline_t := pipeline_t_init;
31 begin
32 gpr_hazard0: process(clk)
33 begin
34 if rising_edge(clk) then
35 r <= rin;
36 end if;
37 end process;
38
39 gpr_hazard1: process(all)
40 variable v : pipeline_t;
41 begin
42 v := r;
43
44 stall_out <= '0';
45 loop_0: for i in 0 to PIPELINE_DEPTH-1 loop
46 if ((r(i).valid = gpr_read_valid_in) and r(i).gpr = gpr_read_in) then
47 stall_out <= '1';
48 end if;
49 end loop;
50
51 v(0).valid := gpr_write_valid_in;
52 v(0).gpr := gpr_write_in;
53 loop_1: for i in 0 to PIPELINE_DEPTH-2 loop
54 -- propagate to next slot
55 v(i+1) := r(i);
56 end loop;
57
58 -- asynchronous output
59 if gpr_read_valid_in = '0' then
60 stall_out <= '0';
61 end if;
62
63 -- update registers
64 rin <= v;
65
66 end process;
67 end;