我有这个错误:错误(10344):REG2.vhd(18)处的VHDL表达式错误:表达式有0个元素,但必须有4个元素

时间:2014-11-21 13:15:59

标签: vhdl

我发现这段代码是Exponentiation实现的一部分,我相信这段代码是针对并行加载寄存器的,代码有很多错误,但我试图修复它并简化它(简化就是让它工作),原始代码是:

    library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity REG is --Register entity
Port ( CLK,set,reset,In_LOAD : in std_logic;
Din_p: in std_logic_vector(m-1 to 0);
Din_s: in std_logic;
Dout: out std_logic);
end REG;
architecture behavior of REG is
signal Q_temp: std_logic_vector(m-1 down to 0);
begin
Dout<=”0”;
comb:process(In_LOAD,Din_s)
begin
if(In_LOAD=”1”) then Q_temp<=Din_p;end if;
end process comb;
state: process(CLK,set,reset)
begin
if(reset=”1”) then Q_temp<=(others=>”0”);end if;
if(set=”1”) then Q_temp<= (others=>”1”);
elsif(CLK’event and CLK=”1”) then
Q_temp:=Din_p & Q_temp(m-1 down to 1);
end if;
Dout<= Q_temp(0);
end process state;
end behavior;

,而我修改的代码是:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity REG2 is --Register entity
generic (m: integer := 4);
Port ( CLK,In_LOAD : in std_logic;
Din_p: in std_logic_vector(m-1 to 0);
Dout: out std_logic);
end REG2;
architecture behavior of REG2 is
signal Q_temp: std_logic_vector(m-1 downto 0);
begin
Dout<='0';
process(In_LOAD, Din_p, CLK)
begin
if (CLK'event and CLK='1') then 
Q_temp <=Din_p;
elsif (In_LOAD='1') then
Q_temp <= Din_p & Q_temp(m-1 downto 1);
end if;
end process;
Dout <= Q_temp(0);
end behavior;

所以我的问题是:1-为什么我收到此错误:(错误(10344):REG2.vhd(18)处的VHDL表达式错误:表达式有0个元素,但必须有4个元素)? 2-这是并行加载寄存器的代码,对吧? THX

2 个答案:

答案 0 :(得分:0)

您的代码(以及原始代码)存在许多问题。

  • 对位字符串使用正确的引号字符",而为'使用而不是downto
  • down to只有一个字,而不是m
  • 未宣布
  • Q_temp;也许这应该是通用的?
  • 使用信号分配<=而非变量分配:=分配给Din_p
  • 您的流程的敏感度列表不完整
  • 正如@Morten所提到的:downto的方向应该是to而不是IEEE.STD_LOGIC_ARITH

Bonus(pet peeve):不要使用IEEE.STD_LOGIC_UNSIGNEDieee.numeric_std,因为它们没有正确标准化。请改用{{1}}。

答案 1 :(得分:0)

如果我们解决了Morten指出的错误:

library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_arith.all;
-- use ieee.std_logic_unsigned.all;

entity reg2 is 
    generic (m: integer := 4);
    port ( 
        clk:        in  std_logic;
        in_load:    in  std_logic;
        din_p:      in  std_logic_vector(m-1 downto 0); -- was to per Morten
        dout:       out std_logic
    );
end entity reg2;

architecture behavior of reg2 is
    signal q_temp: std_logic_vector(m-1 downto 0);
begin

    dout <= '0';

UNLABELLED:
    process(clk)
    begin
        if clk'event and clk = '1' then 
            q_temp <= din_p;
        elsif in_load = '1' then
            q_temp <= din_p & q_temp(m-1 downto 1);
        end if;
    end process;

    dout <= q_temp(0);

end architecture behavior;

我们在行

中看到另一个错误
q_temp <= din_p & q_temp(m-1 downto 1);

在运行时,我们发现长度为q_temp的{​​{1}}是从m(长度din_p)和m的串联中分配的(长度q_temp(m-1 downto 1) - 1)。

因此,根据莫滕的建议,仍然存在错误。

不要选择m位元素,而是转换为&#39; 0&#39;:

din_p

模型将在此之后运行,但仍有几个逻辑错误。

首先,并发信号赋值语句中有两个q_temp <= '0' & q_temp(m-1 downto 1); 赋值,每个赋值都有自己的驱动程序。已解决的值将为&#39; X&#39;

删除第一个:

dout

下一个逻辑错误与您操作移位寄存器的方式有关。

-- dout <= '0';

这会导致 if clk'event and clk = '1' then q_temp <= din_p; elsif in_load = '1' then q_temp <= '0' & q_temp(m-1 downto 1); -- '0' was din_p end if; q_temp的上升沿加载din_p,并在clk的下降沿右移。

而是使用clk来确定是同步加载in_load还是向右移din_p

q_temp

这会给你:

enter image description here (点击打开链接图片)

使用此测试台:

    if clk'event and clk = '1' then 
        if in_load = '0' then
            q_temp <= din_p;
        else
            q_temp <= '0' & q_temp(m-1 downto 1); -- '0' was din_p
        end if;

library ieee; use ieee.std_logic_1164.all; entity reg2_tb is end entity; architecture foo of reg2_tb is constant m: natural := 4; signal clk: std_logic := '0'; signal in_load: std_logic := '0'; signal din_p: std_logic_vector (m-1 downto 0) :="1101"; signal dout: std_logic; begin DUT: entity work.reg2 generic map (m => m) port map ( clk => clk, in_load => in_load, din_p => din_p, dout => dout ); CLOCK: process begin wait for 5 ns; clk <= not clk; if Now > 80 ns then -- report "simulation time > 80 ns"; wait; end if; end process; STIMULUS: process begin wait for 10 ns; in_load <= '1'; wait for 10 ns; wait; end process; end architecture; 使用"1101"的值。

注意而不是移动&#39; 0&#39;从左侧开始,如果有一些理由在移出寄存器后将din_p值返回到移位寄存器中,则可以重新循环q_temp的最右位。

不需要包std_logic_arith和std_logic_unsigned的use子句。