VHDL: for...loop instead of for...generate

7k views Asked by At

Hello I have a problem in using for...loop instead of for...generate. I'd like to use for...loop because our Professor only taught us about it.

library ieee;
use ieee.std_logic_1164.all;

entity supersomm_4bit is
  port (
    c_in: in std_logic;
    a,b: in std_logic_vector(3 downto 0);
    s: out std_logic_vector(3 downto 0);
    sP,sG: out std_logic
  );
end supersomm_4bit;

architecture arch of supersomm_4bit is
  signal p,g,c: std_logic_vector(3 downto 0);

  begin
    g1: for i in 0 to 3 generate
      g(i) <= a(i) and b(i);
      p(i) <= a(i) or b(i);
    end generate;

    c(0) <= c_in;
    c(1) <= g(0) or (p(0) and c(0));
    c(2) <= g(1) or (p(1) and g(0)) or (p(1) and p(0) and c(0));
    c(3) <= g(2) or (p(2) and g(1)) or (p(2) and p(1) and g(0))
            or (p(2) and p(1) and p(0) and c(0));

    g2: for i in 0 to 3 generate
      s(i) <= a(i) xor b(i) xor c(i);
    end generate;

    sP <= p(0) and p(1) and p(2) and p(3);
    sG <= g(3) or (p(3) and g(2)) or (p(3) and p(2) and g(1))
          or (p(3) and p(2) and p(1) and g(0));
end arch;

I've tried doing something like this

architecture for_loop of supersomm_4bit is
  signal p,g,c: std_logic_vector(3 downto 0);
  begin
    process begin
        for i in 0 to 3 loop
        g(i) <= a(i) and b(i);
        p(i) <= a(i) or b(i);
        end loop;
        wait;
    end process;

    c(0) <= c_in;
    c(1) <= g(0) or (p(0) and c(0));
    c(2) <= g(1) or (p(1) and g(0)) or (p(1) and p(0) and c(0));
    c(3) <= g(2) or (p(2) and g(1)) or (p(2) and p(1) and g(0))
            or (p(2) and p(1) and p(0) and c(0));
        
    process begin
        for i in 0 to 3 loop
        s(i) <= a(i) xor b(i) xor c(i);
        end loop;
        wait;
    end process;

    sP <= p(0) and p(1) and p(2) and p(3);
    sG <= g(3) or (p(3) and g(2)) or (p(3) and p(2) and g(1))
            or (p(3) and p(2) and p(1) and g(0));
end architecture for_loop;

but it doesn't work (s and sP/sG are uninitialized). I've also tried putting all the code under a single process but it still doesn't work. Am I doing something wrong or should I simply avoid using for...loop? Thanks!

EDIT (adding the whole project):

library ieee;
use ieee.std_logic_1164.all;

entity unita_cla is
  port (
    a,b: in std_logic_vector(15 downto 0);
    c_in: in std_logic;
    S: out std_logic_vector(15 downto 0);
    C_OUT: out std_logic
  );
end unita_cla;

architecture arch of unita_cla is
  signal C: std_logic_vector(4 downto 1);
  signal P,G: std_logic_vector(3 downto 0);

  component supersomm_4bit
    port (
      c_in: in std_logic;
      a,b: in std_logic_vector(3 downto 0);
      s: out std_logic_vector(3 downto 0);
      sP,sG: out std_logic
    );
  end component;

  begin
    C(1) <= G(0) or (P(0) and c_in);
    C(2) <= G(1) or (P(1) and G(0)) or (P(1) and P(0) and c_in);
    C(3) <= G(2) or (P(2) and G(1)) or (P(2) and P(1) and G(0))
            or (P(2) and P(1) and P(0) and c_in);
    C(4) <= G(3) or (P(3) and G(2)) or (P(3) and P(2) and G(1))
            or (P(3) and P(2) and P(1) and G(0))
            or (P(3) and P(2) and P(1) and P(0) and c_in);

    bit0_3: supersomm_4bit port map (c_in, a(3 downto 0), b(3 downto 0),
                                     S(3 downto 0), P(0), G(0));
    bit4_7: supersomm_4bit port map (C(1), a(7 downto 4), b(7 downto 4),
                                     S(7 downto 4), P(1), G(1));
    bit8_11: supersomm_4bit port map (C(2), a(11 downto 8), b(11 downto 8),
                                     S(11 downto 8), P(2), G(2));
    bit12_15: supersomm_4bit port map (C(3), a(15 downto 12), b(15 downto 12),
                                     S(15 downto 12), P(3), G(3));

    C_OUT <= C(4);
end arch;

TESTBENCH:

library ieee;
use ieee.std_logic_1164.all;

entity unita_cla_tb is
end unita_cla_tb;

