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

时间:2016-04-12 19:14:30

标签: vhdl simulation xilinx-ise

我在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。编译器弹出错误说第52行:运算符&#34;或&#34;的长度不等的参数。 我该如何解决这个问题?

我最诚挚的问候。

1 个答案:

答案 0 :(得分:1)

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

实际上有两个边界不匹配错误,一个用于两个数组值上的“或”:

            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段:

  

如果两个操作数都是一维数组,则操作数应为相同长度的数组,操作在数组的匹配元素上执行,结果是与左操作数具有相同索引范围的数组。如果一个操作数是标量而另一个操作数是一维数组,则使用数组操作数的每个元素对标量操作数执行操作。结果是一个与数组操作数具有相同索引范围的数组。

如此不均匀的长度数组不起作用。

另见10.6.2.1(变量分配),第5和7段:

  

为了执行目标是变量名的变量赋值,首先计算变量名和表达式。然后检查表达式的值是否属于变量的子类型,除非是具有复合类型的变量(在这种情况下,赋值涉及子类型转换)。最后,使用表达式的相应子元素更新未强制变量的每个子元素。如果设计取决于赋值语句的目标和源表达式的评估顺序,则设计是错误的。

     

...
  如果上述子类型检查失败,则会发生错误。

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

5.3.2.2指数约束和离散范围,第4段:

  

第一种形式的数组约束与兼容的类型为if且仅当每个离散范围定义的约束与相应的索引子类型和数组元素约束(如果存在)兼容时,与该类型的元素子类型兼容。如果任何离散范围定义了空范围,则由此约束的任何数组都是空数组,没有元素。如果在每个索引位置处数组值和索引约束具有相同的索引范围,则数组值满足索引约束。 (但请注意,数组上的赋值和某些其他操作涉及隐式子类型转换。)

解决这两件事:

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;

注意我还修复了敏感度列表,我们得到的东西没有边界检查错误。不是使用“或”这种移位,而是使用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;

我们得到:

monblahblah_tb.png

如果我考虑过它,我会连续异或不同的值,这些值在0到1249之间是唯一的,因为二进制XOR与x“DEAD”。 (为简单的测试平台编写一个随机数生成器似乎很简陋,考虑到twnty_k_bit_stream的状态没有显示。目的是显示没有边界检查失败。)

因此,在运行时(或合成)可检测到两个语义错误,并且灵敏度列表不正确。