wb_arbiter: Make arbiter size parametric
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 23 Oct 2019 03:28:12 +0000 (14:28 +1100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 30 Oct 2019 02:18:58 +0000 (13:18 +1100)
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
soc.vhdl
wishbone_arbiter.vhdl
wishbone_types.vhdl

index 6ed6bf745c4d22fdb04bbdd039305c7250bc1c5e..fb8a36d4f1619b0220e60f4a6cbfe7ae912019de 100644 (file)
--- a/soc.vhdl
+++ b/soc.vhdl
@@ -43,6 +43,12 @@ architecture behaviour of soc is
     signal wishbone_debug_in : wishbone_slave_out;
     signal wishbone_debug_out : wishbone_master_out;
 
+    -- Arbiter array (ghdl doesnt' support assigning the array
+    -- elements in the entity instantiation)
+    constant NUM_WB_MASTERS : positive := 3;
+    signal wb_masters_out : wishbone_master_out_vector(0 to NUM_WB_MASTERS-1);
+    signal wb_masters_in  : wishbone_slave_out_vector(0 to NUM_WB_MASTERS-1);
+
     -- Wishbone master (output of arbiter):
     signal wb_master_in : wishbone_slave_out;
     signal wb_master_out : wishbone_master_out;
@@ -96,13 +102,22 @@ begin
            );
 
     -- Wishbone bus master arbiter & mux
+    wb_masters_out <= (0 => wishbone_dcore_out,
+                      1 => wishbone_icore_out,
+                      2 => wishbone_debug_out);
+    wishbone_dcore_in <= wb_masters_in(0);
+    wishbone_icore_in <= wb_masters_in(1);
+    wishbone_debug_in <= wb_masters_in(2);
     wishbone_arbiter_0: entity work.wishbone_arbiter
+       generic map(
+           NUM_MASTERS => NUM_WB_MASTERS
+           )
        port map(
            clk => system_clk, rst => rst,
-           wb1_in => wishbone_dcore_out, wb1_out => wishbone_dcore_in,
-           wb2_in => wishbone_icore_out, wb2_out => wishbone_icore_in,
-           wb3_in => wishbone_debug_out, wb3_out => wishbone_debug_in,
-           wb_out => wb_master_out, wb_in => wb_master_in
+           wb_masters_in => wb_masters_out,
+           wb_masters_out => wb_masters_in,
+           wb_slave_out => wb_master_out,
+           wb_slave_in => wb_master_in
            );
 
     -- Wishbone slaves address decoder & mux
index b206df1561bcc60cf254a92609046d3ee2fa0483..63b3c4a4131283eb1af5a98db6dd4d2a475c0d03 100644 (file)
@@ -6,70 +6,55 @@ use work.wishbone_types.all;
 
 -- TODO: Use an array of master/slaves with parametric size
 entity wishbone_arbiter is
+    generic(
+       NUM_MASTERS : positive := 3
+       );
     port (clk     : in std_ulogic;
          rst     : in std_ulogic;
 
-         wb1_in  : in wishbone_master_out;
-         wb1_out : out wishbone_slave_out;
+         wb_masters_in  : in wishbone_master_out_vector(0 to NUM_MASTERS-1);
+         wb_masters_out : out wishbone_slave_out_vector(0 to NUM_MASTERS-1);
 
-         wb2_in  : in wishbone_master_out;
-         wb2_out : out wishbone_slave_out;
-
-         wb3_in  : in wishbone_master_out;
-         wb3_out : out wishbone_slave_out;
-
-         wb_out  : out wishbone_master_out;
-         wb_in   : in wishbone_slave_out
+         wb_slave_out  : out wishbone_master_out;
+         wb_slave_in   : in wishbone_slave_out
          );
 end wishbone_arbiter;
 
 architecture behave of wishbone_arbiter is
-    type wb_arb_master_t is (WB1, WB2, WB3);
+    subtype wb_arb_master_t is integer range 0 to NUM_MASTERS-1;
     signal candidate, selected : wb_arb_master_t;
 begin
 
-    wishbone_muxes: process(selected, wb_in, wb1_in, wb2_in, wb3_in)
+    wishbone_muxes: process(selected, wb_slave_in, wb_masters_in)
     begin
-       -- Requests from masters are fully muxed
-       wb_out <= wb1_in when selected = WB1 else
-                 wb2_in when selected = WB2 else
-                 wb3_in when selected = WB3;
-
-       -- 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 selected = WB1 else '0';
-       wb2_out.ack <= wb_in.ack when selected = WB2 else '0';
-       wb3_out.ack <= wb_in.ack when selected = WB3 else '0';
-       wb1_out.stall <= wb_in.stall when selected = WB1 else '1';
-       wb2_out.stall <= wb_in.stall when selected = WB2 else '1';
-       wb3_out.stall <= wb_in.stall when selected = WB3 else '1';
+       wb_slave_out <= wb_masters_in(selected);
+       for i in 0 to NUM_MASTERS-1 loop
+           wb_masters_out(i).dat <= wb_slave_in.dat;
+           wb_masters_out(i).ack <= wb_slave_in.ack when selected = i else '0';
+           wb_masters_out(i).stall <= wb_slave_in.stall when selected = i else '1';
+       end loop;
     end process;
 
     -- Candidate selection is dumb, priority order... we could
     -- instead consider some form of fairness but it's not really
     -- an issue at the moment.
     --
-    wishbone_candidate: process(wb1_in.cyc, wb2_in.cyc, wb3_in.cyc)
+    wishbone_candidate: process(all)
     begin
-       if wb1_in.cyc = '1' then
-           candidate <= WB1;
-       elsif wb2_in.cyc = '1' then
-           candidate <= WB2;
-       elsif wb3_in.cyc = '1' then
-           candidate <= WB3;
-       else
-           candidate <= selected;
-       end if;
+       candidate <= selected;
+       for i in NUM_MASTERS-1 downto 0  loop
+           if wb_masters_in(i).cyc = '1' then
+               candidate <= i;
+           end if;
+       end loop;
     end process;
 
     wishbone_arbiter_process: process(clk)
     begin
        if rising_edge(clk) then
            if rst = '1' then
-               selected <= WB1;
-           elsif wb_out.cyc = '0' then
+               selected <= 0;
+           elsif wb_slave_out.cyc = '0' then
                selected <= candidate;
            end if;
        end if;
index 1b8a28baa506db40ce56b0898bdf0fac0ce42495..d1f2a453152af49f7c6f6b1b2b316dbb82d50198 100644 (file)
@@ -27,4 +27,7 @@ package wishbone_types is
     end record;
     constant wishbone_slave_out_init : wishbone_slave_out := (ack => '0', stall => '0', others => (others => '0'));
 
+    type wishbone_master_out_vector is array (natural range <>) of wishbone_master_out;
+    type wishbone_slave_out_vector is array (natural range <>) of wishbone_slave_out;
+
 end package wishbone_types;