VHDL进程if-then-else-if语句

时间:2013-10-05 10:57:29

标签: debugging if-statement process vhdl modelsim

我编辑此主题以更新我的整个新项目并使其更具可读性:

--Propagate & generate team--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY PG_team_1bit IS
    PORT(a, b:IN STD_LOGIC;
         p: OUT STD_LOGIC;
         g: OUT STD_LOGIC);
END PG_team_1bit;
ARCHITECTURE PG_team_1bit_arch OF PG_team_1bit IS
BEGIN
    p <= a XOR b;
    g <= a AND b;      
END PG_team_1bit_arch;       


--Grey Box--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY Grey_box IS
    PORT(P, G, Gminus:IN STD_LOGIC;
         NewG: OUT STD_LOGIC);
END Grey_box;
ARCHITECTURE Grey_box_arch OF Grey_box IS
    SIGNAL temp: STD_LOGIC;
BEGIN
   temp <= P AND Gminus;
   NewG <= G OR temp;      
END Grey_box_arch;       


--Black Box--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY Black_box IS
    PORT(P, G, Pminus, Gminus:IN STD_LOGIC;
         NewP, NewG: OUT STD_LOGIC);
END Black_box;
ARCHITECTURE Black_box_arch OF Black_box IS
    SIGNAL temp: STD_LOGIC;
BEGIN
   NewP <= P AND Pminus;
   temp <= P AND Gminus;  
   NewG <= G or temp;    
END Black_box_arch;   


--Full adder--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY Full_Adder IS
    PORT(A, B, Cin:IN STD_LOGIC;
         S, Cout: OUT STD_LOGIC);
END Full_Adder;
ARCHITECTURE Full_Adder_arch OF Full_Adder IS
    SIGNAL p: STD_LOGIC;
BEGIN
   p <= A XOR B;
   S <= p XOR Cin;  
   Cout <= (A AND B) OR (A AND Cin) OR (B AND Cin);    
END Full_Adder_arch;  



--SKLANSKY SPARSE TREE ADDER 32 bit--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY SSTA32 IS
    PORT(A, B:IN STD_LOGIC_VECTOR(31 downto 0);
         S: OUT STD_LOGIC_VECTOR(32 downto 0));
END SSTA32;
ARCHITECTURE SSTA32_arch of SSTA32 IS 
    SIGNAL con: STD_LOGIC;
    SIGNAL p: STD_LOGIC_VECTOR(31 downto 0);
    SIGNAL g: STD_LOGIC_VECTOR(31 downto 0);
    SIGNAL NewGG: STD_LOGIC_VECTOR(6 downto 0);
    SIGNAL NewP: STD_LOGIC_VECTOR(6 downto 0);
    SIGNAL NewBG: STD_LOGIC_VECTOR(6 downto 0);
    variable j : integer := 0;
    variable k : integer := 0;
    variable l : integer := 0;
    variable m : integer := 0;
    variable d : integer := 0;
    variable e : integer := 0;
COMPONENT PG_team_1bit
    PORT(a, b:IN STD_LOGIC;
         p: OUT STD_LOGIC;
         g: OUT STD_LOGIC);
END COMPONENT; 
COMPONENT Grey_box IS
    PORT(P, G, Gminus:IN STD_LOGIC;
         NewG: OUT STD_LOGIC);
END COMPONENT;
COMPONENT Black_box IS
    PORT(P, G, Pminus, Gminus:IN STD_LOGIC;
         NewP, NewG: OUT STD_LOGIC);
END COMPONENT;
COMPONENT Full_Adder IS
    PORT(A, B, Cin:IN STD_LOGIC;
         S, Cout: OUT STD_LOGIC);
