如何在VHDL中以十六进制形式将整数写入标准输出?

如何在VHDL中以十六进制形式将整数写入标准输出?,vhdl,ghdl,Vhdl,Ghdl,我可以将整数作为十进制打印到标准输出: library std; use std.textio.all; entity min is end min; architecture behav of min is begin process is variable my_line : line; begin write(my_line, 16); writeline(output, my_line); wait;

我可以将
整数
作为十进制打印到标准输出:

library std;
use std.textio.all;

entity min is
end min;

architecture behav of min is
begin
    process is
        variable my_line : line;
    begin
        write(my_line, 16);
        writeline(output, my_line);
        wait;
    end process;
end behav;
哪些产出:

16
但如何进行输出:

10
0x10
没有标准的库实现,但例如,我们的包中有几个格式化函数。除此之外,我们还有一个函数,它接受一个格式字符,如用于十六进制输出的
h

如何将这样的整数转换为十六进制?

  • 将整数转换为二进制表示形式
  • 将二进制值分组为4位组
  • 将每组转换为0..F范围内的整数/α
  • 如有必要,请预编
    0x
  • 下面是一个将整数转换为二进制表示的包装器:

    -- format a natural as HEX string
    function raw_format_nat_hex(Value : NATURAL) return STRING is
    begin
      return raw_format_slv_hex(std_logic_vector(to_unsigned(Value, log2ceil(Value+1))));
    end function;
    
    现在是分组和转换

    -- format a std_logic_vector as HEX string
    function raw_format_slv_hex(slv : STD_LOGIC_VECTOR) return STRING is
      variable Value                : STD_LOGIC_VECTOR(4*div_ceil(slv'length, 4) - 1 downto 0);
      variable Digit                : STD_LOGIC_VECTOR(3 downto 0);
      variable Result               : STRING(1 to div_ceil(slv'length, 4));
      variable j                    : NATURAL;
    begin
      Value := resize(slv, Value'length);
      j             := 0;
      for i in Result'reverse_range loop
        Digit       := Value((j * 4) + 3 downto (j * 4));
        Result(i)   := to_HexChar(unsigned(Digit));
        j           := j + 1;
      end loop;
      return Result;
    end function;
    
    -- convert an unsigned value(4 bit) to a HEX digit (0-F)
    function to_HexChar(Value : UNSIGNED) return CHARACTER is
      constant HEX : STRING := "0123456789ABCDEF";
    begin
      if (Value < 16) then
        return HEX(to_integer(Value)+1);
      else
        return 'X';
      end if;
    end function;
    
    -- return TRUE, if input is a power of 2
    function div_ceil(a : NATURAL; b : POSITIVE) return NATURAL is  -- calculates: ceil(a / b)
    begin
      return (a + (b - 1)) / b;
    end function;
    
    -- return log2; always rounded up
    function log2ceil(arg : positive) return natural is
      variable tmp : positive;
      variable log : natural;
    begin
      if arg = 1 then   return 0; end if;
      tmp := 1;
      log := 0;
      while arg > tmp loop
        tmp := tmp * 2;
        log := log + 1;
      end loop;
      return log;
    end function;
    
    ——将标准逻辑向量格式化为十六进制字符串
    函数原始格式slv十六进制(slv:STD逻辑向量)返回字符串为
    变量值:标准逻辑向量(4*div\u ceil(slv'长度,4)-1到0);
    可变数字:标准逻辑向量(3到0);
    变量结果:字符串(1到div_ceil(slv'length,4));
    变量j:自然变量;
    开始
    值:=调整大小(slv,值的长度);
    j:=0;
    对于结果“反向”范围循环中的i
    数字:=值((j*4)+3向下至(j*4));
    结果(i):=to_HexChar(无符号(数字));
    j:=j+1;
    端环;
    返回结果;
    末端功能;
    --将无符号值(4位)转换为十六进制数字(0-F)
    函数返回的字符为_HexChar(值:无符号)
    常量十六进制:字符串:=“0123456789ABCDEF”;
    开始
    如果(值<16),则
    返回十六进制(到_整数(值)+1);
    其他的
    返回'X';
    如果结束;
    末端功能;
    --如果输入为2的幂,则返回TRUE
    函数div_ceil(a:NATURAL;b:POSITIVE)返回的自然值是--计算:ceil(a/b)
    开始
    返回(a+(b-1))/b;
    末端功能;
    --返回log2;总是围捕
    函数log2ceil(arg:正)返回自然值
    变量tmp:正;
    可变对数:自然对数;
    开始
    如果arg=1,则返回0;如果结束;
    tmp:=1;
    对数:=0;
    而arg>tmp循环
    tmp:=tmp*2;
    log:=log+1;
    端环;
    返回日志;
    末端功能;
    

    注意:这些函数不在
    0x

    前加前缀,假设是整数
    i
    ,并且VHDL-2008,您可以使用:

    write(output, integer'image(i) & LF);  -- Plain integer value
    write(output, "0x" & to_hstring(to_signed(i, 32)) & LF);  -- Hexadecimal representation
    
    您需要
    使用std.textio.all以使其工作。更改
    32
    以减少十六进制值的长度。我选择了32,以便它可以在大多数模拟器中表示任何整数值

    这些也适用于
    报告
    语句,例如

    report "i = 0x" & to_hstring(to_signed(i, 32));
    

    您可以使用IEEE.std_logic_textio
    包中的
    hwrite
    过程:

    library IEEE;                                                   -- ADDED
    use IEEE.std_logic_1164.all;                                    -- ADDED
    use IEEE.numeric_std.all;                                       -- ADDED
    use IEEE.std_logic_textio.all;                                  -- ADDED
    
    library std;
    use std.textio.all;
    
    entity min is
    end min;
    
    architecture behav of min is
    begin
        process is
            variable my_line : line;
        begin
            hwrite(my_line, std_logic_vector(to_unsigned(16,8)));   -- CHANGED
            writeline(output, my_line);
            wait;
        end process;
    end behav;
    
    hwrite
    过程将
    std_逻辑_向量
    写入文件。因此,您必须将
    整数
    转换为
    标准逻辑向量
    (这也需要您在
    to_unsigned
    函数中指定一定数量的位)


    @downvorters:请解释一下,这样我就可以学习和提高;-)。整数标量是一种离散类型,其位置为整数值(IEEE Std 1076-2008,5.2标量类型),integr没有位。您可以编写一个函数,将整数值转换为base16,该函数适用于基于文字等价物的字符串表示法(15.5.3),或者将整数值转换为以数字表示二进制位且其字符串表示形式具有位字符串等价物的类型(15.8).我们能从输入中计算出
    32
    吗?我知道
    integer'high
    属性,但是还有更直接的吗?是的,你可以用这样的答案来计算所需的宽度:什么,没有函数div?