我对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) <=
开头的长行实际上编译时没有错误(实现m_in_bits
宏)。但是,当我添加以下行时,从+
开始,会发生错误。我尝试使用std_logic_vector
和signed
类型,并且错误会发生变化。
表达的类型不明确 - &#34; SIGNED&#34;或者&#34; UNSIGNED&#34;是两个可能的比赛...
无法确定运营商的定义&#34;&#34; sll&#34;&#34; - 找到0个可能的定义......
非法签字表达......
我认为这是一个正确的铸造和使用正确类型来完成所需操作的问题。
答案 0 :(得分:2)
首先,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函数,
例如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));