END COMPONENT;
BEGIN 
   con <= '1';
   GENERATE_LABEL_1:
   FOR i IN 0 TO 31 GENERATE
      PG_team_1bit_i: PG_team_1bit PORT MAP(a(i), b(i), p(i), g(i));
   END GENERATE GENERATE_LABEL_1;   
   GENERATE_LABEL_2: 
   FOR i IN 0 TO 31 GENERATE
       BEGIN
          F0 : IF ((i=1) OR (i=5) OR (i=9) OR (i=13) OR (i=17) OR (i=21) OR (i=25) OR (i=29)) GENERATE
             BEGIN Grey_box_i: Grey_box PORT MAP(p(i), g(i), g(i-1), NewGG(j));--
             j := j+1;
             END GENERATE F0;
          F1 : IF ((i/=1) AND (i/=5) AND (i/=9) AND (i/=13) AND (i/=17) AND (i/=21) AND (i/=25) AND (i/=29)) GENERATE
             BEGIN Black_box_i: Black_box PORT MAP(p(i), g(i), p(i-1), g(i-1), NewP(k), NewBG(k));
             k := k+1;
             END GENERATE F1; 
       END GENERATE GENERATE_LABEL_2;
   GENERATE_LABEL_3:
   FOR i IN 0 TO 31 GENERATE
      BEGIN
         F2 : IF (i=3) GENERATE
            BEGIN Grey_box_i: Grey_box PORT MAP(NewP(m), NewBG(m), NewGG(m), DNewG);
            m := m+1;
            END GENERATE F2;
         F3 : IF ((i=7) OR (i=11) OR (i=15) OR (i=19) OR (i=23) OR (i=27) OR (i=31)) GENERATE
            BEGIN Black_box_i: Black_box PORT MAP(NewP(m), NewBG(m), con, NewBG(m), TNewP(l), TNewBG(l));
            l := l+1; 
            END GENERATE F3;
      END GENERATE GENERATE_LABEL_3;
   GENERATE_LABEL_4:
   FOR i IN 0 TO 31 GENERATE 
      BEGIN
         F4 : IF (i=3) GENERATE
            BEGIN C(d) <= '0';
            d := d+1;
            C(d) <= NOT DNewG;
            d := d+1;
            END GENERATE F4;
         F5 : IF (i=7) GENERATE
            BEGIN Grey_box_i: Grey_box PORT MAP(TNewP(e), TNewBG(e), DNewG, DNewG2);
            C(d) <= NOT DNewG2;
            d := d+1;
            e := e+1;
            END GENERATE F5;
         F6 : IF (i=11) GENERATE
            BEGIN Grey_box_i: Grey_box PORT MAP(NOT TNewP(e), NOT TNewBG(e), DNewG2, C(d));
            d := d+1;
            e := e+1;
            END GENERATE F6;
         F7 : IF (i=15) GENERATE
            BEGIN Black_box_i: Black_box PORT MAP(TNewP(e), TNewBG(e), TNewP(e-1), TNewBG(e-1), QNewP, QNewBG);
            Grey_box_i: Grey_box PORT MAP(QNewP, QNewBG, DNewG2, DNewG3);
            C(d) <= DNewG3;
            d := d+1;
            e := e+1;
            END GENERATE F7;
         F8 : IF (i=19) GENERATE
            BEGIN Grey_box_i: Grey_box PORT MAP(NOT TNewP(e), NOT TNewBG(e), DNewG3, C(d));
            d := d+1;
            e := e+1;
            END GENERATE F8;
         F9 : IF (i=23) GENERATE
            BEGIN Black_box_i: Black_box PORT MAP(TNewP(e), TNewBG(e), TNewP(e-1), TNewBG(e-1), PNewP, PNewBG);
            Grey_box_i: Grey_box PORT MAP(PNewP, PNewBG, DNewG3, C(d));
            d <= d+1;
            e <= e+1;
            END GENERATE F9;
         F10 : IF (i=27) GENERATE
            BEGIN Black_box_i: Black_box PORT MAP(NOT TNewP(e), NOT TNewBG(e), PNewP, PNewBG, HNewP, HNewBG);
            Grey_box_i: Grey_box PORT MAP(HNewP, HNewBG, DNewG3, C(d));
            END GENERATE F10;
      END GENERATE GENERATE_LABEL_4;
   d := 0;
   GENERATE_LABEL_5:
   FOR i IN 0 TO 31 GENERATE
      BEGIN
         F11 : IF ((i=0) AND (d=0)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F11;
         F12 : IF ((i=4) AND (d=1)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F12;
         F13 : IF ((i=8) AND (d=2)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F13;
         F14 : IF ((i=12) AND (d=3)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F14;
         F15 : IF ((i=16) AND (d=4)) GENERATE
            BEGIN Cin <= C(d); 
            d := d+1;
            END GENERATE F15;
         F16 : IF ((i=20) AND (d=5)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F16;
         F17 : IF ((i=24) AND (d=6)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F17;
         F18 : IF ((i=28) AND (d=7)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F18; 
         Full_Adder_i: Full_Adder PORT MAP(a(i), b(i), Cin, S(i), Cout);
         Cin <= Cout;
         F19 : IF (i=31) GENERATE
            BEGIN S(32) <= Cout;
            END GENERATE F19;
      END GENERATE GENERATE_LABEL_5;
END SSTA32_arch;

我得到的错误如下: - 我使用的几乎所有信号都没有静态信号名称。 - 在我这样做的地方不允许变量声明。 - 未知标识符。 - 信号分配的非法目标 - 非法的陈述。

修理它们的任何提示? 如果现在也正确我的生成?我改变了以避免进程。 提前谢谢

2 个答案:

答案 0 :(得分:1)

退一步;很明显,你还没有习惯VHDL;它与其他语言略有不同,坦率地说(IMO)在许多(大多数?)书中都没有很好的教学。

修复语法错误无法帮助您完成此操作;学会看到背后的概念错误。

有些文章强调VHDL是硬件描述语言而不是编程语言:虽然如此,但这并不是特别有用,可能会导致您进入糟糕的低级设计实践。这是一个不同的观点...

VHDL实际上是两种不同的语言:Pascal或C等顺序语言,以及类似的并行处理语言......我无法想到一个很好的例子,但也许是像ML这样的函数式编程语言Haskell(请耐心等待......),事情并行而不是以任何特定的顺序发生:VHDL的真正优势在于它safely!

在一个过程中,你可以像顺序语言一样对待它,包括函数,过程(C程序员的void函数!),变量,循环,if / then / else和熟悉的顺序语义 - 有一个例外:{{ 3}}因为它们是(通常是不同的)进程之间进行通信的手段。 (一个典型的C程序是一个单独的过程:如果你编写多线程C程序,你就会知道你需要一个非常不同的学科,以及像线程库这样的额外支持。)

VHDL的另一个方面是并行方面,您可以在其中创建多个单元 - 基本上所有进程彼此独立运行,通过信号进行通信。在流程之外,您有一组不同的编程工具:

  • 实体/体系结构是一组进程的包装器。

  • 组件是相同的,因为它们只是映射到实体(通过 配置,允许您选择不同的实体或 体系结构)。如果您不需要重新映射它们,则可以消除 组件并直接实例化设计中的实体。

  • 简单的信号分配,如    p <= A XOR B;在流程之外是完成整个流程的简写。

  • 还有条件信号分配和选定的信号分配,例如

    p <= A when B = '1' else C;这些也是流程的简写。

  • 连接多个并行进程变得乏味:Generate语句是自动完成该工作的工具。

混合两个域是错误的:例如在进程外使用if / then / else或变量赋值a := b;,或者实例化组件或在其中使用Generate。现在,在ARCHITECTURE SSTA32_arch of SSTA32内你可以看到这样的错误......

我不会修复你的项目,我不认为你想要我;但这里有几点建议:

  • 虽然可以在流程外使用变量和变量赋值,但通常是错误:这些被称为&#34;共享变量&#34 ; (用C程序员的话来说)不是线程安全的,并且通常不会做你期望的事情。使用信号(并学习它们的语义)是这里的方法。

  • 虽然您无法在流程外使用if a then b else c;,但您可以使用if a generate b; end generate; if not a generate c; end generate;并且可以嵌套生成语句。

  • 更好的格式化将使阅读更容易,更容易发现错误。

  • 我想你可能想要&#34; elsif&#34;而不是&#34;否则如果&#34;在某些地方:这解决了很多失踪的问题&#34;结束了如果&#34;问题

编辑:更新答案的更多指示......

  • &#34;不允许变量声明&#34;在架构中仍然是一个问题...乍一看,我无法理解你为什么不使用信号。

  • 乍一看:

     F2 : IF i=3 GENERATE
        BEGIN 
           Grey_box_i: Grey_box PORT MAP(NewP(m), NewBG(m), NewGG(m), DNewG);
           m := m+1;
        END GENERATE F2;
    

您不能在Generate语句中使用变量(因为它们在进程外部)。我怀疑你打算让他们的价值基本上是静态的 - (i)的确定性函数而不是他们自己的国家持有者。

编译器并不知道 - 它会看到更多可能在运行时发生变化的状态(并且您无法在运行时增加更多硬件!)因此它拒绝了这一想法。例如,Generate生成的硬件无序,从而生成&#34; i = 3&#34; case last完全合法,你对m的值有无保证。你可能不喜欢这个结果!

解决方案很简单:将m作为变量消除,使成为(i)的函数。

 function m(x : integer) return integer is
 begin
   case x is
      when 3      => return 0;
      when others => return 1;
   end case;
 end m;

 ... PORT MAP(NewP(m(i)), ...

这些函数属于具有其他声明的体系结构。因为i在生成语句的任何实例中都是固定的(静态),所以f(i) - 这里m(i) - 也是静态的,虽然我没有测试过这种方法,但我希望它可以工作。

  • 对于未知标识符,我在上面的代码段中看到了各种名称,例如DNEWG,我找不到声明;这很容易解决。

  • 你可以在if-expressions周围丢失不必要的括号;它们只是一个过时的C程序员留下的杂乱

答案 1 :(得分:0)

基于结构的缩进通常会显示语法问题,所以我接受了 自由美化你的代码。正如你在上一部分所看到的,很多 if语句没有正确的结束end if语句。那句法 错误必须修复,您可以考虑使用elsif进行互操作 独家条件。

关于你的问题:

  1. 我应该在敏感度列表中添加什么内容:对于描述的过程 触发器,灵敏度应该是时钟和任何异步复位 信号(S)。对于描述组合逻辑的过程,灵敏度 list必须包含组合逻辑中使用的所有源信号。 通常,您编写的任何进程都应该是这两个进程中的任何一个,所以也是如此 描述触发器或描述组合逻辑。之后的过程 问题既不是两个问题,也存在多个问题:事实并非如此 允许在进程内实例化模块Grey_box和Black_box, 一般情况下,你不能使用k作为变量,:=赋值,而不是 在此过程中宣布它。

  2. 如何使p和g全局化;我做得还不够吗? p和g 自从在架构中声明以来可用,所以问题是由于 如上所述,尝试在进程中实例化模块。

  3. 总的来说,您可以考虑更好地了解VHDL概念 在开始这样一个更大的项目之前,因为它会更容易 了解并更​​正您遇到的任何语法错误消息。

    一个好的起点是Wikipedia VHDL page,您可以在Further reading下查看。为了得到一个 良好的VHDL经验我建议您深入学习一些资源 基本概念。