architecture testbench of unita_cla_tb is
  signal a,b,S: std_logic_vector(15 downto 0);
  signal c_in,C_OUT: std_logic;

  component unita_cla
    port (
      a,b: in std_logic_vector(15 downto 0);
      c_in: in std_logic;
      S: out std_logic_vector(15 downto 0);
      C_OUT: out std_logic
    );
  end component;

  begin
    u1: unita_cla port map (a,b,c_in,S,C_OUT);
    tb: process
    begin
      a <= "0000000000000000";
      b <= "0000000000000000";
      c_in <= '1';
      wait for 10 ns;
      a <= "1111111111111111";
      b <= "0000000000000000";
      c_in <= '0';
      wait for 10 ns;
      a <= "1010101010101010";
      b <= "0101010101010101";
      c_in <= '1';
      wait for 10 ns;
      a <= "1111111111111111";
      b <= "1111111111111111";
      c_in <= '0';
      wait for 10 ns;
      a <= "1010101010101010";
      b <= "1010101010101010";
      c_in <= '1';
      wait for 10 ns;
      wait;
    end process;
  end testbench;
1

There are 1 answers

0
AudioBubble On BEST ANSWER

The two process in the for loop version of the architecture for supersomm_4bit execute only once due to the unconditional wait statements. Adding sensitivity lists and removing the wait statements:

architecture for_loop of supersomm_4bit is
    signal p,g,c: std_logic_vector(3 downto 0);
begin
    process (a, b)  -- ADDED sensitiity list
    begin
        for i in 0 to 3 loop
            g(i) <= a(i) and b(i);
            p(i) <= a(i) or b(i);
        end loop;
        -- wait;  -- resumes for every change in a or b
    end process;

    c(0) <= c_in;
    c(1) <= g(0) or (p(0) and c(0));
    c(2) <= g(1) or (p(1) and g(0)) or (p(1) and p(0) and c(0));
    c(3) <= g(2) or (p(2) and g(1)) or (p(2) and p(1) and g(0))
            or (p(2) and p(1) and p(0) and c(0));

    process  (a, b, c)  -- ADDED sensitivity list
    begin
        for i in 0 to 3 loop
        s(i) <= a(i) xor b(i) xor c(i);
        end loop;
        -- wait;   -- resumes for every change in a, b or c
    end process;

    sP <= p(0) and p(1) and p(2) and p(3);
    sG <= g(3) or (p(3) and g(2)) or (p(3) and p(2) and g(1))
            or (p(3) and p(2) and p(1) and g(0));
end architecture for_loop;

Allows the simulation to match that of architecture arch. Each process will resume for any signal in the sensitivity list that has an event (a new value).

IEEE Std 1076-2008
11.3 Process statement

If a process sensitivity list appears following the reserved word process, then the process statement is assumed to contain an implicit wait statement as the last statement of the process statement part; this implicit wait statement is of the form

wait on sensitivity_list ;

The rules for constructing a sensitivity list are found in 10.2 Wait statement.

14.7.5 Model execution
14.7.5.1 General

The execution of a model consists of an initialization phase followed by the repetitive execution of process statements in the description of that model. Each such repetition is said to be a simulation cycle. In each cycle, the values of all signals in the description are computed. If as a result of this computation an event occurs on a given signal, process statements that are sensitive to that signal will resume and will be executed as part of the simulation cycle.

At certain stages during the initialization phase and each simulation cycle, the current time, Tc, and the time of the next simulation cycle, Tn, are calculated. Tn is calculated by setting it to the earliest of ...

14.7.5.2 Initialization

At the beginning of initialization, the current time, Tc, is assumed to be 0 ns.

The initialization phase consists of the following steps:

.. f) For each nonpostponed process P in the model, the following actions occur in the indicated order:

  1. The process executes until it suspends.
    ...

Processes suspend and resume in wait statements. A process with a sensitivity list has an implicit wait statement as the last statement.

10.2 Wait statement

The timeout clause specifies the maximum amount of time the process will remain suspended at this wait statement. If no timeout clause appears, the timeout clause for (STD.STANDARD.TIME'HIGH – STD.STANDARD.NOW) is assumed. It is an error if the time expression in the timeout clause evaluates to a negative value.

The existing wait statements have no time out clause and would cause the process to cease execution following the first process execution following initialization. The input values used to provide update waveforms for signal outputs would be all 'U's at that time.

14.7.5.3 Simulation cycle

A simulation cycle consists of the following steps:

...
f) The following actions occur in the indicated order:

...
2) For each process, P, if P is currently sensitive to a signal, S, and if an event has occurred on S in this simulation cycle, then P resumes

Scheduled and updated at the current simulation time.