VHDL:连接2个向量-得到的向量方向是什么?
论文: Xilinx XST在连接这些向量后反转向量的方向 我有一个SATA控制器和一个Picobaze软核CPU。该CPU使用寄存器接口+交叉时钟来读取/写入测试数据。CPU写入六个8位寄存器,这些寄存器为读取请求存储24位偏移量和24位长度字段。这些地址和长度字段扩展为48位关键字:LBA-48寻址模式 看起来怎么样 附录-功能声明: 调整大小功能:VHDL:连接2个向量-得到的向量方向是什么?,vhdl,xilinx-ise,Vhdl,Xilinx Ise,论文: Xilinx XST在连接这些向量后反转向量的方向 我有一个SATA控制器和一个Picobaze软核CPU。该CPU使用寄存器接口+交叉时钟来读取/写入测试数据。CPU写入六个8位寄存器,这些寄存器为读取请求存储24位偏移量和24位长度字段。这些地址和长度字段扩展为48位关键字:LBA-48寻址模式 看起来怎么样 附录-功能声明: 调整大小功能: -- Resizes the vector to the specified length. The adjustment is make o
-- Resizes the vector to the specified length. The adjustment is make on
-- on the 'high end of the vector. The 'low index remains as in the argument.
-- If the result vector is larger, the extension uses the provided fill value
-- (default: '0').
-- Use the resize functions of the numeric_std package for value-preserving
-- resizes of the signed and unsigned data types.
function resize(vec : std_logic_vector; length : natural; fill : std_logic := '0') return std_logic_vector is
constant high2b : natural := vec'low+length-1;
constant highcp : natural := imin(vec'high, high2b);
variable res_up : std_logic_vector(vec'low to high2b);
variable res_dn : std_logic_vector(high2b downto vec'low);
begin
if vec'ascending then
res_up := (others => fill);
res_up(vec'low to highcp) := vec(vec'low to highcp);
return res_up;
else
res_dn := (others => fill);
res_dn(highcp downto vec'low) := vec(highcp downto vec'low);
return res_dn;
end if;
end function;
function imin(arg1 : integer; arg2 : integer) return integer is
begin
if arg1 < arg2 then return arg1; end if;
return arg2;
end function;
function descend(vec : std_logic_vector) return std_logic_vector is
variable res : std_logic_vector(vec'high downto vec'low);
begin
res := vec;
return res;
end function;
T_SLV_代表类型;标准逻辑向量;n位->n-1降为0,并将其作为MCVe:
library ieee;
use ieee.std_logic_1164.all;
entity sync is
end entity;
architecture mcve of sync is
subtype T_SLV_24 is std_logic_vector(23 downto 0);
subtype T_SLV_48 is std_logic_vector(47 downto 0);
-- register values after cross clocking with double FFs
signal sync_Offset : T_SLV_24 := x"deadbe";
signal sync_Length : T_SLV_24 := x"feedfa";
-- output signals for LBA-48 addressing
signal Address_LB : T_SLV_48; -- std_logic_vector(47 downto 0)
signal BlockCount_LB : T_SLV_48;
function MINIMUM (l,r: integer) return integer is
begin
if l > r then
return r;
else
return l;
end if;
end function;
-- [...]
-- Resizes the vector to the specified length. The adjustment is make on
-- on the 'high end of the vector. The 'low index remains as in the argument.
-- If the result vector is larger, the extension uses the provided fill value
-- (default: '0').
-- Use the resize functions of the numeric_std package for value-preserving
-- resizes of the signed and unsigned data types.
function resize(vec : std_logic_vector; length : natural; fill : std_logic := '0') return std_logic_vector is
constant high2b : natural := vec'low+length-1;
constant highcp : natural := MINIMUM(vec'high, high2b); -- imin
variable res_up : std_logic_vector(vec'low to high2b);
variable res_dn : std_logic_vector(high2b downto vec'low);
begin
if vec'ascending then
res_up := (others => fill);
res_up(vec'low to highcp) := vec(vec'low to highcp);
return res_up;
else
res_dn := (others => fill);
res_dn(highcp downto vec'low) := vec(highcp downto vec'low);
return res_dn;
end if;
end function;
function descend(vec : std_logic_vector) return std_logic_vector is
variable res : std_logic_vector(vec'high downto vec'low);
begin
res := vec;
return res;
end function;
function to_string(inp: std_logic_vector) return string is
variable image_str: string (1 to inp'length);
alias input_str: std_logic_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
end loop;
return image_str;
end;
begin
-- [...]
-- SLL 7 -> granularity for logical blocks is 1 MiB
-- Address_LB <= resize(sync_Offset & "0000000", Address_LB'length);
-- BlockCount_LB <= resize(sync_Length & "0000000", BlockCount_LB'length);
Address_LB <= resize(descend(sync_Offset & "0000000"), Address_LB'length);
BlockCount_LB <= resize(descend(sync_Length & "0000000"), BlockCount_LB'length);
Process (Address_LB, BlockCount_LB)
begin
report "Address_LB = " & to_string(Address_LB) Severity NOTE;
report "BlockCount_LB = " & to_string(BlockCount_LB) Severity NOTE;
end process;
end architecture;
请注意,未提供本地函数最小值而不是imin,并且此ghdl符合-1993的to_字符串的本地副本。还要注意带有局部最小值的最小上下文子句
这使得:
ghdl-sync.vhdl
ghdl-e同步
ghdl-r同步
sync.vhdl:75:9:@0ms:report note:Address_LB=uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
sync.vhdl:76:9:@0ms:report note:BlockCount_LB=uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
sync.vhdl:75:9:@0ms:报告注释:地址\u LB=000000000000000001101111010101101111100000000
sync.vhdl:76:9:@0ms:report note:BlockCount_LB=000000000000000001111111111101110100000000
地址看起来不错
0000 0000 0000 0000 0 1111 1110 1110 1101 1111 1010 000 0000
F E E D F A
BlockCount_LB也是如此
没有下降调用原始分配:
Address_LB <= resize(sync_Offset & "0000000", Address_LB'length);
BlockCount_LB <= resize(sync_Length & "0000000", BlockCount_LB'length);
及
这看起来不像是一个问题,实际上是说你应该提供一个MCVe。这些确实看起来像您从读取调整大小函数中所期望的
这是语言特性还是特定于工具?
我使用Xilinx XST进行这些测试。
在ghdl工作。特定于工具。我还将仔细研究XST支持的VHDL结构
何处定义了&d?
定义类型后,将立即定义它,以及用于一维数组类型和基本操作的其他预定义运算符。注:我使用了一个子类型,因此在本例中,这些隐式声明出现在std_logic_1164包中,紧随std_logic_vector std_ulogic_vector,-2008的声明之后
结果向量方向是什么
等向向量和
反向定向向量?
嗯?再试试这个,佩培尔。赋值是从左到右关联,从左元素到左元素。。。右元素到右元素。没有保留的数据,这将需要下降中的循环或接口列表中的子类型指示,但这样就不能使用任何长度
就我个人而言,我不认为编写函数来实现这一点有什么意义。简单地使用串联应该是合成安全的。串联运算符&在VHDL标准中定义,例如。 VHDL-2008第9.2.5节添加运算符,其中包含相关信息 关于方向和范围是: a。。。设S为结果基类型的索引子类型。 连接结果的方向是方向 结果的左界是S的左 对于类型std_逻辑,向量是std_逻辑的数组自然范围;或 类似地,索引子类型是自然的,具有上升方向 自然“升序=真,左边界0自然”左=0 因此,std_逻辑_向量的串联结果以0的左界递增,这也是sync_Offset&0000000的情况。唯一的例外是两个零长度数组的串联,它返回正确的参数 您编写的resize函数将把vec参数放置到 在结果中保留,并用fill填充,因此我希望结果来自:
resize(sync_Offset & "0000000", Address_LB'length);
将是:
sync_Offset & "000...000"
如果结果中sync_Offset值左侧有任何0,则
这听起来像是一个问题,无论是在您的结果解释或XST少
很可能
顺便说一句,将函数的调整大小名称重新用于除
调整未签名文件的大小可能会导致混淆。为了完整起见,您可以包括T_SLV_24和地址的类型吗?还有,这里有哪些库和包?@Josh T_SLV_24是一个24位std_逻辑向量范围23..0。地址LB是一个T_SLV_48->我在信号声明中删除了SATA_uu前缀。“编辑1”部分列出了涉及的包。我还修复了resize,因为我复制了位向量版本。本例使用标准逻辑向量版本。代码是一样的,除了使用的类型。a如何?处理函数中升序与降序范围的正确方法可能是使用别名,它允许您定义它,并且后续赋值是左右关联的,而不考虑升序或降序。
signal sync_Offset : T_SLV_24 := x"deadbe";
signal sync_Length : T_SLV_24 := x"feedfa";
0000 0000 0000 0000 0 1101 1110 1010 1101 1011 1110 000 0000
D E A D B E
0000 0000 0000 0000 0 1111 1110 1110 1101 1111 1010 000 0000
F E E D F A
Address_LB <= resize(sync_Offset & "0000000", Address_LB'length);
BlockCount_LB <= resize(sync_Length & "0000000", BlockCount_LB'length);
D E A D B E 0000 0000 0000 0000 0000 0000
F E E D F A 0000 0000 0000 0000 0000 0000
resize(sync_Offset & "0000000", Address_LB'length);
sync_Offset & "000...000"