From 219b2ad28fc36bbffbcdf94befdb0020591c8adf Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" <w.terpstra@gsi.de> Date: Thu, 21 Apr 2016 14:24:48 +0200 Subject: [PATCH] sdb: new master-describing SDB record --- modules/wishbone/wb_crossbar/sdb_rom.vhd | 70 +++++++++++++++---- .../wishbone/wb_crossbar/xwb_sdb_crossbar.vhd | 6 +- modules/wishbone/wishbone_pkg.vhd | 58 ++++++++++++++- 3 files changed, 119 insertions(+), 15 deletions(-) diff --git a/modules/wishbone/wb_crossbar/sdb_rom.vhd b/modules/wishbone/wb_crossbar/sdb_rom.vhd index 1c47f753..37acd3b1 100644 --- a/modules/wishbone/wb_crossbar/sdb_rom.vhd +++ b/modules/wishbone/wb_crossbar/sdb_rom.vhd @@ -5,19 +5,22 @@ use work.wishbone_pkg.all; entity sdb_rom is generic( - g_layout : t_sdb_record_array; + g_slaves : t_sdb_record_array; + g_masters : t_sdb_record_array; 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); end sdb_rom; architecture rtl of sdb_rom is - alias c_layout : t_sdb_record_array(g_layout'length downto 1) is g_layout; + 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; -- The ROM must describe all slaves, the crossbar itself and the optional information records - constant c_used_entries : natural := c_layout'length + 1; + constant c_used_entries : natural := c_slaves'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; @@ -42,10 +45,17 @@ 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 - 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 "; + 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_device(447 downto 8) := f_sdb_embed_component(sdb_component, (others => '0')); for i in 0 to c_sdb_words-1 loop @@ -53,8 +63,17 @@ architecture rtl of sdb_rom is sdb_device((i+1)*c_wishbone_data_width-1 downto i*c_wishbone_data_width); end loop; - for slave in 1 to c_used_entries-1 loop - sdb_device(511 downto 0) := c_layout(slave); + for master in c_masters'range loop + sdb_device(511 downto 0) := c_masters(master); + + for i in 0 to c_sdb_words-1 loop + res((master+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) := @@ -64,23 +83,50 @@ architecture rtl of sdb_rom is return res; end f_build_rom; - - signal rom : t_rom := 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); + + signal s_rom : t_wishbone_data; + signal s_flag : t_wishbone_data := (others => '0'); begin + -- Simple ROM; ignore we/sel/dat slave_o.err <= '0'; slave_o.rty <= '0'; slave_o.stall <= '0'; slave_o.int <= '0'; -- Tom sucks! This should not be here. - slave_o.dat <= rom(to_integer(adr_reg)); + 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'; + slave_o.dat <= s_rom or s_flag; slave_clk : process(clk_sys_i) begin if (rising_edge(clk_sys_i)) then adr_reg <= unsigned(slave_i.adr(c_rom_depth+c_rom_lowbits-1 downto c_rom_lowbits)); + sel_reg <= unsigned(f_msi_flag_index(master_i)); slave_o.ack <= slave_i.cyc and slave_i.stb; end if; end process; diff --git a/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd b/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd index f03f03c3..dee02661 100644 --- a/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd +++ b/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd @@ -154,10 +154,10 @@ architecture rtl of xwb_sdb_crossbar is constant c_sdb_mask : t_wishbone_address := std_logic_vector(c_rom_mask(c_wishbone_address_width-1 downto 0)); constant c_address : t_wishbone_address_array(g_num_slaves downto 0) := - g_sdb_addr & f_addresses; constant c_mask : t_wishbone_address_array(g_num_slaves downto 0) := c_sdb_mask & f_masks; + 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); @@ -167,10 +167,12 @@ begin rom : sdb_rom generic map( - g_layout => c_layout, + g_slaves => c_layout, + g_masters => c_null, g_bus_end => c_bus_end) port map( clk_sys_i => clk_sys_i, + master_i => (others => '0'), slave_i => master_o_1(g_num_slaves), slave_o => master_i_1(g_num_slaves)); diff --git a/modules/wishbone/wishbone_pkg.vhd b/modules/wishbone/wishbone_pkg.vhd index 72c8ac17..ddeed8e5 100644 --- a/modules/wishbone/wishbone_pkg.vhd +++ b/modules/wishbone/wishbone_pkg.vhd @@ -124,6 +124,12 @@ package wishbone_pkg is sdb_component : t_sdb_component; end record t_sdb_device; + type t_sdb_msi is record + wbd_endian : std_logic; -- 0 = big, 1 = little + wbd_width : std_logic_vector(3 downto 0); -- 3=64-bit, 2=32-bit, 1=16-bit, 0=8-bit + sdb_component : t_sdb_component; + end record t_sdb_msi; + type t_sdb_bridge is record sdb_child : std_logic_vector(63 downto 0); sdb_component : t_sdb_component; @@ -165,12 +171,14 @@ package wishbone_pkg is -- Used to configure a device at a certain address function f_sdb_embed_device(device : t_sdb_device; address : t_wishbone_address) return t_sdb_record; function f_sdb_embed_bridge(bridge : t_sdb_bridge; address : t_wishbone_address) return t_sdb_record; + function f_sdb_embed_msi(msi : t_sdb_msi; address : t_wishbone_address) return t_sdb_record; function f_sdb_embed_integration(integr : t_sdb_integration) return t_sdb_record; function f_sdb_embed_repo_url(url : t_sdb_repo_url) return t_sdb_record; function f_sdb_embed_synthesis(syn : t_sdb_synthesis) return t_sdb_record; function f_sdb_extract_device(sdb_record : t_sdb_record) return t_sdb_device; function f_sdb_extract_bridge(sdb_record : t_sdb_record) return t_sdb_bridge; + function f_sdb_extract_msi(sdb_record : t_sdb_record) return t_sdb_msi; function f_sdb_extract_integration(sdb_record : t_sdb_record) return t_sdb_integration; function f_sdb_extract_repo_url(sdb_record : t_sdb_record) return t_sdb_repo_url; function f_sdb_extract_synthesis(sdb_record : t_sdb_record) return t_sdb_synthesis; @@ -178,6 +186,7 @@ package wishbone_pkg is -- Automatic crossbar mapping functions function f_sdb_auto_device(device : t_sdb_device; enable : boolean := true) return t_sdb_record; function f_sdb_auto_bridge(bridge : t_sdb_bridge; enable : boolean := true) return t_sdb_record; + function f_sdb_auto_msi (msi : t_sdb_msi; enable : boolean := true) return t_sdb_record; function f_sdb_auto_layout(records : t_sdb_record_array) return t_sdb_record_array; function f_sdb_auto_sdb (records : t_sdb_record_array) return t_wishbone_address; @@ -349,10 +358,12 @@ package wishbone_pkg is component sdb_rom is generic( - g_layout : t_sdb_record_array; + g_slaves : t_sdb_record_array; + g_masters : t_sdb_record_array; 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); end component; @@ -1196,6 +1207,36 @@ package body wishbone_pkg is return result; end; + function f_sdb_embed_msi(msi : t_sdb_msi; address : t_wishbone_address) + return t_sdb_record + is + variable result : t_sdb_record; + begin + result(511 downto 456) := (others => '0'); + result(455) := msi.wbd_endian; + result(454 downto 452) := (others => '0'); + result(451 downto 448) := msi.wbd_width; + result(447 downto 8) := f_sdb_embed_component(msi.sdb_component, address); + result(7 downto 0) := x"03"; -- msi + return result; + end; + + function f_sdb_extract_msi(sdb_record : t_sdb_record) + return t_sdb_msi + is + variable result : t_sdb_msi; + begin + result.wbd_endian := sdb_record(452); + result.wbd_width := sdb_record(451 downto 448); + result.sdb_component := f_sdb_extract_component(sdb_record(447 downto 8)); + + assert sdb_record(7 downto 0) = x"03" + report "Cannot extract t_sdb_msi from record of type " & integer'image(to_integer(unsigned(sdb_record(7 downto 0)))) & "." + severity failure; + + return result; + end; + function f_sdb_embed_integration(integr : t_sdb_integration) return t_sdb_record is @@ -1339,6 +1380,20 @@ package body wishbone_pkg is end if; end f_sdb_auto_bridge; + function f_sdb_auto_msi(msi : t_sdb_msi; enable : boolean := true) + return t_sdb_record + 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'); + if enable then + return f_sdb_embed_msi(msi, c_zero); + else + return v_empty; + end if; + end f_sdb_auto_msi; + subtype t_usdb_address is unsigned(63 downto 0); type t_usdb_address_array is array(natural range <>) of t_usdb_address; @@ -1843,6 +1898,7 @@ package body wishbone_pkg is return ret_v; end f_string_fix_len; + -- do not synthesize function f_hot_to_bin(x : std_logic_vector) return natural is variable rv : natural; begin -- GitLab