VHDL处理if-then-else-if语句 [英] VHDL process if-then-else-if statement

查看:150
本文介绍了VHDL处理if-then-else-if语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编辑了该线程以更新我的整个新项目并使它更具可读性:

I Edited this thread to update my whole new project and make it more readable:

--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;

我得到的错误如下:-不是我使用的几乎所有信号的静态信号名称.-变量声明不允许在我做的地方使用.-未知标识符.-信号分配的非法目标和-非法一致声明.

The errors that I get are the following : -Not static signal names for almost all the signals I use. -Variable Declaration not allowed where I did it. -Unknown Identifiers. -Illegal target for signal assignment and -Illegal concurent statement.

有任何修复建议吗?如果现在正确,我的生成也可以吗?我将其更改为避免流程.预先感谢

Any tips to fix them? Also is my generate if now correct?I changed that to avoid processes. thanks in advance

推荐答案

退后一步;很显然,您还不习惯VHDL.它与其他语言有点不同,并且坦率地说(IMO)在很多(大多数?)书中都没有很好地讲授这些差异.

Step back a bit; it is clear that you aren't used to VHDL yet; it is a bit different from other languages and the differences are frankly (IMO) not very well taught in many (most?) books.

修复语法错误将无法帮助您解决;学习了解背后的概念错误.

Fixing syntax errors won't get you through this; learn to see the conceptual errors behind them.

有些文本强调VHDL是一种硬件描述语言,而不是一种编程语言:的确,这不是特别有用,并且会导致您进入不良的低级设计实践.这是另一种看法...

Some texts stress that VHDL is a Hardware Description Language not a programming language : while true, this isn't particularly helpful and can lead you into poor low-level design practices. Here's a different view...

VHDL实际上是两种不同的语言,其中之一:诸如Pascal或C的顺序语言,以及诸如...的并行处理语言.我想不到一个很好的例子,但也许是ML或Haskell这样的功能性编程语言(请耐心等待...)事情并行而不是以任何特定顺序发生:VHDL的真正优势在于它做到了

VHDL is virtually two different languages in one : a sequential language like Pascal or C, and a parallel processing language like ... I can't think of a good example, but perhaps a functional programming language like ML or Haskell (bear with me on this bit...) where things happen in parallel and not in any specific order : the real strength of VHDL is that it does so safely!

在一个过程中,您可以将其视为一种顺序语言,包括函数,过程(对于C程序员而言是无效函数!),变量,循环,if/then/else和熟悉的顺序语义-除了一个例外:信号具有不同的语义,因为它们是相互之间通信的方式(通常是不同的)流程.(典型的C程序是单个过程:如果您编写多线程C程序,您将知道您需要非常不同的纪律,并需要像线程库这样的额外支持.)

Within a process, you can treat it like a sequential language, with functions, procedures (void functions to C programmers!), variables, loops, if/then/else, and familiar sequential semantics - with ONE exception : Signals have different semantics because they are the means of communicating between (usually different) processes. (A typical C program is a single process : if you write multi-threaded C programs you will know you need a very different discipline for them and extra support like a threads library).

VHDL的另一个方面是并行方面,在这里您可以创建多个单元-基本上所有进程都彼此独立运行,通过信号进行通信.在流程之外,您拥有另一套编程工具:

The other aspect of VHDL is the parallel aspect, where you create multiple units - essentially all processes operating independently of each other, communicating via signals. Outside a process, you have a different set of programming tools:

  • 实体/体系结构是围绕一组进程的包装.

  • Entities/architectures are wrappers around a group of processes.

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

Components are the same, because they simply map to entities (via configurations, to allow you to select different entities or architectures). If you don't need to remap them, you can eliminate components and directly instantiate entities in a design.

简单的信号分配,例如 p< = A XOR B ;流程之外是完成单个任务的完整流程的简写.

Simple signal assignments like p <= A XOR B; outside of a process are shorthand for a complete process wrapping up that single assignment.

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

There are also conditional signal assignments and selected signal assignments, e.g.

p< = B等于'1'时为A,否则为C; 这些也是流程的简写.

p <= A when B = '1' else C; These are again shorthand for processes.

连接多个并行进程变得很乏味: Generate 语句是使该作业自动化的工具.

Wiring up multiple parallel processes gets tedious : the Generate statements are tools to automate that job.

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

It is a mistake to mix the two domains : such as using if/then/else or variable assignment a := b; outside a process, or to instantiate a component or use Generate inside one. Now, inside ARCHITECTURE SSTA32_arch of SSTA32 you can see such mistakes...

我不会修复您的项目,并且我不认为您希望我这样做;但是这里有一些指针:

I'm not going to fix your project and I don't think you want me to; but here are a couple of pointers:

  • 虽然您可以在进程外使用变量和变量分配,但这通常是错误:这些被称为共享变量",并且(在C语言中程序员条款)不是线程安全的,通常不会做您期望的事情.使用信号(并学习其语义)是解决问题的方法.

  • While you can use variables and variable assignment outside a process, it is usually a mistake : these are known as "shared variables" and (in C programmer terms) not thread-safe and won't usually do what you expect. Using signals (and learning their semantics) is the way to go here.

虽然不能在进程外部使用 if a then b else c; ,但是可以在生成器b上使用结束产生如果不是生成c;结束generate; ,然后可以嵌套generate语句.

While you can't use if a then b else c; outside a process, you CAN use if a generate b; end generate; if not a generate c; end generate; and you can nest generate statements.

更好的格式将使其更易于阅读,更容易发现错误.

better formatting will make it easier to read and mistakes easier to spot.

我认为您可能希望使用"elsif"而不是"else if":这样可以解决许多缺少的"end if"问题

I think you may want "elsif" instead of "else if" in places : that addresses a lot of missing "end if" problems

更多有关更新答案的指针...

  • 体系结构中的不允许使用变量声明"仍然是一个问题……乍一看,我看不到为什么不使用信号.

  • "Variable Declaration Not Allowed" in the architecture is still an issue ... at first glance I couldn't see why you aren't using signals.

乍一看:

 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)的确定性函数,而不是拥有国家独立的权利.

You can't use variables in a Generate statement like that (because they are outside a process). I suspect you intend their value to be essentially static - a deterministic function of (i) and not holders of state in their own right.

编译器不知道-它看到更多的状态,这些状态可能在运行时发生变化(并且您在运行时无法增加硬件!),因此它拒绝了这个想法.例如, Generate 生成的硬件没有没有订购,因此最后生成"i = 3"情况是完全合法的,并且您没有保证>关于m的值.您可能不想要结果!

The compiler doesn't know that - it sees more state which could potentially vary at runtime (and you can't grow more hardware at runtime!) so it rejects that idea. For example there is no ordering of the hardware generated by Generate thus generating the "i=3" case last is perfectly legal and you have no guarantees on the value of m. You probably wouldn't like the result!

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

The solution is simple : eliminate m as a variable and make it a function of (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 在generate语句的任何实例中都是固定的(静态的),所以f(i)-这里的m(i)也是静态的,尽管我没有测试这种方法,但我希望它能起作用

The functions belong in the architecture with the other declarations. Because i is fixed (static) within any instance of a generate statement, f(i) - here m(i) - is also static, and though I have not tested this approach I expect it to work.

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

  • As for the unknown identifiers, I see various names such as DNEWG in the above snippet for which I cannot find a declaration; this is trivial to solve.

您可能会在if表达式周围丢失不必要的括号;他们只是一个过往的C程序员留下的混乱杂物

you can lose the unnecessary parentheses around if-expressions; they are just clutter left by a passing C programmer

这篇关于VHDL处理if-then-else-if语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