Use a 3 way WB arbiter and cleanup fpga toplevel

The 3rd master is currently unused, it will host the WB debug module.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
pull/69/head
Benjamin Herrenschmidt 5 years ago
parent 6571b13308
commit 1206dfe18c

@ -35,6 +35,8 @@ architecture behaviour of soc is
signal wishbone_dcore_out : wishbone_master_out; signal wishbone_dcore_out : wishbone_master_out;
signal wishbone_icore_in : wishbone_slave_out; signal wishbone_icore_in : wishbone_slave_out;
signal wishbone_icore_out : wishbone_master_out; signal wishbone_icore_out : wishbone_master_out;
signal wishbone_debug_in : wishbone_slave_out;
signal wishbone_debug_out : wishbone_master_out;


-- Wishbone master (output of arbiter): -- Wishbone master (output of arbiter):
signal wb_master_in : wishbone_slave_out; signal wb_master_in : wishbone_slave_out;
@ -75,16 +77,17 @@ begin
-- Wishbone bus master arbiter & mux -- Wishbone bus master arbiter & mux
wishbone_arbiter_0: entity work.wishbone_arbiter wishbone_arbiter_0: entity work.wishbone_arbiter
port map( port map(
clk => system_clk, clk => system_clk, rst => rst,
rst => rst, wb1_in => wishbone_dcore_out, wb1_out => wishbone_dcore_in,
wb1_in => wishbone_dcore_out, wb2_in => wishbone_icore_out, wb2_out => wishbone_icore_in,
wb1_out => wishbone_dcore_in, wb3_in => wishbone_debug_out, wb3_out => wishbone_debug_in,
wb2_in => wishbone_icore_out, wb_out => wb_master_out, wb_in => wb_master_in
wb2_out => wishbone_icore_in,
wb_out => wb_master_out,
wb_in => wb_master_in
); );


-- Dummy wishbone debug module
wishbone_debug_out.cyc <= '0';
wishbone_debug_out.stb <= '0';

-- Wishbone slaves address decoder & mux -- Wishbone slaves address decoder & mux
slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out) slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out)
-- Selected slave -- Selected slave

@ -4,54 +4,76 @@ use ieee.std_logic_1164.all;
library work; library work;
use work.wishbone_types.all; use work.wishbone_types.all;


-- TODO: Use an array of master/slaves with parametric size
entity wishbone_arbiter is entity wishbone_arbiter is
port ( port (clk : in std_ulogic;
clk : in std_ulogic; rst : in std_ulogic;
rst : in std_ulogic;


wb1_in : in wishbone_master_out; wb1_in : in wishbone_master_out;
wb1_out : out wishbone_slave_out; wb1_out : out wishbone_slave_out;


wb2_in : in wishbone_master_out; wb2_in : in wishbone_master_out;
wb2_out : out wishbone_slave_out; wb2_out : out wishbone_slave_out;


wb_out : out wishbone_master_out; wb3_in : in wishbone_master_out;
wb_in : in wishbone_slave_out wb3_out : out wishbone_slave_out;
);
wb_out : out wishbone_master_out;
wb_in : in wishbone_slave_out
);
end wishbone_arbiter; end wishbone_arbiter;


architecture behave of wishbone_arbiter is architecture behave of wishbone_arbiter is
type wishbone_arbiter_state_t is (IDLE, WB1_BUSY, WB2_BUSY); type wishbone_arbiter_state_t is (IDLE, WB1_BUSY, WB2_BUSY, WB3_BUSY);
signal state : wishbone_arbiter_state_t := IDLE; signal state : wishbone_arbiter_state_t := IDLE;
begin begin
wb1_out <= wb_in when state = WB1_BUSY else wishbone_slave_out_init;
wb2_out <= wb_in when state = WB2_BUSY else wishbone_slave_out_init;


wb_out <= wb1_in when state = WB1_BUSY else wb2_in when state = WB2_BUSY else wishbone_master_out_init; wishbone_muxes: process(state, wb_in, wb1_in, wb2_in, wb3_in)
begin
-- Requests from masters are fully muxed
wb_out <= wb1_in when state = WB1_BUSY else
wb2_in when state = WB2_BUSY else
wb3_in when state = WB3_BUSY else
wishbone_master_out_init;

-- Responses from slave don't need to mux the data bus
wb1_out.dat <= wb_in.dat;
wb2_out.dat <= wb_in.dat;
wb3_out.dat <= wb_in.dat;
wb1_out.ack <= wb_in.ack when state = WB1_BUSY else '0';
wb2_out.ack <= wb_in.ack when state = WB2_BUSY else '0';
wb3_out.ack <= wb_in.ack when state = WB3_BUSY else '0';
end process;


wishbone_arbiter_process: process(clk) wishbone_arbiter_process: process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if rst = '1' then if rst = '1' then
state <= IDLE; state <= IDLE;
else else
case state is case state is
when IDLE => when IDLE =>
if wb1_in.cyc = '1' then if wb1_in.cyc = '1' then
state <= WB1_BUSY; state <= WB1_BUSY;
elsif wb2_in.cyc = '1' then elsif wb2_in.cyc = '1' then
state <= WB2_BUSY; state <= WB2_BUSY;
end if; elsif wb3_in.cyc = '1' then
when WB1_BUSY => state <= WB3_BUSY;
if wb1_in.cyc = '0' then end if;
state <= IDLE; when WB1_BUSY =>
end if; if wb1_in.cyc = '0' then
when WB2_BUSY => state <= IDLE;
if wb2_in.cyc = '0' then end if;
state <= IDLE; when WB2_BUSY =>
end if; if wb2_in.cyc = '0' then
end case; state <= IDLE;
end if; end if;
end if; when WB3_BUSY =>
if wb3_in.cyc = '0' then
state <= IDLE;
end if;
end case;
end if;
end if;
end process; end process;
end behave; end behave;

Loading…
Cancel
Save