我正在尝试将一个sfixed(从ieee.fixed_pkg)转换为std_logic_vector,我想知道正确的语法是什么以及为什么以下是(显然是错误的)。我尝试编译以下3种架构:
library ieee;
use ieee.std_logic_1164.all;
use ieee.fixed_pkg.all;
entity test is
port (input: in sfixed(0 downto -7) := x"00";
output: out std_logic_vector(7 downto 0) := x"00");
end;
架构a:
architecture a of test is begin
output <= std_logic_vector(input);
end;
架构b:
architecture b of test is begin
proc: process (input) begin
output <= std_logic_vector(input);
end process;
end;
架构c:
architecture c of test is begin
proc: process (input) begin
if ('1' and '1') then
output <= std_logic_vector(input);
end if;
end process;
end;
我使用的编译器是“ModelSim ALTERA vcom 10.3d Compiler 2014.10 Oct 7 2014”。 架构a和b不编译错误消息:
Error: [...] Index value -7 (of type std.STANDARD.NATURAL) is out of range 0 to 2147483647.
但是架构c编译,同时仍然给我警告信息:
Warning: [...] Index value -7 (of type std.STANDARD.NATURAL) is out of range 0 to 2147483647.
所以我的问题是:投出这个的正确方法是什么,为什么上面发布的三种架构之间有什么区别?
答案 0 :(得分:4)
对于带有负面索引的sfixed类型转换导致的范围问题@BrianDrmmond讨论的std_logic_vector是在标准开发过程中发现的问题。对于除GHDL之外的模拟器,这也是一个真正的问题。
因此,包提供了类型转换功能来处理这个问题。要从sfixed或ufixed转换为std_logic_vector,请使用to_slv和to_std_logic_vector:
output <= to_slv(input);
要从std_logic_vector转换为sfixed / ufixed,请使用to_sfixed / to_ufixed之一。有一个将索引作为参数,另一个接受对象。
signal a_sfixed : sfixed(0 downto -7) := x"00";
signal a_slv : std_logic_vector(7 downto 0) := x"00";
a_sfixed <= to_sfixed(a_slv, 0, -7);
. . .
a_sfixed <= to_sfixed(a_slv, a_sfixed);
是的,您可以使用类型转换(也就是转换)来进行赋值而不是上面的操作,但是,如果您希望在表达式中使用转换后的值,则结果的范围将是不正确的,因为它已确定按输入范围。
signal a_sfixed : sfixed(0 downto -7) := x"00";
signal a_slv : std_logic_vector(7 downto 0) := x"00";
signal y_sfixed : sfixed(1 downto -7) := x"00";
y_sfixed <= a_sfixed + to_sfixed(a_slv, 0, -7);
答案 1 :(得分:2)
有趣的是,这可能实际上是VHDL语言本身规范中的灰色区域。对于开源模拟器discussed as a possible "bug"
,同样有问题的转换ghdl.问题的实质是input
被声明为sfixed(0 downto -7)
,而std_logic_vector
的定义要求其索引为natural
,即正整数或0。
因此类型转换为无约束的std_logic_vector
output <= std_logic_vector(input);
继承源向量的边界(0和-7)并失败,因为一个边界超出范围。
有一个简单的解决方法,但是:类型转换为约束 std_logic_vector ...例如std_logic_vector (input'length-1 downto 0)
...使用'length
属性保证是合适的大小。此转换的语义使索引有效,因此转换成功,将最左位转移到最左位,依此类推。
更详细一点,代码如下:
-- declarations
subtype result_type is std_logic_vector (input'length-1 downto 0);
signal output : result_type;
-- assignment
output <= result_type (arg);
我不能保证Altera会接受相同的解决方法,但我有理由相信它会更有效,VHDL也是如此。我还没有尝试将output
声明为您需要的端口。
据我们所知,ghdl(通常对VHDL的解释通常是严格的)在根据VHDL语言参考手册(LRM)和&#34; bug&#34的字母拒绝这个结构时是正确的。 ;因此报告已经结束。
然而,已经从VHDL标准委员会寻求进一步的澄清 - 并且可能未来放宽规则 - IF - 它可以被证明可以完全证明阵列边界错误和缓冲区溢出困扰其他一些语言
答案 2 :(得分:0)
我发现使用David Bishop的fixed_pkg_c(FPHDL,在github上),该帖子在GHDL 0.35(mcode,windows)中也遇到了相同的错误。
请注意,此处的答案似乎正确;为了使GHDL能够进行编译和模拟,我必须在fixed_pkg_c中添加以下内容:
const clonedReq = req.clone({
headers: req.headers.set('Cache-Control','no-cache') . // Header 1
headers: new HttpHeaders({ // Header 2
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'Pragma' : 'no-cache' //IE Ajax cache
})
});
对于固定类型的to_sulv函数,需要进行相同的更改。
我不确定为什么以前使用STD_ULOGIC_VECTOR进行的“类型转换”不起作用,而且我对此还没有花费更多的思考。
如果其他人发现此问题,请更新原始的fixed_pkg_c文件是否在其原始实现中起作用。
答案 3 :(得分:-1)
固定包转换功能不是OP报告的错误的解决方案,请参阅下面转换为std_ulogic_vector的功能的发布。请注意,&#39;结果&#39;是一个std_ulogic_vector,它是通过执行操作数&#39; arg&#39;的类型转换获得的,与OP完全相同(除了OP使用了std_logic_vector)。定点包将产生与OP报告的相同的错误。
-- Conversion functions. These are needed for synthesis where typically
-- the only input and output type is a std_logic_vector.
function to_sulv (
arg : UNRESOLVED_ufixed) -- fixed point vector
return STD_ULOGIC_VECTOR is
variable result : STD_ULOGIC_VECTOR (arg'length-1 downto 0);
begin
if arg'length < 1 then
return NSLV;
end if;
result := STD_ULOGIC_VECTOR (arg);
return result;
end function to_sulv;
KJ