xxx 的 VHDL 类型与 xxx 的类型不兼容

VHDL Type of xxx is incompatible with type of xxx

我有两种不同的类型:

type signal_4bit_t is
record
   signals_v      : STD_ULOGIC_VECTOR (3 downto 0);
end record;

 type signal_8bit_t is
record
   signals_v      : STD_ULOGIC_VECTOR (7 downto 0);
end record;

我创建了两个数组:

 type Array_signal_4bit_t   is array (0 to 2) of signal_4bit_t;
 type Array_signal_8bit_t   is array (0 to 2) of signal_8bit_t;

并且一个实体使用 4 位数组作为输入:

entity test_input is
    Port ( 
           hx_i      : in  Array_signal_4bit_t;
           lx_i      : in  Array_signal_4bit_t;
          );
end test;

另一个使用 8 位数组作为输出:

entity test_ouput is
    Port ( 
           out_o      : out Array_signal_8bit_t
          );
end test;

对于两个组件之间的连接,我使用信号:

signal tets_out_to_test_in   : Array_signal_8bit_t;

实例化看起来像这样:

in: test_input 
    Port Map ( 
           hx_i  =>    tets_out_to_test_in(7 downto 4),
           lx_i  =>    tets_out_to_test_in(3 downto 0)
          );

out: test_out 
    Port Map ( 
           out_o  =>    tets_out_to_test_in
          );

现在我得到错误 "Type of hx_i is incompatible with type of tets_out_to_test_in. I see that Array_signal_4bit_t is different to Array_signal_8bit_t, but is there a "easy" 解决这个问题的方法而不改变我的实体?或者知道如何解决这个问题?

您的代码有 2 个问题:

  1. 您必须解决记录的成员才能访问内部 std_ulogic_vectors。
  2. 您必须遍历向量 test_out_to_test_in 的每个索引,以将其分配给结果向量。这可以通过生成语句或进程(不是很好的解决方案)或函数(很好的解决方案)来完成。

信号:

signal test_out_to_test_in   : Array_signal_8bit_t;
signal test_in_lo            : Array_signal_4bit_t;
signal test_in_hi            : Array_signal_4bit_t;

实例:

out: test_out 
  Port Map ( 
    out_o  =>  test_out_to_test_in
  );

gen : for i in test_out_to_test_in'range generate
  test_in_lo(i).signals_v   <= test_out_to_test_in(i).signals_v(3 downto 0);
  test_in_hi(i).signals_v   <= test_out_to_test_in(i).signals_v(7 downto 4);
end generate;

in: test_input 
  Port Map ( 
    hx_i  =>    test_in_hi,
    lx_i  =>    test_in_lo
  );

您确定要使用记录,甚至不使用子类型吗?

编辑 1:

如果您只想创建一个 std_ulogic_vector 4 位的新类型,那么您可以使用子类型:

subtype signal_4bit_t is STD_ULOGIC_VECTOR (3 downto 0);
subtype signal_8bit_t is STD_ULOGIC_VECTOR (7 downto 0);

在大多数情况下,让数组类型不受约束会更灵活:

type Array_signal_4bit_t is array (NATURAL range <>) of signal_4bit_t;
type Array_signal_8bit_t is array (NATURAL range <>) of signal_8bit_t;

现在您的分配代码如下所示:

signal test_out_to_test_in   : Array_signal_8bit_t(0 to 2);
signal test_in_lo            : Array_signal_4bit_t(0 to 2);
signal test_in_hi            : Array_signal_4bit_t(0 to 2);

out: test_out 
  Port Map ( 
    out_o  =>  test_out_to_test_in
  );

gen : for i in test_out_to_test_in'range generate
  test_in_lo(i)   <= test_out_to_test_in(i)(3 downto 0);
  test_in_hi(i)   <= test_out_to_test_in(i)(7 downto 4);
end generate;

in: test_input 
  Port Map ( 
    hx_i  =>    test_in_hi,
    lx_i  =>    test_in_lo
  );

编辑 2:

您可以通过编写一个函数来隐藏现在使用生成语句的转换代码:

function to_4bit_hi(value : Array_signal_8bit_t) return Array_signal_4bit_t is
  variable Result : Array_signal_4bit_t;
begin
  for i in value'range loop
    Result(i) <= value(i)(7 downto 4);
  end loop;
  return Result;
end function;

