简体   繁体   中英

VHDL process if-then-else-if statement

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

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.

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

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).

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.

  • 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, eg

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

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

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:

  • 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.

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

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

EDIT : more pointers for updated answer...

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

  • At second glance :

      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; 

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.

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!

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)), ...

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.

  • 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.

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

Indentation based on structure will often reveal syntax problems, so I took the liberty to beautify your code. As you can see in the last part, a lot of the if statements does not have proper closing end if statements. That syntax error must be fixed, and you may consider using elsif for the mutually exclusive conditions.

Regarding your questions:

  1. What should I put in the sensitivity list: For a process that describes flip-flop(s), the sensitivity should must the clock and any asynchronous reset signal(s). For a process that describes combinatorial logic, the sensitivity list must contain all source signals that are used in the combinatorial logic. In general, any process you write should be either of these two, so either describing flip-flop(s), or describing combinatorial logic. The process after the questions is neither of the two, and have multiple problems: It is not allowed to instantiate modules, the Grey_box and Black_box, inside a process, and in general you can't use k as a variable, with := assign, without declaring it in the process.

  2. How can I make p and g global; is what I have done not enough? The p and g are available since declared in the architecture, so the problem is due to the attempt of instantiating a module ia process, as I noted above.

Overall, you may consider to get a better understanding about the VHDL concept before starting a larger project like this, since it will then be much easier to understand and correct any syntax error messages you encounter.

A good place to start is the Wikipedia VHDL page , where you can look under Further reading . In order to get a good VHDL experience I suggest that you dig into some of the resources to learn the basic concepts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM