Merge pull request #180 from antonblanchard/Makefile-rework
[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_ulogic;
11 stall_in : in std_ulogic;
12
13 gpr_write_valid_in : in std_ulogic;
14 gpr_write_in : in std_ulogic_vector(5 downto 0);
15 bypass_avail : in std_ulogic;
16 gpr_read_valid_in : in std_ulogic;
17 gpr_read_in : in std_ulogic_vector(5 downto 0);
18
19 stall_out : out std_ulogic;
20 use_bypass : out std_ulogic
21 );
22 end entity gpr_hazard;
23 architecture behaviour of gpr_hazard is
24 type pipeline_entry_type is record
25 valid : std_ulogic;
26 bypass : std_ulogic;
27 gpr : std_ulogic_vector(5 downto 0);
28 end record;
29 constant pipeline_entry_init : pipeline_entry_type := (valid => '0', bypass => '0', gpr => (others => '0'));
30
31 type pipeline_t is array(0 to PIPELINE_DEPTH-1) of pipeline_entry_type;
32 constant pipeline_t_init : pipeline_t := (others => pipeline_entry_init);
33
34 signal r, rin : pipeline_t := pipeline_t_init;
35 begin
36 gpr_hazard0: process(clk)
37 begin
38 if rising_edge(clk) then
39 r <= rin;
40 end if;
41 end process;
42
43 gpr_hazard1: process(all)
44 variable v : pipeline_t;
45 begin
46 v := r;
47
48 stall_out <= '0';
49 use_bypass <= '0';
50 if gpr_read_valid_in = '1' then
51 if r(0).valid = '1' and r(0).gpr = gpr_read_in then
52 if r(0).bypass = '1' and stall_in = '0' then
53 use_bypass <= '1';
54 else
55 stall_out <= '1';
56 end if;
57 end if;
58 loop_0: for i in 1 to PIPELINE_DEPTH-1 loop
59 if r(i).valid = '1' and r(i).gpr = gpr_read_in then
60 if r(i).bypass = '1' then
61 use_bypass <= '1';
62 else
63 stall_out <= '1';
64 end if;
65 end if;
66 end loop;
67 end if;
68
69 if stall_in = '0' then
70 v(0).valid := gpr_write_valid_in;
71 v(0).bypass := bypass_avail;
72 v(0).gpr := gpr_write_in;
73 loop_1: for i in 1 to PIPELINE_DEPTH-1 loop
74 -- propagate to next slot
75 v(i).valid := r(i-1).valid;
76 v(i).bypass := r(i-1).bypass;
77 v(i).gpr := r(i-1).gpr;
78 end loop;
79
80 else
81 -- stage 0 stalled, so stage 1 becomes empty
82 loop_1b: for i in 1 to PIPELINE_DEPTH-1 loop
83 -- propagate to next slot
84 if i = 1 then
85 v(i).valid := '0';
86 else
87 v(i).valid := r(i-1).valid;
88 v(i).bypass := r(i-1).bypass;
89 v(i).gpr := r(i-1).gpr;
90 end if;
91 end loop;
92 end if;
93
94 -- update registers
95 rin <= v;
96
97 end process;
98 end;