如何在VHDL中将无符号类型写入文件?

如何在VHDL中将无符号类型写入文件?,vhdl,Vhdl,我有一些48位无符号数字,我想从我的VHDL测试台写入一个文件。不幸的是,我过去一直采用的转换为整数的方法对大于32位的数字不起作用 write(L=>result_line, value=>to_integer(unsigned(C_combo_out))); 下面是我在使用小于32位的数字时一直使用的方法 write(L=>result_line, value=>to_integer(unsigned(C_combo_out))); 下面是我想做的,但不支持无符号

我有一些48位无符号数字,我想从我的VHDL测试台写入一个文件。不幸的是,我过去一直采用的转换为整数的方法对大于32位的数字不起作用

write(L=>result_line, value=>to_integer(unsigned(C_combo_out)));
下面是我在使用小于32位的数字时一直使用的方法

write(L=>result_line, value=>to_integer(unsigned(C_combo_out)));
下面是我想做的,但不支持无符号类型

write(L=>result_line, value=>unsigned(C_combo_out));

C_combo_out
是表示无符号整数的48位标准逻辑向量。请注意,我确实希望输出文件中有数字,而不是“1”和“0”字符串。

所以需要以10为基数的数字

导出大量的base 16将非常简单,特别是当其他工具或语言后期处理您的输出时。基数为10且大于2**31的数量需要特殊处理

您可以使用将如此大的数字转换为BCD表示,然后将BCD数字转换为ASCII以进行文件导出

这应将大型std_逻辑_向量转换为十进制数:

function raw_format_slv_dec(slv : STD_LOGIC_VECTOR) return STRING is
  function div_ceil(a : NATURAL; b : POSITIVE) return NATURAL is  -- calculates: ceil(a / b)
  begin
    return (a + (b - 1)) / b;
  end function;

  variable Result     : STRING(1 to div_ceil(slv'length, 3));

  subtype TT_BCD      is INTEGER range 0 to 31;
  type TT_BCD_VECTOR  is array(natural range <>) of TT_BCD;

  variable Temp   : TT_BCD_VECTOR(div_ceil(slv'length, 3) - 1 downto 0)    := (others => 0);
  variable Carry  : T_UINT_8;

begin
  for i in slv'range loop
    if (slv(i) = '0') then
      Carry      := 0;
    else
      Carry      := 1;
    end if;
    for j in Temp'reverse_range loop
      Temp(j)    := Temp(j) * 2 + Carry;
      if (Temp(j) > 9) then
        Carry    := 1;
        Temp(j)  := Temp(j) - 10;
      else
        Carry    := 0;
      end if;
    end loop;
  end loop;

  for i in Result'range loop
    Result(i)    := CHARACTER'val(to_integer(Temp(Temp'high - i + 1)));
  end loop;

  -- trim leading zeros, except the last
  return Result;
end function;
函数原始格式slv dec(slv:STD逻辑向量)返回字符串为
函数div_ceil(a:NATURAL;b:POSITIVE)返回的自然值是--计算:ceil(a/b)
开始
返回(a+(b-1))/b;
末端功能;
可变结果:字符串(1到div_ceil(slv'length,3));
子类型TT_BCD是0到31之间的整数范围;
类型TT_BCD_向量是TT_BCD的数组(自然范围);
变量温度:TT_BCD_VECTOR(div_ceil(slv'length,3)-1到0):=(其他=>0);
可变进位:T_UINT_8;
开始
对于slv范围循环中的i
如果(slv(i)=“0”),则
进位:=0;
其他的
进位:=1;
如果结束;
用于温度反向范围回路中的j
温度(j):=温度(j)*2+进位;
如果(温度(j)>9),则
进位:=1;
温度(j):=温度(j)-10;
其他的
进位:=0;
如果结束;
端环;
端环;
对于结果范围循环中的i
结果(i):=字符'val(到整数(Temp(Temp'high-i+1));
端环;
--修剪前导零,最后一个除外
返回结果;
末端功能;
已将扩展版本上载到

附录:在PoC.strings包上运行测试台 PoC库带有测试台,所以您可以从控制台运行它。需要执行4个简单步骤:

  • 配置您首选的模拟器工具链:

    cd
    ./poc.sh—配置
    
  • : 从template
    /src/common/my_project.vhdl.template
    /tb/common/
    中创建my_project.vhdl。使用该文件配置两个常量

  • :

    cd/tb
    ./testbench.sh--isim PoC.common.strings-g
    
  • 如果在不使用
    -g
    的情况下运行模拟,则应如下所示:


    (可点击)

    如果使用选项
    -g
    运行模拟,它将在GUI模式下运行,如下所示:


    (可点击)

    更多信息:
    -
    -


    如果您还有其他问题,请参阅该文件并直接与我或我的同事联系。

    很抱歉,我的解决方案中存在一些错误。我将log10ceil更改为div_ceil(长度,3),以近似结果长度。一个修剪前导零的版本被上传到Paebbels,这个函数非常聪明,但一种设计用于描述数字逻辑的语言肯定有一种更直接的方法来打印以10为基数的大数字。64位数字并不罕见。在我看来,没有其他或更短的方法,因为VHDL不能处理2^31-1以上的数字。我从来没有说过64位数字是罕见的,但以十进制形式导出大于2^32的数字是不寻常的,因此十六进制格式是存在的……我尝试使用您的PoC库来获得以十进制格式将大量数字打印到文件的能力,但我从未让您的原始格式\u slv\u dec()函数在我的模拟中工作。我收到了关于索引超出范围的各种运行时错误。您是否有一个将此函数与write()函数一起使用的工作示例?@Pedro_Uno我用附录扩展了我的答案,介绍了如何运行PoC的测试台以及如何运行strings测试台。GitHub上的wiki页面是新的,所以请忽略我的错误或报告这些错误,这样我就可以修复它们:)。[rant alert]我真的很惊讶数字设计工具在过去20年中进步如此之慢。摆弄这些低水平的HDL必须结束。即使是中等规模的FPGA现在也是巨大的。一个人必须花一天的时间才能弄清楚如何将48位无符号十进制数写入文本文件,这一事实本身就是可耻的。15年前,write()函数应该重载以处理有符号和无符号类型。需要有一种更好的方式,像gnu和linux那样,将新特性推到工具的上游。我厌倦了这种摆弄。
    cd <PoCRoot>/tb
    ./testbench.sh --isim PoC.common.strings -g