您将需要 3 downto 0 的第二个函数,或者您将偏移量作为参数传递给该函数。并非所有工具都支持在端口映射中使用函数,因此您仍然需要两个额外的信号。

signal test_out_to_test_in   : Array_signal_8bit_t(0 to 2);
signal test_in_lo            : Array_signal_4bit_t(0 to 2);
signal test_in_hi            : Array_signal_4bit_t(0 to 2);

out: test_out 
  Port Map ( 
    out_o  =>  test_out_to_test_in
  );

test_in_lo   <= to_4bit_lo(test_out_to_test_in);
test_in_hi   <= to_4bit_hi(test_out_to_test_in);

in: test_input 
  Port Map ( 
    hx_i  =>    test_in_hi,
    lx_i  =>    test_in_lo
  );

如果您对更多向量操作函数和过程感兴趣,请查看此包:https://code.google.com/p/picoblaze-library/source/browse/vhdl/lib_PoC/vectors.vhdl?name=release

创建一个最小的、可验证的和完整的例子:

library ieee;
use ieee.std_logic_1164.all;

package somepack is
    type signal_4bit_t is
    record
       signals_v      : std_ulogic_vector (3 downto 0);
    end record;

     type signal_8bit_t is
    record
       signals_v      : std_ulogic_vector (7 downto 0);
    end record;
    type array_signal_4bit_t   is array (0 to 2) of signal_4bit_t;
    type array_signal_8bit_t   is array (0 to 2) of signal_8bit_t;
end package;

use work.somepack.all;
entity test_input is
    port ( 
           hx_i      : in  array_signal_4bit_t;
           lx_i      : in  array_signal_4bit_t
         );
end test_input;

architecture foo of test_input is
begin
end architecture;

use work.somepack.all;
entity test_output is
    port ( 
           out_o      : out array_signal_8bit_t
         );
end test_output;

architecture foo of test_output is
begin
end architecture;

library ieee;
use ieee.std_logic_1164.all;
use work.somepack.all;

entity sometestbench is
end entity;

architecture foo of sometestbench is
    signal tets_out_to_test_in: array_signal_8bit_t;
    component test_input is
        port (
            hx_i: in  array_signal_4bit_t;
            lx_i: in  array_signal_4bit_t
        );
    end component;
    component test_output is
        port (
           out_o      : out array_signal_8bit_t        
        );
    end component;    

    signal hx_i_high: array_signal_4bit_t;
    signal lx_i_low:  array_signal_4bit_t;

begin

    hx_i_high(0).signals_v <= tets_out_to_test_in(0).signals_v(7 downto 4);
    hx_i_high(1).signals_v <= tets_out_to_test_in(1).signals_v(7 downto 4);
    hx_i_high(2).signals_v <= tets_out_to_test_in(2).signals_v(7 downto 4);
    lx_i_low(0).signals_v  <= tets_out_to_test_in(0).signals_v(3 downto 0);
    lx_i_low(1).signals_v  <= tets_out_to_test_in(1).signals_v(3 downto 0);
    lx_i_low(2).signals_v  <= tets_out_to_test_in(2).signals_v(3 downto 0);                

label_in: test_input 
    port map ( 
          --  hx_i  =>    tets_out_to_test_in(7 downto 4),
          hx_i => hx_i_high,
          --lx_i  =>    tets_out_to_test_in(3 downto 0)
          lx_i => lx_i_low
    );


label_out: test_output 
    port map ( 
           out_o  =>    tets_out_to_test_in
          );    
end architecture;

存在各种标点符号问题和拼写不匹配,in 和 out 不能用作标识符(标签)它们是保留字。组件 test_out 应该是 test_output,...

还有更直接一点的,从 array_signal_8bit_t 类型中提取的元素构造一个 array_signal_4bit_t 类型:

    hx_i_high <= array_signal_4bit_t'(
               0 => (signals_v => tets_out_to_test_in(0).signals_v(7 downto 4)),
               1 => (signals_v => tets_out_to_test_in(1).signals_v(7 downto 4)),
               2 => (signals_v => tets_out_to_test_in(2).signals_v(7 downto 4))
               );

    lx_i_low <= array_signal_4bit_t'(
               0 => (signals_v => tets_out_to_test_in(0).signals_v(3 downto 0)),
               1 => (signals_v => tets_out_to_test_in(1).signals_v(3 downto 0)),
               2 => (signals_v => tets_out_to_test_in(2).signals_v(3 downto 0))
               );

