【问题标题】:Converting C Macro to VHDL将 C 宏转换为 VHDL
【发布时间】:2014-02-24 04:13:06
【问题描述】:

我对 VHDL 相当陌生,并试图将两个给定的 C 宏转换为在我的 FPGA 上作为一条指令执行。宏是:

#define m_in_bits(buf, num) (buf) >> (24 - (num)) // buf is uint32_t
#define m_ext_bits(buf, i) ((buf) < (1<<((i)-1)) ? (buf) + (((-1)<<(i)) + 1) : (buf))

而使用宏的C代码是:

m_ext_bits(m_in_bits(buffer, size), size);

我在让m_ext_bits 正确编译时遇到问题。这是我的 VHDL:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity myEntity is
port(
  signal buffer: in std_logic_vector(31 downto 0);
  signal result: out std_logic_vector(31 downto 0)
);
end entity myEntity;

architecture myArch of myEntity  is
  signal size : signed (3 downto 0);
begin

size <= signed(buffer(27 downto 24));

result(15 downto 0) <= std_logic_vector(signed(buffer(23 downto 0)) srl (24 - to_integer(size))
                     + signed((-1 sll to_integer(size)) + 1)); -- the offending line

end architecture myArch ;

result(15 downto 0) &lt;= 开头的长行实际上编译时没有错误(实现了m_in_bits 宏)。但是,当我添加以+ 开头的以下行时,会发生错误。我试着玩转 std_logic_vectorsigned 类型并且错误发生了变化。

表达式类型不明确 - “SIGNED”或“UNSIGNED”是两个可能的匹配项...
无法确定运算符 ""sll"" 的定义 -- 找到 0 个可能的定义...
表达式中的非法签名...

我认为这是正确转换和使用正确类型来完成所需操作的问题。

【问题讨论】:

标签: c vhdl


【解决方案1】:

首先,buffer 是一个保留的 VHDL 字,所以改变它;在下面使用argbuf

表达式-1 sll to_integer(size) 没有在 VHDL 中定义,因为 整数值-1 只是一个没有位表示的数值表达式 由 VHDL 指定,因此无法进行移位。也不是这样的操作 整数上的按位与、或等。可以将 24 位 signed 类型的 -1 表示创建为:

to_signed(-1, 24)

分配存在长度问题,因为 16 位信号 (result(15 downto 0)) 被分配了 24 位值(基于右侧 argbuf(23 downto 0))。

srl 应在解决上述问题后编译。

代码为:

result(15 downto 0) <= std_logic_vector(resize((signed(argbuf(23 downto 0)) srl (24 - to_integer(size)))
                                               + signed((to_signed(-1, 24) sll to_integer(size)) + 1), 16));

但是,VHDL 移位运算符,例如srl,可能会产生意想不到的结果,如 在此页面中描述"Arithmetic and logical shifts and rotates are done with functions in VHDL, not operators", 因此您可以考虑使用 numeric_std 中定义的移位函数, 例如shift_right,作为一般的编码风格。代码如下:

result(15 downto 0) <= std_logic_vector(resize(shift_right(signed(argbuf(23 downto 0)), 24 - to_integer(size))
                                               + signed(shift_left(to_signed(-1, 24), to_integer(size)) + 1), 16));

【讨论】:

  • 哎呀,我缩短了问题的变量名,最后得到了buffer,但感谢您的提示。我想到了result 的长度问题,但在实践中,右移可确保该值适合 16 位(或者可以被截断)。那么,如何创建相当于左移-1的值呢?
  • 对于 -1 移位,转换为有符号移位。对于长度调整,请使用resize 明确进行。请参阅上面添加到答案的代码。
猜你喜欢
  • 2021-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-15
  • 2023-02-06
  • 2017-10-14
  • 1970-01-01
相关资源
最近更新 更多