VHDL:连接2个向量-得到的向量方向是什么?

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

论文: Xilinx XST在连接这些向量后反转向量的方向

我有一个SATA控制器和一个Picobaze软核CPU。该CPU使用寄存器接口+交叉时钟来读取/写入测试数据。CPU写入六个8位寄存器,这些寄存器为读取请求存储24位偏移量和24位长度字段。这些地址和长度字段扩展为48位关键字:LBA-48寻址模式

看起来怎么样

附录-功能声明: 调整大小功能:

-- 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"