'Propagation delay VHDL

I need to modify the XOR operations used in the parity calculation in such a way that the XOR gates described are each supplemented by a hold time and the propagation delay and use the circuit diagram as a guide.

enter image description here

For the duration of the hold time, the signal used should be assigned the value "X" (invalid) in the VHDL description, and after the delay time, the new valid signal value. Note that signal delays are non-synthesisable constructs.

I'm just confused about the delay implementation. Should X(0)/X(1) be stable for 5ns or 8ns ? and X(2) for 3ns or 5ns ?

That's the code I wrote, but like I said, I'm not sure about the delay implementation and would appreciate some guidance.

library ieee;
use ieee.std_logic_1164.all;

entity parity_gen is
   port( x : in std_logic_vector (2 downto 0);
         y : out std_logic_vector (3 downto 0)
         );
end parity_gen;

architecture sig_handling of parity_gen is
   signal peven: std_logic;
   
    begin
        
   process(peven, x) 
        begin
      peven  <= x(0) xor x(1) xor x(2) after 10 ns;
      if  (x(0)'stable(8 ns) and x(1)'stable(8 ns) and x(2)'stable(3 ns)) then
         y  <= peven & x ; 
      else
         y  <= 'X' & x after 10 ns;
      end if;
    end process;
end sig_handling;


Solution 1:[1]

Here is a literal translation of the shown diagram as far as I understand it:

library ieee;
use ieee.std_logic_1164.all;

entity parity_gen is
   port(x : in std_logic_vector (2 downto 0);
        y : out std_logic);
end parity_gen;

architecture sig_handling of parity_gen is
   signal c: std_logic;
   
begin        
   process(all) 
   begin
      if (x(0)'stable(3 ns) and x(1)'stable(3 ns)) then
         c <= x(0) xor x(1) after 5 ns;
      else
         c <= 'X' after 5 ns;
      end if;
   end process;

   process(all) 
   begin
      if (c'stable(3 ns) and x(2)'stable(3 ns)) then
         y <= c xor x(2) after 5 ns;
      else
         y <= 'X' after 5 ns;
      end if;
   end process;

end sig_handling;

i.e. there are 2 XOR gates which update their output after 5 ns (tp), if their inputs have been stable for 3 ns (th), otherwise their output is undefined (my interpretation is that the propagation delay applies here as well).

The inputs to the first XOR gate are x(0) and x(1), and the output is c; and the inputs to the second XOR gate are c and x(2), and the output is y.

Solution 2:[2]

Edit: added the flip-flop interpretation of the concept of hold time.

There is something strange with your specifications: the output of a XOR gate shall be X for 3 ns after an input change and it shall be the resulting xor value after 5 ns. But what should it be meanwhile (from 3 to 5 ns after an input change)? So, there must be something wrong and/or missing.

Something else is missing in your specifications: what should happen when the inputs change again before 3 ns or 5 ns? Shall we use inertial or transport delays?

There are two interpretations that I can think of. The first one is quite strange but let's have a look at it: your XOR gates behave a bit like flip-flops. When their inputs change, if it is less than 3 ns after a previous change, they output X (after 5 ns), else, if it is more than 3 ns after a previous change, they output the xor of the inputs (after 5 ns). This is the classical interpretation of a hold time. Modelling this is a bit tricky (because there is no clock to use as a time reference), but doable:

entity myxor is
  port(a, b: in  std_ulogic;
       c:    out std_ulogic
  );
end entity myxor;

architecture beh of myxor is
begin
  process(a, b)
    variable t: time := 0 ns;
  begin
    if t = 0 ns or now - t >= 3 ns then
      c <= a xor b after 5 ns;
    else
      c <= 'X' after 5 ns;
    end if;
    t := now;
  end process;
end architecture beh;

Note: there are variants of this interpretation where c is assigned 'X' with a 3 ns delay instead of 5 ns, or no delay at all. Modify the code if you prefer one or the other.

And then, for your parity module:

entity parity is
  port(x: in  std_ulogic_vector(0 to 2);
       y: out std_ulogic
  );
end entity parity;

architecture str of parity is
  signal c: std_ulogic;
begin
  u0: entity work.myxor
    port map(
      a => x(0),
      b => x(1),
      c => c
    );
  u1: entity work.myxor
    port map(
      a => x(2),
      b => c,
      c => y
    );
end architecture str;

But this kind of mixture between a flip-flop and a XOR gate is so strange that another, maybe a bit more logical, interpretation could be the following: the hold time is the time for the fastest signals to propagate to the output and the propagation delay is the time for the slowest signals to propagate to the output. So, when the inputs of your XOR gate change, the output does not change for 3 ns, then it takes value X from 3 ns to 5 ns, and then the xor result. With the default inertial delay(*) you could simply use something like:

entity myxor is
  port(a, b: in  std_ulogic;
       c:    out std_ulogic
  );
end entity myxor;

architecture beh of myxor is
begin
  c <= 'X' after 3 ns, a xor b after 5 ns;
end architecture beh;

(*) If your interpretation of these specifications is more oriented towards transport delays, just modify the signal assignments accordingly:

architecture beh of myxor is
begin
  c <= transport 'X' after 3 ns, a xor b after 5 ns;
end architecture beh;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2