你不能在实际的关联列表中这样做,因为限定表达式的表达式操作数必须是全局静态的(历史上 (-1993) 并且可能用于合成仍然)。 (在 IEEE 标准 1076-2008 中,6.5.6.3 端口条款,第 6 段):

If the actual part of a given association element for a formal port of a block is the reserved word inertial followed by an expression, or is an expression that is not globally static, then the given association element is equivalent to association of the port with an anonymous signal implicitly declared in the declarative region that immediately encloses the block. The signal has the same subtype as the formal port and is the target of an implicit concurrent signal assignment statement of the form

anonymous <= E;  

where E is the expression in the actual part of the given association element. The concurrent signal assignment statement occurs in the same statement part as the block.

上面的例子也说明了你不必有一个循环。

这个 MVCe 分析、阐述和模拟(同时没有做任何特别有趣的事情)。

稍微不同的架构使用了一个过程:

architecture fie of sometestbench is
    signal tets_out_to_test_in: array_signal_8bit_t;
    component test_input is
        port (
            hx_i: in  array_signal_4bit_t;
            lx_i: in  array_signal_4bit_t
        );
    end component;
    component test_output is
        port (
           out_o      : out array_signal_8bit_t        
        );
    end component;    

    signal hx_i_high: array_signal_4bit_t;
    signal lx_i_low:  array_signal_4bit_t;

    procedure slice_array_signal_8bit (
            signal input:   in  array_signal_8bit_t; 
            signal low:     out array_signal_4bit_t;
            signal high:    out array_signal_4bit_t
    ) is
    begin
        for i in array_signal_4bit_t'range loop
            high(i).signals_v <= input(i).signals_v(7 downto 4);
            low(i).signals_v  <= input(i).signals_v(3 downto 0);
        end loop;
    end procedure;

begin

BREAKOUT: 
slice_array_signal_8bit ( tets_out_to_test_in, hx_i_high, lx_i_low);             

label_in: test_input 
    port map ( 
          hx_i => hx_i_high,
          lx_i => lx_i_low
    );


label_out: test_output 
    port map ( 
           out_o  =>    tets_out_to_test_in
          );    
end architecture;

其中还告诉我们如何使用进程语句:

architecture foe of sometestbench is
    signal tets_out_to_test_in: array_signal_8bit_t;
    component test_input is
        port (
            hx_i: in  array_signal_4bit_t;
            lx_i: in  array_signal_4bit_t
        );
    end component;
    component test_output is
        port (
           out_o      : out array_signal_8bit_t        
        );
    end component;    

    signal hx_i_high: array_signal_4bit_t;
    signal lx_i_low:  array_signal_4bit_t;

begin

BREAKOUT: 
    process (tets_out_to_test_in)
    begin
        for i in array_signal_4bit_t'range loop
            hx_i_high(i).signals_v <= tets_out_to_test_in(i).signals_v(7 downto 4);
            lx_i_low(i).signals_v  <= tets_out_to_test_in(i).signals_v(3 downto 0);
        end loop;
    end process;          

label_in: test_input 
    port map ( 
          hx_i => hx_i_high,
          lx_i => lx_i_low
    );


label_out: test_output 
    port map ( 
           out_o  =>    tets_out_to_test_in
          );    
end architecture;

最后,最简单的方法:

architecture fum of sometestbench is
    signal tets_out_to_test_in: array_signal_8bit_t;
    component test_input is
        port (
            hx_i: in  array_signal_4bit_t;
            lx_i: in  array_signal_4bit_t
        );
    end component;
    component test_output is
        port (
           out_o      : out array_signal_8bit_t
        );
    end component;
begin

label_in: test_input
    port map (
          hx_i(0).signals_v => tets_out_to_test_in(0).signals_v(7 downto 4),
          hx_i(1).signals_v => tets_out_to_test_in(1).signals_v(7 downto 4),
          hx_i(2).signals_v => tets_out_to_test_in(2).signals_v(7 downto 4),
          lx_i(0).signals_v => tets_out_to_test_in(0).signals_v(3 downto 0),
          lx_i(1).signals_v => tets_out_to_test_in(1).signals_v(3 downto 0),
          lx_i(2).signals_v => tets_out_to_test_in(2).signals_v(3 downto 0)
    );

label_out: test_output
    port map (
           out_o  =>    tets_out_to_test_in
          );
end architecture;

我们可以将正式复合类型的元素分别映射到端口关联列表中的实际元素。而且这个表格应该符合合成条件。