【问题标题】:How can I write unsigned type to file in VHDL?如何将无符号类型写入 VHDL 文件?
【发布时间】:2015-07-17 20:55:05
【问题描述】:

我有一些 48 位无符号数字,我想从我的 VHDL 测试台写入文件。不幸的是,我过去一直这样做的方式,转换为整数,不适用于大于 32 位的数字。

这是我一直使用小于 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 位 std_logic_vector,表示一个无符号整数。注意,我真的想要输出文件中的数字,而不是“1”和“0”的字符串。

【问题讨论】:

  • 抱歉,我的解决方案存在一些问题。我将 log10ceil 更改为 div_ceil(length, 3) 以近似结果长度。修剪前导零的版本已上传到PoC.Strings

标签: vhdl


【解决方案1】:

所以你需要以 10 为底的数字?

导出大量以 16 为基的数字非常简单,尤其是在其他工具或语言对您的输出进行后处理时。以 10 为底且大于 2**31 的数需要特殊处理。

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

这应该将大的 std_logic_vectors 转换为十进制数:

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;

扩展版已上传至PoC's strings package

附录:在 PoC.strings 包上运行测试台

PoC-Library 带有测试平台,因此您可以从控制台运行它。有4个简单的步骤,需要执行:

  1. Download PoC
  2. 配置您喜欢的模拟器工具链:

    cd <PoCRoot>
    ./poc.sh --configure
    
  3. Setup: 从模板&lt;PoCRoot&gt;/src/common/my_project.vhdl.template&lt;PoCRoot&gt;/tb/common/ 中创建一个my_project.vhdl。使用该文件配置两个常量。

  4. Run the simulation:

    cd <PoCRoot>/tb
    ./testbench.sh --isim PoC.common.strings -g
    

如果您在没有-g 的情况下运行模拟,它应该如下所示:


(可点击)

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


(可点击)

更多信息:
- List of used files
- Testbench

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

【讨论】:

  • Paebbels,该功能非常聪明,但设计用于描述数字逻辑的语言肯定有更直接的方式来打印以 10 为底的大数。64 位数字并不罕见。
  • 在我看来,没有其他或更短的方法,因为VHDL无法处理2^31-1以上的数字。我从来没有说过64位数字很少见,但是以十进制导出大于2^32的数字是不寻常的,因此存在十六进制格式...
  • 好吧,我尝试使用你的 PoC 库来获得以十进制格式将大数字打印到文件的能力,但我从来没有让你的 raw_format_slv_dec() 函数在我的模拟中工作。我收到了关于索引超出范围的各种运行时错误。您是否有一个工作示例,可以将此函数与 write() 函数一起使用?
  • @Pedro_Uno 我用附录扩展了我的答案,关于如何运行 PoC 的测试平台以及如何运行字符串测试平台。 GitHub 上的 wiki 页面是新的,所以请忽略我的错误或报告这些错误,以便我修复它们:)。
  • [rant alert] 我真的很惊讶数字设计工具在过去 20 年中改进的速度如此缓慢。必须停止摆弄这些低级 HDL。即使是中型 FPGA 现在也是巨大的。必须花一天时间才能弄清楚如何将 48 位无符号十进制数写入文本文件这一事实是可耻的。 write() 函数应该在 15 年前被重载以处理有符号和无符号类型。需要有一种更好的方法来将新功能向上游推送到工具中,就像 gnu 和 linux 一样。我厌倦了所有这些摆弄。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
  • 2017-05-11
  • 2018-07-16
  • 2011-10-23
相关资源
最近更新 更多