Merge pull request #127 from tomtor/CR-PR
[microwatt.git] / cr_hazard.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4
5 entity cr_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 cr_read_in : in std_ulogic;
14 cr_write_in : in std_ulogic;
15
16 stall_out : out std_ulogic
17 );
18 end entity cr_hazard;
19 architecture behaviour of cr_hazard is
20 type pipeline_entry_type is record
21 valid : std_ulogic;
22 end record;
23 constant pipeline_entry_init : pipeline_entry_type := (valid => '0');
24
25 type pipeline_t is array(0 to PIPELINE_DEPTH-1) of pipeline_entry_type;
26 constant pipeline_t_init : pipeline_t := (others => pipeline_entry_init);
27
28 signal r, rin : pipeline_t := pipeline_t_init;
29 begin
30 cr_hazard0: process(clk)
31 begin
32 if rising_edge(clk) then
33 if stall_in = '0' then
34 r <= rin;
35 end if;
36 end if;
37 end process;
38
39 cr_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 = cr_read_in) then
47 stall_out <= '1';
48 end if;
49 end loop;
50
51 v(0).valid := cr_write_in;
52 loop_1: for i in 0 to PIPELINE_DEPTH-2 loop
53 -- propagate to next slot
54 v(i+1) := r(i);
55 end loop;
56
57 -- asynchronous output
58 if cr_read_in = '0' then
59 stall_out <= '0';
60 end if;
61
62 -- update registers
63 rin <= v;
64
65 end process;
66 end;