From 91c42e0f27dfc5e72bd09a7dfd3db8dfcd6b9f2d Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" <w.terpstra@gsi.de> Date: Thu, 21 Apr 2016 17:18:36 +0200 Subject: [PATCH] sdb: modify ROM handle active master flag --- modules/wishbone/wb_crossbar/sdb_rom.vhd | 115 ++++++++++-------- .../wishbone/wb_crossbar/xwb_sdb_crossbar.vhd | 13 +- modules/wishbone/wishbone_pkg.vhd | 10 +- 3 files changed, 73 insertions(+), 65 deletions(-) diff --git a/modules/wishbone/wb_crossbar/sdb_rom.vhd b/modules/wishbone/wb_crossbar/sdb_rom.vhd index 37acd3b1..d0b65b11 100644 --- a/modules/wishbone/wb_crossbar/sdb_rom.vhd +++ b/modules/wishbone/wb_crossbar/sdb_rom.vhd @@ -5,28 +5,72 @@ use work.wishbone_pkg.all; entity sdb_rom is generic( - g_slaves : t_sdb_record_array; - g_masters : t_sdb_record_array; - g_bus_end : unsigned(63 downto 0)); + g_layout : t_sdb_record_array; + g_masters : natural; + g_bus_end : unsigned(63 downto 0)); port( - clk_sys_i : in std_logic; - master_i : in std_logic_vector(g_masters'length-1 downto 0); - slave_i : in t_wishbone_slave_in; - slave_o : out t_wishbone_slave_out); + clk_sys_i : in std_logic; + master_i : in std_logic_vector(g_masters-1 downto 0); + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out); end sdb_rom; architecture rtl of sdb_rom is - alias c_masters : t_sdb_record_array(g_masters'length downto 1) is g_masters; - alias c_slaves : t_sdb_record_array(g_slaves'length+c_masters'high downto c_masters'high+1) is g_slaves; + alias c_layout : t_sdb_record_array(g_layout'length downto 1) is g_layout; -- The ROM must describe all slaves, the crossbar itself and the optional information records - constant c_used_entries : natural := c_slaves'high + 1; + constant c_used_entries : natural := c_layout'high + 1; constant c_rom_entries : natural := 2**f_ceil_log2(c_used_entries); -- next power of 2 constant c_sdb_words : natural := c_sdb_device_length / c_wishbone_data_width; constant c_rom_words : natural := c_rom_entries * c_sdb_words; constant c_rom_depth : natural := f_ceil_log2(c_rom_words); constant c_rom_lowbits : natural := f_ceil_log2(c_wishbone_data_width / 8); + -- Index of the MSI entry in SDB + type t_nat_array is array(g_masters-1 downto 0) of natural; + function f_master_positions return t_nat_array is + variable result : t_nat_array; + variable master : natural := 0; + begin + for rec in c_layout'low to c_layout'high loop + if c_layout(rec)(7 downto 0) = x"03" then + assert master < g_masters + report "Too many msi records found" + severity failure; + + result(master) := rec; + master := master + 1; + end if; + end loop; + + if master = 0 then + result := (others => g_masters); + else + assert master = g_masters + report "Insufficient msi records found" + severity failure; + end if; + return result; + end f_master_positions; + + constant c_master_positions : t_nat_array := f_master_positions; + constant c_msi : boolean := c_master_positions(0) /= g_masters; + + function f_msi_flag_index(y : std_logic_vector) return std_logic_vector is + variable offset : unsigned(c_rom_depth-1 downto 0) := (others => '0'); + variable result : std_logic_vector(c_rom_depth-1 downto 0) := (others => '0'); + begin + for i in c_master_positions'range loop + if c_msi then + offset := to_unsigned(c_master_positions(i)*16, offset'length); + end if; + for b in result'range loop + result(b) := result(b) or (offset(b) and y(i)); + end loop; + end loop; + return result; + end f_msi_flag_index; + type t_rom is array(c_rom_words-1 downto 0) of t_wishbone_data; function f_build_rom @@ -45,17 +89,10 @@ architecture rtl of sdb_rom is sdb_component.addr_first := (others => '0'); sdb_component.addr_last := std_logic_vector(g_bus_end); sdb_component.product.vendor_id := x"0000000000000651"; -- GSI - if g_masters'length > 0 then - sdb_component.product.device_id := x"2b6e61b3"; - sdb_component.product.version := x"00000001"; - sdb_component.product.date := x"20160421"; - sdb_component.product.name := "MSI-Crossbar-GSI "; - else - sdb_component.product.device_id := x"e6a542c9"; - sdb_component.product.version := x"00000002"; - sdb_component.product.date := x"20120511"; - sdb_component.product.name := "WB4-Crossbar-GSI "; - end if; + sdb_component.product.device_id := x"e6a542c9"; + sdb_component.product.version := x"00000003"; + sdb_component.product.date := x"20120511"; + sdb_component.product.name := "WB4-Crossbar-GSI "; sdb_device(447 downto 8) := f_sdb_embed_component(sdb_component, (others => '0')); for i in 0 to c_sdb_words-1 loop @@ -63,46 +100,18 @@ architecture rtl of sdb_rom is sdb_device((i+1)*c_wishbone_data_width-1 downto i*c_wishbone_data_width); end loop; - for master in c_masters'range loop - sdb_device(511 downto 0) := c_masters(master); + for idx in c_layout'range loop + sdb_device(511 downto 0) := c_layout(idx); for i in 0 to c_sdb_words-1 loop - res((master+1)*c_sdb_words-1-i) := + res((idx+1)*c_sdb_words-1-i) := sdb_device((i+1)*c_wishbone_data_width-1 downto i*c_wishbone_data_width); end loop; end loop; - for slave in c_slaves'range loop - sdb_device(511 downto 0) := c_slaves(slave); - - for i in 0 to c_sdb_words-1 loop - res((slave+1)*c_sdb_words-1-i) := - sdb_device((i+1)*c_wishbone_data_width-1 downto i*c_wishbone_data_width); - end loop; - end loop; - return res; end f_build_rom; - function f_msi_flag_index(y : std_logic_vector) return std_logic_vector is - -- Bump the indexes to start from 1 (0 is the SDB table header) - alias x : std_logic_vector(y'length downto 1) is y; - -- Result is the full width of the SDB word address - variable result : std_logic_vector(c_rom_depth-1 downto 0) := (others => '0'); - variable step : natural := 1; - begin - -- Leave bits 0-3 as '0' (16 words per SDB record) - for i in 4 to result'high loop - for j in x'range loop - if (j / step) mod 2 = 1 then - result(i) := result(i) or x(j); - end if; - end loop; - step := step + step; - end loop; - return result; - end f_msi_flag_index; - constant rom : t_rom := f_build_rom; signal adr_reg : unsigned(c_rom_depth-1 downto 0); signal sel_reg : unsigned(c_rom_depth-1 downto 0); @@ -119,7 +128,7 @@ begin slave_o.int <= '0'; -- Tom sucks! This should not be here. s_rom <= rom(to_integer(adr_reg)); - s_flag(s_flag'high) <= '1' when adr_reg = sel_reg and g_masters'length > 0 else '0'; + s_flag(s_flag'high) <= '1' when adr_reg = sel_reg and c_msi else '0'; slave_o.dat <= s_rom or s_flag; slave_clk : process(clk_sys_i) diff --git a/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd b/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd index fd7ceb61..c237a721 100644 --- a/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd +++ b/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd @@ -214,11 +214,9 @@ architecture rtl of xwb_sdb_crossbar is constant c_mask : t_wishbone_address_array(g_num_slaves downto 0) := c_sdb_mask & c_addresses.bus_mask; - -- !!! to remove - constant c_null : t_sdb_record_array(0 downto 1) := (others => (others => '0')); - signal master_i_1 : t_wishbone_master_in_array(g_num_slaves downto 0); signal master_o_1 : t_wishbone_master_out_array(g_num_slaves downto 0); + signal sdb_sel : std_logic_vector(g_num_masters-1 downto 0); begin @@ -228,12 +226,12 @@ begin rom : sdb_rom generic map( - g_slaves => c_layout, - g_masters => c_null, + g_layout => c_layout, + g_masters => g_num_masters, g_bus_end => c_sizes.bus_last) port map( clk_sys_i => clk_sys_i, - master_i => (others => '0'), + master_i => sdb_sel, slave_i => master_o_1(g_num_slaves), slave_o => master_i_1(g_num_slaves)); @@ -250,6 +248,7 @@ begin slave_i => slave_i, slave_o => slave_o, master_i => master_i_1, - master_o => master_o_1); + master_o => master_o_1, + sdb_sel_o => sdb_sel); end rtl; diff --git a/modules/wishbone/wishbone_pkg.vhd b/modules/wishbone/wishbone_pkg.vhd index 35564c73..ea085890 100644 --- a/modules/wishbone/wishbone_pkg.vhd +++ b/modules/wishbone/wishbone_pkg.vhd @@ -361,12 +361,12 @@ package wishbone_pkg is component sdb_rom is generic( - g_slaves : t_sdb_record_array; - g_masters : t_sdb_record_array; - g_bus_end : unsigned(63 downto 0)); + g_layout : t_sdb_record_array; + g_masters : natural; + g_bus_end : unsigned(63 downto 0)); port( clk_sys_i : in std_logic; - master_i : in std_logic_vector(g_masters'length-1 downto 0); + master_i : in std_logic_vector(g_masters-1 downto 0); slave_i : in t_wishbone_slave_in; slave_o : out t_wishbone_slave_out); end component; @@ -1389,7 +1389,7 @@ package body wishbone_pkg is constant c_zero : t_wishbone_address := (others => '0'); variable v_empty : t_sdb_record := (others => '0'); begin - v_empty(7 downto 0) := (others => '1'); + v_empty(7 downto 0) := (others => '1'); -- !!! fuck if enable then return f_sdb_embed_msi(msi, c_zero); else -- GitLab