⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 altera_vhdl_support.vhd

📁 采用nios2的嵌入式数字钟的设计与实现
💻 VHD
📖 第 1 页 / 共 2 页
字号:
      result(i) := arg_copy(i);
    end LOOP;
    
    RETURN(result);   
  END;

  -------------------------------------------------------
  -- Conversions for Verilog $display/$write emulation --
  -------------------------------------------------------

  subtype slv4        is std_logic_vector(1 to 4);
  subtype slv3        is std_logic_vector(1 to 3);

  -- Remove leading zeros.  Also changes strings of all 'x' or 'z' to one char.
  -- This handles the %0<radix> kind of Verilog syntax in the format string.
  -- Examples:
  --        input           output
  --        -----           -----------
  --        001f            1f
  --        0000            0
  --        xxxx            x
  --        zzzz            z
  --        xxzz            xxzz

  function do_pad_none(
      str_in             : string) return string is
      variable start     : integer;
      variable all_x     : boolean := true;
      variable all_z     : boolean := true;
  begin
      -- Nothing to remove if string isn't at least two characters long.
      if (str_in'length < 2) then
         return str_in;
      end if;

      for i in str_in'range loop
          case str_in(i) is
            when 'X' | 'x' => all_z := false;
            when 'Z' | 'z' => all_x := false;
            when others    => all_x := false; all_z := false;
          end case;
      end loop;

      if (all_x or all_z) then
         return str_in(str_in'left to str_in'left);
      end if;

      -- Find index of first non-zero character.
      for i in str_in'range loop
          start := i;
          exit when (str_in(i) /= '0');
      end loop;

      return str_in(start to str_in'right);
  end do_pad_none;  

  -- Replace leading zeros with spaces.
  -- This handles the %d kind of Verilog syntax in the format string.
  function replace_leading_zeros(
      str_in           : string;
      c                : character) return string is
      variable str_out : string(str_in'range) := str_in;
  begin
      -- Nothing to replace if string isn't at least two characters long.
      if (str_in'length < 2) then
         return str_in;
      end if;

      for i in str_in'range loop
          if (str_in(i) = '0') then
              str_out(i) := c;
          else
              exit;
          end if;
      end loop;

      return str_out;
  end replace_leading_zeros;  

  function do_pad(
      str            : string;
      pad            : pad_type) return string is
  begin
      case pad is
        when pad_none =>   return do_pad_none(str);
        when pad_spaces => return replace_leading_zeros(str, ' ');
        when pad_zeros =>  return str;
      end case;
  end do_pad;

  function round_up_to_multiple(
      val        : integer; 
      size       : integer) return integer is
  begin
      return ((val + size - 1) / size) * size;
  end round_up_to_multiple;

  function to_hex_string(
      val              : std_logic_vector;
      pad              : pad_type     := pad_zeros) return string is
      variable ext_len : integer := round_up_to_multiple(val'length,4);
      variable val_ext : std_logic_vector(1 to ext_len) := (others => '0');
      variable ptr     : integer range 1 to (ext_len/4)+1 := 1;
      variable str     : string(1 to ext_len/4) := (others=>'0');
      variable found_x : boolean := false;
      variable found_z : boolean := false;
  begin
      val_ext(ext_len-val'length+1 to ext_len) := val;

      -- Extend MSB to extended sulv unless it starts with one (unsigned).
      -- Done to extend 'x' and 'z'.
      if ext_len-val'length > 0 and val(val'left) /= '1' then 
        val_ext(1 to ext_len-val'length) := (others => val(val'left));
      end if;

      for i in val_ext'range loop
        next when i rem 4 /= 1;

        case slv4'(to_x01z(val_ext(i to i+3))) is
          when "0000" => str(ptr) := '0';
          when "0001" => str(ptr) := '1';
          when "0010" => str(ptr) := '2';
          when "0011" => str(ptr) := '3';
          when "0100" => str(ptr) := '4';
          when "0101" => str(ptr) := '5';
          when "0110" => str(ptr) := '6';
          when "0111" => str(ptr) := '7';
          when "1000" => str(ptr) := '8';
          when "1001" => str(ptr) := '9';
          when "1010" => str(ptr) := 'a';
          when "1011" => str(ptr) := 'b';
          when "1100" => str(ptr) := 'c';
          when "1101" => str(ptr) := 'd';
          when "1110" => str(ptr) := 'e';
          when "1111" => str(ptr) := 'f';
          when "XXXX" => str(ptr) := 'x';
          when "ZZZZ" => str(ptr) := 'z';
          when others =>
            for j in 0 to 3 loop
                case val_ext(i + j) is
                  when 'X' => found_x := true;
                  when 'Z' => found_z := true;
                  when others => null;
                end case;
            end loop;
            
            if found_x then
                str(ptr) := 'X';
            elsif found_z then
                str(ptr) := 'Z';
            else
                str(ptr) := 'X';
            end if;
        end case;
        ptr := ptr + 1;
      end loop;
      return do_pad(str, pad);
    end to_hex_string;

  function to_decimal_string(
      val              : integer;
      pad              : pad_type := pad_spaces) return string is
      variable     tmp : integer := val;
      variable     ptr : integer range 1 to 32 := 32;
      variable     str : string(1 to 32) := (others=>'0');
  begin
      if val=0 then 
          return do_pad("0", pad); 
      else
          while tmp > 0 loop
              case tmp rem 10 is
                when 0 => str(ptr) := '0';
                when 1 => str(ptr) := '1';
                when 2 => str(ptr) := '2';
                when 3 => str(ptr) := '3';
                when 4 => str(ptr) := '4';
                when 5 => str(ptr) := '5';
                when 6 => str(ptr) := '6';
                when 7 => str(ptr) := '7';
                when 8 => str(ptr) := '8';
                when 9 => str(ptr) := '9';
                when others => null;
              end case;

              tmp := tmp / 10;
              ptr := ptr - 1;
          end loop;

          return do_pad(str(ptr+1 to 32), pad);
      end if;
  end to_decimal_string;

  function to_decimal_string(
      val                : std_logic_vector;
      pad                : pad_type := pad_spaces) return string is
      variable all_x     : boolean := true;
      variable all_z     : boolean := true;
      variable some_x    : boolean := false;
      variable some_z    : boolean := false;
      variable fixed_str : string(1 to 1);
  begin
      for i in val'range loop
          case to_x01z(val(i)) is
            when 'X'    => some_x := true; all_z := false;
            when 'Z'    => some_z := true; all_x := false;
            when others => all_x := false; all_z := false;
          end case;
      end loop;

      if (all_x) then
          fixed_str(1) := 'x';
          return fixed_str;
      elsif (all_z) then
          fixed_str(1) := 'z';
          return fixed_str;
      elsif (some_x) then
          fixed_str(1) := 'X';
          return fixed_str;
      elsif (some_z) then
          fixed_str(1) := 'Z';
          return fixed_str;
      else
          return to_decimal_string(conv_integer(val), pad);
      end if;
  end to_decimal_string;

  function to_octal_string(
      val              : std_logic_vector;
      pad              : pad_type     := pad_zeros) return string is
      variable ext_len : integer := round_up_to_multiple(val'length,3);
      variable val_ext : std_logic_vector(1 to ext_len) := (others => '0');
      variable ptr     : integer range 1 to (ext_len/3)+1 := 1;
      variable str     : string(1 to ext_len/3) := (others=>'0');
      variable found_x : boolean := false;
      variable found_z : boolean := false;
  begin
      val_ext(ext_len-val'length+1 to ext_len) := val;

      -- Extend MSB to extended sulv unless it starts with one (unsigned).
      -- Done to extend 'x' and 'z'.
      if ext_len-val'length > 0 and val(val'left) /= '1' then 
        val_ext(1 to ext_len-val'length) := (others => val(val'left));
      end if;

      for i in val_ext'range loop
        next when i rem 3 /= 1;

        case slv3'(to_x01z(val_ext(i to i+2))) is
          when "000" => str(ptr) := '0';
          when "001" => str(ptr) := '1';
          when "010" => str(ptr) := '2';
          when "011" => str(ptr) := '3';
          when "100" => str(ptr) := '4';
          when "101" => str(ptr) := '5';
          when "110" => str(ptr) := '6';
          when "111" => str(ptr) := '7';
          when "XXX" => str(ptr) := 'x';
          when "ZZZ" => str(ptr) := 'z';
          when others =>
            for j in 0 to 2 loop
                case val_ext(i + j) is
                  when 'X' => found_x := true;
                  when 'Z' => found_z := true;
                  when others => null;
                end case;
            end loop;
            
            if found_x then
                str(ptr) := 'X';
            elsif found_z then
                str(ptr) := 'Z';
            else
                str(ptr) := 'X';
            end if;
        end case;
        ptr := ptr + 1;
      end loop;
      return do_pad(str, pad);
  end to_octal_string;

  function to_hex_string(
      val              : std_logic;
      pad              : pad_type     := pad_zeros) return string is
  begin
      return to_binary_string(val, pad);
  end to_hex_string;

  function to_decimal_string(
      val              : std_logic;
      pad              : pad_type     := pad_spaces) return string is
  begin
      return to_binary_string(val, pad);
  end to_decimal_string;

  function to_octal_string(
      val              : std_logic;
      pad              : pad_type     := pad_zeros) return string is
  begin
      return to_binary_string(val, pad);
  end to_octal_string;

  function to_binary_string(
      val              : std_logic;
      pad              : pad_type := pad_zeros) return string is
      variable str     : string(1 to 1);
  begin
      case to_x01z(val) is
          when '0'    => str(1) := '0';
          when '1'    => str(1) := '1';
          when 'X'    => str(1) := 'x';
          when 'Z'    => str(1) := 'z';
          when others => str(1) := 'x';
        end case;
      return do_pad(str, pad);
  end to_binary_string;

  function to_binary_string(
      val              : std_logic_vector;
      pad              : pad_type := pad_zeros) return string is
      variable str     : string(1 to val'length) := (others=>'0');
      variable ptr     : integer := str'left;
  begin
      for i in val'range loop
        str(ptr to ptr) := to_binary_string(val(i));
        ptr := ptr + 1;
      end loop;
      return do_pad(str, pad);
  end to_binary_string;

end altera_vhdl_support_lib;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -