diff --git a/common/UtilsP.vhd b/common/UtilsP.vhd index 8b6925d..05fbe90 100644 --- a/common/UtilsP.vhd +++ b/common/UtilsP.vhd @@ -28,6 +28,8 @@ package UtilsP is function uint_to_slv (data: in natural; len : in positive) return std_logic_vector; function slv_to_uint (data: in std_logic_vector) return natural; + function uint_bitsize(data : in natural) return natural; + end package UtilsP; @@ -127,7 +129,7 @@ package body UtilsP is function uint_to_slv (data: in natural; len : in positive) return std_logic_vector is begin - assert len > integer(trunc(log2(real(data)))) + assert len >= uint_bitsize(data) report "Warning: std_logic_vector result truncated" severity warning; return std_logic_vector(to_unsigned(data, len)); @@ -148,4 +150,22 @@ package body UtilsP is end function slv_to_uint; + function uint_bitsize(data : in natural) return natural is + variable v_nlz : natural := 0; + variable v_data : unsigned(30 downto 0) := to_unsigned(data, 31); + begin + if (data = 0) then + return 1; + end if; + for i in 30 downto 0 loop + if(v_data(i) /= '0') then + exit; + else + v_nlz := v_nlz + 1; + end if; + end loop; + return 31 - v_nlz; + end function uint_bitsize; + + end package body UtilsP; diff --git a/test/WishBoneT.vhd b/test/WishBoneT.vhd index 27bbfb3..b37b4e4 100644 --- a/test/WishBoneT.vhd +++ b/test/WishBoneT.vhd @@ -17,6 +17,7 @@ library libvhdl; use libvhdl.AssertP.all; use libvhdl.SimP.all; use libvhdl.QueueP.all; + use libvhdl.UtilsP.all; @@ -161,7 +162,7 @@ begin for i in 0 to integer'(2**C_ADDRESS_WIDTH-1) loop v_wbmaster_data := v_random.RandSlv(C_DATA_WIDTH); s_master_local_din <= v_wbmaster_data; - s_master_local_adress <= std_logic_vector(to_unsigned(i, C_ADDRESS_WIDTH)); + s_master_local_adress <= uint_to_slv(i, C_ADDRESS_WIDTH); s_master_local_wen <= '1'; wait until rising_edge(s_wb_clk); s_master_local_din <= (others => '0'); @@ -172,7 +173,7 @@ begin end loop; -- read back and check the wishbone slave registers for i in 0 to integer'(2**C_ADDRESS_WIDTH-1) loop - s_master_local_adress <= std_logic_vector(to_unsigned(i, C_ADDRESS_WIDTH)); + s_master_local_adress <= uint_to_slv(i, C_ADDRESS_WIDTH); s_master_local_ren <= '1'; wait until rising_edge(s_wb_clk); s_master_local_adress <= (others => '0'); @@ -273,9 +274,9 @@ begin s_slave_local_din <= (others => '0'); else if (s_slave_local_wen = '1') then - v_register(to_integer(unsigned(s_slave_local_adress))) := s_slave_local_dout; + v_register(slv_to_uint(s_slave_local_adress)) := s_slave_local_dout; elsif (s_slave_local_ren = '1') then - s_slave_local_din <= v_register(to_integer(unsigned(s_slave_local_adress))); + s_slave_local_din <= v_register(slv_to_uint(s_slave_local_adress)); end if; end if; end process WbSlaveLocalP;