从 16bit unsigned_vector 构造一个 20kbit bit_vector 数据

Constructing a 20kbit bit_vector data from 16bit unsigned_vector

我是 VHDL 的新手,我猜在赋值方面遇到了问题。

假设我有一个模块,它为时钟源的每个上升沿获取一个 16 位输入信号 noisein_mono。我想要的是从这个 16 位输入构造一个 20 Kbit 长的位向量。所以我要对其进行随机数测试 FIPS_140-2

我最终得到的代码如下所示:

-- Entity Decleration
entity MonoTestModule is

Port ( clk                  : in    STD_LOGIC;
       rst                  : in    STD_LOGIC;
       start                : in    STD_LOGIC;
       noisein_mono         : in    STD_LOGIC_VECTOR (15 downto 0);
       running_mono         : out   STD_LOGIC;
       tok_mono             : out   STD_LOGIC     
     );

end MonoTestModule;

architecture Behavioral of MonoTestModule is

-- Signal to communication between processes.
signal enable_20k_bit_stream : std_logic;                                                       

begin
process (rst, clk, start, noisein_mono)
    variable count : integer := 0;                                                                                      
    variable twnty_k_bit_stream : bit_vector(19999 to 0);                                   
    begin
        if(start = '1') then                                                                            
            if (rising_edge(clk)) then                                                      
                count := count + 1;                                                         
                twnty_k_bit_stream := twnty_k_bit_stream or to_bitvector(noisein_mono);
                twnty_k_bit_stream := twnty_k_bit_stream sll 16;
            end if;

            if (rst = '1') then                                                             
                count := 0;                                                                     
                enable_20k_bit_stream <= '0';                                                                           
            end if;

            -- if count is reached to 1250, 20kbit is constructed.
            if(count = 1250) then                                                                   
                enable_20k_bit_stream <= '1';
            else                                                                                            
                enable_20k_bit_stream <= '0';
            end if; 
    end if;
end process;

我正在使用 Xilinx ISE 14.7。编译器弹出错误提示 Line 52: Unequal length arguments for operator "or"。 我该如何解决这个问题?

谨致问候。

在模拟中,这将是两个不同的 运行 时间错误。

实际上有两个边界不匹配错误,一个是针对两个数组值的 "or":

            twnty_k_bit_stream := twnty_k_bit_stream or
                                  to_bitvector(noisein_mono);

还有一个用于分配给 twnty_k_bit_stream,其中长度在隐式子类型转换后不匹配。

那是因为

  variable twnty_k_bit_stream : bit_vector(19999 to 0);

to 应该是 downto。当方向错误时,您将得到一个空范围(一个没有元素的数组)。

参见 IEEE Std 1076-2008 9.2.2 逻辑运算符,第 3 段:

If both operands are one-dimensional arrays, the operands shall be arrays of the same length, the operation is performed on matching elements of the arrays, and the result is an array with the same index range as the left operand. If one operand is a scalar and the other operand is a one-dimensional array, the operation is performed on the scalar operand with each element of the array operand. The result is an array with the same index range as the array operand.

所以不均匀长度数组不起作用。

另见 10.6.2.1(变量赋值),第 5 段和第 7 段:

For the execution of a variable assignment whose target is a variable name, the variable name and the expression are first evaluated. A check is then made that the value of the expression belongs to the subtype of the variable, except in the case of a variable that is of a composite type (in which case the assignment involves a subtype conversion). Finally, each subelement of the variable that is not forced is updated with the corresponding subelement of the expression. A design is erroneous if it depends on the order of evaluation of the target and source expressions of an assignment statement.

...
An error occurs if the aforementioned subtype checks fail.

如果在变量赋值的目标表达式和右侧表达式中都没有相应的元素,则会发生该错误。

5.3.2.2 索引约束和离散范围,第 4 段:

An array constraint of the first form is compatible with the type if, and only if, the constraint defined by each discrete range is compatible with the corresponding index subtype and the array element constraint, if present, is compatible with the element subtype of the type. If any of the discrete ranges defines a null range, any array thus constrained is a null array, having no elements. An array value satisfies an index constraint if at each index position the array value and the index constraint have the same index range. (Note, however, that assignment and certain other operations on arrays involve an implicit subtype conversion.)

解决这两个问题:

begin
    process (rst, clk) -- , start, noisein_mono)  -- not needed
        variable count:  integer := 0;
        variable twnty_k_bit_stream:  bit_vector(19999 downto 0); -- was to 
    begin
        if start = '1' then
            if rising_edge(clk) then
                count := count + 1;
                -- twnty_k_bit_stream := twnty_k_bit_stream or
                --                       to_bitvector(noisein_mono);
                -- twnty_k_bit_stream := twnty_k_bit_stream sll 16;

                twnty_k_bit_stream (twnty_k_bit_stream'LEFT downto noisein_mono'LENGTH) :=
                    twnty_k_bit_stream (twnty_k_bit_stream'LEFT - noisein_mono'LENGTH downto 0);
                twnty_k_bit_stream (noisein_mono'RANGE) :=
                                    to_bitvector(noisein_mono);
            end if;

注意到我还修复了敏感度列表,我们得到了一些没有边界检查错误的东西。而不是使用 "or" 这个移位然后用 noisein_mono.

写入较低的 16 位

添加测试平台:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity monoblahblah_tb is
end entity;

architecture foo of monoblahblah_tb is
    signal clk:           std_logic := '0';
    signal rst:           std_logic;
    signal start:         std_logic;
    signal noisein_mono:  std_logic_vector (15 downto 0);

    signal running_mono:  std_logic;
    signal tok_mono:      std_logic;
begin
DUT:
    entity work.monotestmodule
        port map (
            clk => clk,
            rst => rst,
            start => start,
            noisein_mono => noisein_mono,
            running_mono => running_mono,
            tok_mono => tok_mono
        );
CLOCK:
    process
    begin
        wait for 5 ns;
        clk <= not clk;
        if now > 12680 ns then
            wait;
        end if;
    end process;
STIMULI:
    process
    begin
        wait for 6 ns;
        rst <= '0';
        start <= '0';
        noisein_mono <= (others => '0');
        wait for 10 ns;
        rst <= '1';
        wait for 10 ns;
        rst <= '0';
        wait for 100 ns;
        start <= '1';
        for i in 0 to 1249 loop -- 20,000 / 16
            noisein_mono <= 
                std_logic_vector(to_unsigned(i, noisein_mono'length)) 
                  xor
                x"dead";
            wait for 10 ns;
        end loop;
        wait;
    end process;
end architecture;

我们得到:

如果我考虑过,我会连续对不同的值进行异或运算,这些值在 0 到 1249 之间是唯一的,就像与 x"DEAD" 进行二进制异或运算一样。 (考虑到未显示 twnty_k_bit_stream 的状态,为简单的测试平台编写随机数生成器似乎很奇怪。目的是表明没有边界检查失败。)

因此在 运行 时间(或综合)检测到两个语义错误和一个不正确的敏感度列表。