wb_arbiter: Forward stall signals
[microwatt.git] / wishbone_arbiter.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3
4 library work;
5 use work.wishbone_types.all;
6
7 -- TODO: Use an array of master/slaves with parametric size
8 entity wishbone_arbiter is
9 port (clk : in std_ulogic;
10 rst : in std_ulogic;
11
12 wb1_in : in wishbone_master_out;
13 wb1_out : out wishbone_slave_out;
14
15 wb2_in : in wishbone_master_out;
16 wb2_out : out wishbone_slave_out;
17
18 wb3_in : in wishbone_master_out;
19 wb3_out : out wishbone_slave_out;
20
21 wb_out : out wishbone_master_out;
22 wb_in : in wishbone_slave_out
23 );
24 end wishbone_arbiter;
25
26 architecture behave of wishbone_arbiter is
27 type wishbone_arbiter_state_t is (IDLE, WB1_BUSY, WB2_BUSY, WB3_BUSY);
28 signal state : wishbone_arbiter_state_t := IDLE;
29 begin
30
31 wishbone_muxes: process(state, wb_in, wb1_in, wb2_in, wb3_in)
32 begin
33 -- Requests from masters are fully muxed
34 wb_out <= wb1_in when state = WB1_BUSY else
35 wb2_in when state = WB2_BUSY else
36 wb3_in when state = WB3_BUSY else
37 wishbone_master_out_init;
38
39 -- Responses from slave don't need to mux the data bus
40 wb1_out.dat <= wb_in.dat;
41 wb2_out.dat <= wb_in.dat;
42 wb3_out.dat <= wb_in.dat;
43 wb1_out.ack <= wb_in.ack when state = WB1_BUSY else '0';
44 wb2_out.ack <= wb_in.ack when state = WB2_BUSY else '0';
45 wb3_out.ack <= wb_in.ack when state = WB3_BUSY else '0';
46 wb1_out.stall <= wb_in.stall when state = WB1_BUSY else '1';
47 wb2_out.stall <= wb_in.stall when state = WB2_BUSY else '1';
48 wb3_out.stall <= wb_in.stall when state = WB3_BUSY else '1';
49 end process;
50
51 wishbone_arbiter_process: process(clk)
52 begin
53 if rising_edge(clk) then
54 if rst = '1' then
55 state <= IDLE;
56 else
57 case state is
58 when IDLE =>
59 if wb1_in.cyc = '1' then
60 state <= WB1_BUSY;
61 elsif wb2_in.cyc = '1' then
62 state <= WB2_BUSY;
63 elsif wb3_in.cyc = '1' then
64 state <= WB3_BUSY;
65 end if;
66 when WB1_BUSY =>
67 if wb1_in.cyc = '0' then
68 state <= IDLE;
69 end if;
70 when WB2_BUSY =>
71 if wb2_in.cyc = '0' then
72 state <= IDLE;
73 end if;
74 when WB3_BUSY =>
75 if wb3_in.cyc = '0' then
76 state <= IDLE;
77 end if;
78 end case;
79 end if;
80 end if;
81 end process;
82 end behave;