From 308d96c9c5f16d1d1d447b59aa72fcfd0296d8bd Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" <w.terpstra@gsi.de> Date: Mon, 5 Mar 2012 13:57:15 +0100 Subject: [PATCH] Fix bugs: record count is 16 bit index aliased decription (to avoid overflow) Added feature: make it easy to relocate a device to a new address Checks added: confirm address ranges to not overlap during synthesis check wbd_begin/end addresses for compatability with the crossbar --- modules/wishbone/wb_crossbar/sdwb_rom.vhd | 22 ++++++------- modules/wishbone/wb_crossbar/xwb_crossbar.vhd | 23 +++++++++++-- .../wb_crossbar/xwb_sdwb_crossbar.vhd | 33 +++++++++++++++---- modules/wishbone/wishbone_pkg.vhd | 21 ++++++++++++ 4 files changed, 80 insertions(+), 19 deletions(-) diff --git a/modules/wishbone/wb_crossbar/sdwb_rom.vhd b/modules/wishbone/wb_crossbar/sdwb_rom.vhd index 248894e6..4a264147 100644 --- a/modules/wishbone/wb_crossbar/sdwb_rom.vhd +++ b/modules/wishbone/wb_crossbar/sdwb_rom.vhd @@ -41,16 +41,16 @@ architecture rtl of sdwb_rom is variable res : t_rom := (others => (others => '0')); variable sdwb_device : std_logic_vector(0 to c_sdwb_device_length-1) := (others => '0'); begin - sdwb_device( 0 to 127) := not x"40f6e98c29eae24c7e6461ae8d2af247"; -- magic - sdwb_device(128 to 191) := std_logic_vector(g_bus_end); -- bus_end - sdwb_device(192 to 207) := std_logic_vector(to_unsigned(c_used_entries, 8)); -- sdwb_records - sdwb_device(208 to 215) := x"01"; -- sdwb_ver_major - sdwb_device(216 to 223) := x"00"; -- sdwb_ver_minor - sdwb_device(224 to 255) := x"00000651"; -- bus_vendor (GSI) - sdwb_device(256 to 287) := x"00000004"; -- bus_device - sdwb_device(288 to 319) := std_logic_vector(to_unsigned(c_version, 32)); -- bus_version - sdwb_device(320 to 351) := std_logic_vector(to_unsigned(c_date, 32)); -- bus_date - sdwb_device(352 to 383) := x"00000000"; -- bus_flags + sdwb_device( 0 to 127) := not x"40f6e98c29eae24c7e6461ae8d2af247"; -- magic + sdwb_device(128 to 191) := std_logic_vector(g_bus_end); -- bus_end + sdwb_device(192 to 207) := std_logic_vector(to_unsigned(c_used_entries, 16)); -- sdwb_records + sdwb_device(208 to 215) := x"01"; -- sdwb_ver_major + sdwb_device(216 to 223) := x"00"; -- sdwb_ver_minor + sdwb_device(224 to 255) := x"00000651"; -- bus_vendor (GSI) + sdwb_device(256 to 287) := x"eef0b198"; -- bus_device + sdwb_device(288 to 319) := std_logic_vector(to_unsigned(c_version, 32)); -- bus_version + sdwb_device(320 to 351) := std_logic_vector(to_unsigned(c_date, 32)); -- bus_date + sdwb_device(352 to 383) := x"00000000"; -- bus_flags for i in 1 to 16 loop sdwb_device(376+i*8 to 383+i*8) := std_logic_vector(to_unsigned(character'pos(c_rom_description(i)), 8)); @@ -77,7 +77,7 @@ architecture rtl of sdwb_rom is for i in 1 to 16 loop -- string to ascii sdwb_device(376+i*8 to 383+i*8) := - std_logic_vector(to_unsigned(character'pos(g_layout(slave).description(i)), 8)); + std_logic_vector(to_unsigned(character'pos(c_layout(slave).description(i)), 8)); end loop; for i in 0 to c_sdwb_words-1 loop diff --git a/modules/wishbone/wb_crossbar/xwb_crossbar.vhd b/modules/wishbone/wb_crossbar/xwb_crossbar.vhd index 14ed1ddf..266fc2f7 100644 --- a/modules/wishbone/wb_crossbar/xwb_crossbar.vhd +++ b/modules/wishbone/wb_crossbar/xwb_crossbar.vhd @@ -73,6 +73,27 @@ architecture rtl of xwb_crossbar is alias c_address : t_wishbone_address_array(g_num_slaves-1 downto 0) is g_address; alias c_mask : t_wishbone_address_array(g_num_slaves-1 downto 0) is g_mask; + -- Confirm that no address ranges overlap + function f_ranges_ok + return boolean + is + variable zero : t_wishbone_address := (others => '0'); + begin + for i in 0 to g_num_slaves-2 loop + for j in i+1 to g_num_slaves-1 loop + assert not (((g_mask(i) and g_mask(j)) and (g_address(i) xor g_address(j))) = zero) + report "Address ranges must be distinct (slaves " & + Integer'image(i) & "[" & Integer'image(to_integer(unsigned(g_address(i)))) & "/" & + Integer'image(to_integer(unsigned(g_mask(i)))) & "] & " & + Integer'image(j) & "[" & Integer'image(to_integer(unsigned(g_address(j)))) & "/" & + Integer'image(to_integer(unsigned(g_mask(j)))) & "])" + severity Failure; + end loop; + end loop; + return true; + end f_ranges_ok; + constant c_ok : boolean := f_ranges_ok; + -- Crossbar connection matrix type matrix is array (g_num_masters-1 downto 0, g_num_slaves downto 0) of std_logic; @@ -363,6 +384,4 @@ begin master_matrix : for master in g_num_masters-1 downto 0 generate slave_o(master) <= master_logic(master, granted, master_ie); end generate; - - -- !!! check for overlap end rtl; diff --git a/modules/wishbone/wb_crossbar/xwb_sdwb_crossbar.vhd b/modules/wishbone/wb_crossbar/xwb_sdwb_crossbar.vhd index 52bc97aa..b820a1c2 100644 --- a/modules/wishbone/wb_crossbar/xwb_sdwb_crossbar.vhd +++ b/modules/wishbone/wb_crossbar/xwb_sdwb_crossbar.vhd @@ -65,11 +65,21 @@ architecture rtl of xwb_sdwb_crossbar is function f_addresses return t_wishbone_address_array is variable result : t_wishbone_address_array(g_layout'range); + variable extend : unsigned(63 downto 0) := (others => '0'); begin for i in g_layout'range loop result(i) := std_logic_vector(g_layout(i).wbd_begin(c_wishbone_address_width-1 downto 0)); - -- !!! report if address is too big - -- !!! report if end < begin + + -- Range must be valid + assert g_layout(i).wbd_begin <= g_layout(i).wbd_end + report "Wishbone slave device #" & Integer'image(i) & " (" & g_layout(i).description & ") wbd_begin address must precede wbd_end address." + severity Failure; + + -- Address must fit + extend(c_wishbone_address_width-1 downto 0) := unsigned(result(i)); + assert g_layout(i).wbd_begin = extend + report "Wishbone slave device #" & Integer'image(i) & " (" & g_layout(i).description & ") wbd_begin does not fit in t_wishbone_address." + severity Failure; end loop; return result; end f_addresses; @@ -77,12 +87,23 @@ architecture rtl of xwb_sdwb_crossbar is function f_masks return t_wishbone_address_array is variable result : t_wishbone_address_array(g_layout'range); variable size : unsigned(63 downto 0); + variable zero : unsigned(63 downto 0) := (others => '0'); begin for i in g_layout'range loop - size := (g_layout(i).wbd_end - g_layout(i).wbd_begin); - -- !!! report if size not a power of 2 - -- !!! report if address is misaligned - result(i) := std_logic_vector(c_bus_bits - size); + size := g_layout(i).wbd_end - g_layout(i).wbd_begin; + + -- size must be of the form 000000...00001111...1 + assert (size and (size + to_unsigned(1, 64))) = zero + report "Wishbone slave device #" & Integer'image(i) & " (" & g_layout(i).description & ") has an address range size that is not a power of 2 minus one (" & Integer'image(to_integer(size)) & "). This is not supported by this crossbar." + severity Failure; + + -- the base address must be aligned to the size + assert (g_layout(i).wbd_begin and size) = zero + report "Wishbone slave device #" & Integer'image(i) & " (" & g_layout(i).description & ") wbd_begin address is not aligned. This is not supported by this crossbar." + severity Failure; + + size := c_bus_bits - size; + result(i) := std_logic_vector(size(c_wishbone_address_width-1 downto 0)); end loop; return result; end f_masks; diff --git a/modules/wishbone/wishbone_pkg.vhd b/modules/wishbone/wishbone_pkg.vhd index 04811c54..3a6e02ca 100644 --- a/modules/wishbone/wishbone_pkg.vhd +++ b/modules/wishbone/wishbone_pkg.vhd @@ -88,6 +88,10 @@ package wishbone_pkg is description : string(1 to 16); end record t_sdwb_device; type t_sdwb_device_array is array(natural range <>) of t_sdwb_device; + + -- Used to configure a device at a certain address + function f_sdwb_set_address(device : t_sdwb_device; address : t_wishbone_address) + return t_sdwb_device; ------------------------------------------------------------------------------ -- Components declaration @@ -543,3 +547,20 @@ package wishbone_pkg is irq_master_o : out std_logic); end component; end wishbone_pkg; + +package body wishbone_pkg is + -- Used to configure a device at a certain address + function f_sdwb_set_address(device : t_sdwb_device; address : t_wishbone_address) + return t_sdwb_device + is + variable result : t_sdwb_device; + begin + result := device; + result.wbd_begin := (others => '0'); + + result.wbd_begin(c_wishbone_address_width-1 downto 0) := unsigned(address); + result.wbd_end := result.wbd_begin + (device.wbd_end - device.wbd_begin); + + return result; + end; +end wishbone_pkg; -- GitLab