Skip to content
Snippets Groups Projects
wishbone_pkg.vhd 89.7 KiB
Newer Older
  function f_xwb_bridge_layout_sdb(     -- determine bus size from layout
    g_wraparound : boolean := true;
    g_layout     : t_sdb_record_array;
    g_sdb_addr   : t_wishbone_address) return t_sdb_bridge
  is
    variable address : t_wishbone_address;
  begin
    address := std_logic_vector(f_sdb_bus_end(g_wraparound, g_layout, g_sdb_addr, false)(address'range));
    return f_xwb_bridge_manual_sdb(address, g_sdb_addr);
  end f_xwb_bridge_layout_sdb;
  function f_xwb_msi_manual_sdb(
    g_size     : t_wishbone_address) return t_sdb_msi
  is
    variable result : t_sdb_msi;
  begin
    result.wbd_endian := '0';
    result.wbd_width  := x"7";

    result.sdb_component.addr_first                                     := (others => '0');
    result.sdb_component.addr_last                                      := (others => '0');
    result.sdb_component.addr_last(c_wishbone_address_width-1 downto 0) := g_size;

    result.sdb_component.product.vendor_id := x"0000000000000651";  -- GSI
    result.sdb_component.product.device_id := x"aa7bfb3c";
    result.sdb_component.product.version   := x"00000001";
    result.sdb_component.product.date      := x"20160422";
    result.sdb_component.product.name      := "WB4-MSI-Bridge-GSI ";

    return result;
  end f_xwb_msi_manual_sdb;
  
  function f_xwb_msi_layout_sdb(     -- determine MSI size from layout
    g_layout     : t_sdb_record_array) return t_sdb_msi
  is
    constant zero : t_wishbone_address := (others => '0');
    variable address : t_wishbone_address;
    address := std_logic_vector(f_sdb_bus_end(true, g_layout, zero, true)(address'range));
    return f_xwb_msi_manual_sdb(address);
  function f_xwb_dpram(g_size : natural) return t_sdb_device
    variable result : t_sdb_device;
    result.abi_ver_major := x"01";
    result.abi_ver_minor := x"00";
    result.wbd_endian    := c_sdb_endian_big;
    result.sdb_component.addr_first := (others => '0');
    result.sdb_component.addr_last  := std_logic_vector(to_unsigned(g_size*4-1, 64));

    result.sdb_component.product.vendor_id := x"000000000000CE42";  -- CERN
    result.sdb_component.product.device_id := x"66cfeb52";
    result.sdb_component.product.version   := x"00000001";
    result.sdb_component.product.date      := x"20120305";
    result.sdb_component.product.name      := "WB4-BlockRAM       ";
  function f_bits2string(s : std_logic_vector) return string is
    --- extend length to full hex nibble
    variable result : string((s'length+7)/4 downto 1);
    variable s_norm : std_logic_vector(result'length*4-1 downto 0) := (others=>'0');
    variable cut : natural;
    variable nibble: std_logic_vector(3 downto 0);
  begin
    s_norm(s'length-1 downto 0) := s;
      nibble := s_norm(i*4+3 downto i*4);
      case nibble is
        when "0000" => result(i+1) := '0';
        when "0001" => result(i+1) := '1';
        when "0010" => result(i+1) := '2';
        when "0011" => result(i+1) := '3';
        when "0100" => result(i+1) := '4';
        when "0101" => result(i+1) := '5';
        when "0110" => result(i+1) := '6';
        when "0111" => result(i+1) := '7';
        when "1000" => result(i+1) := '8';
        when "1001" => result(i+1) := '9';
        when "1010" => result(i+1) := 'a';
        when "1011" => result(i+1) := 'b';
        when "1100" => result(i+1) := 'c';
        when "1101" => result(i+1) := 'd';
        when "1110" => result(i+1) := 'e';
        when "1111" => result(i+1) := 'f';
        when others => result(i+1) := 'X';
      end case;
    end loop;
    -- trim leading 0s
    strip : for i in result'length downto 1 loop
      cut := i;
      exit strip when result(i) /= '0';
    end loop;
    return "0x" & result(cut downto 1);
  end f_bits2string;

  -- Converts string (hex number, without leading 0x) to std_logic_vector
  function f_string2bits(s : string) return std_logic_vector is
    variable slv : std_logic_vector(s'length*4-1 downto 0);
    variable nibble : std_logic_vector(3 downto 0);
  begin
      case s(i+1) is
        when '0' => nibble := X"0";
        when '1' => nibble := X"1";
        when '2' => nibble := X"2";
        when '3' => nibble := X"3";
        when '4' => nibble := X"4";
        when '5' => nibble := X"5";
        when '6' => nibble := X"6";
        when '7' => nibble := X"7";
        when '8' => nibble := X"8";
        when '9' => nibble := X"9";
        when 'a' => nibble := X"A";
        when 'A' => nibble := X"A";
        when 'b' => nibble := X"B";
        when 'B' => nibble := X"B";
        when 'c' => nibble := X"C";
        when 'C' => nibble := X"C";
        when 'd' => nibble := X"D";
        when 'D' => nibble := X"D";
        when 'e' => nibble := X"E";
        when 'E' => nibble := X"E";
        when 'f' => nibble := X"F";
        when 'F' => nibble := X"F";
        when others => nibble := "XXXX";
      end case;
      if s'ascending then
        slv(slv'length-(i*4)-1 downto slv'length-(i+1)*4) := nibble;
      else
        slv(((i+1)*4)-1 downto i*4) := nibble;
      end if;
    end loop;
    return slv;
  end f_string2bits;

  -- Converts string to ascii (std_logic_vector)
  function f_string2svl (s : string) return std_logic_vector is
    alias as : string(1 to len) is s;
    variable slv : std_logic_vector((len * 8) - 1 downto 0);
      slv(slv'high-i*8 downto (slv'high-7)-i*8) :=
        std_logic_vector(to_unsigned(character'pos(as(i+1)), 8));
    end loop;
    return slv;
  end f_string2svl;

  -- Converts ascii (std_logic_vector) to string
  function f_slv2string (slv : std_logic_vector) return string is
    variable s : string(1 to slv'length/8);
  begin
      s(i+1) := character'val(to_integer(unsigned(slv(slv'high-i*8 downto (slv'high-7)-i*8))));
    end loop;
    return s;
  end f_slv2string;

    -- pads a string of unknown length to a given length (useful for integer'image)
  function f_string_fix_len ( s : string; ret_len : natural := 10; fill_char : character := '0'; justify_right : boolean := true ) return string is
      variable ret_v : string (1 to ret_len);
      constant pad_len : integer := ret_len - s'length ;
      variable pad_v : string (1 to abs(pad_len));
   begin
      if pad_len < 1 then
         ret_v := s(ret_v'range);
      else
         pad_v := (others => fill_char);
         if justify_right then
           ret_v := pad_v & s;
         else
           ret_v := s & pad_v ;
         end if;
      end if;
      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
      rv := 0;
      -- if there are few ones set in _x_ then the most significant will be
      -- translated to bin
      for i in 0 to x'left loop
         if x(i) = '1' then
           rv := i+1;
         end if;
      end loop;
      return rv;
  end function;  

  function f_wb_spi_flash_sdb(g_bits : natural) return t_sdb_device is
    variable result : t_sdb_device := (
      abi_class     => x"0000", -- undocumented device
      abi_ver_major => x"01",
      wbd_endian    => c_sdb_endian_big,
      wbd_width     => x"7", -- 8/16/32-bit port granularity
      sdb_component => (
      addr_first    => x"0000000000000000",
      addr_last     => x"0000000000ffffff",
      product => (
      vendor_id     => x"0000000000000651", -- GSI
      device_id     => x"5cf12a1c",
      version       => x"00000002",
      date          => x"20140417",
      name          => "SPI-FLASH-16M-MMAP ")));
  begin
    result.sdb_component.addr_last := std_logic_vector(to_unsigned(2**g_bits-1, 64));
    return result;
  end f_wb_spi_flash_sdb;
  
Wesley W. Terpstra's avatar
Wesley W. Terpstra committed
end wishbone_pkg;