Function with don't-care inputs

Wayne Conrad picture Wayne Conrad · Jul 28, 2013 · Viewed 8.6k times · Source

How can I implement a VHDL function which has "don't care" inputs and have the "don't cares" be directly represented?

Exercise 4.8-2a of Free Range VHDL asks me to:

...write VHDL models that implement these functions using...selected signal assignment.

a) F (A, B, C, D) = A'CD' + B'C + BCD'

This code works:

library ieee;
use ieee.std_logic_1164.all;

entity funca_selected is
  port (
    a: in std_ulogic;
    b: in std_ulogic;
    c: in std_ulogic;
    d: in std_ulogic;
    x: out std_ulogic);
end entity;

architecture rtl of funca_selected is
  signal s: std_ulogic_vector(3 downto 0);
begin
  s <= a & b & c & d;
  with s select x <=
    '1' when "0010" | "0110" | "0011" | "1010" | "1011" | "1110",
    '0' when others;
end architecture;

It is, however, a poor representation of the function definition. I want to code it using "don't care" inputs so that the code more closely matches the definition. This would be less work, and easier to get right. I tried this:

  with s select x <=
    '1' when "0-10" | "-01-" | "-110",
    '0' when others;

This does not work: When my test bed exercises this function, the result is always '0'.

I am using GHDL version 0.29+gcc4.3.i386.

How can a VHDL function represent "don't care" inputs?

Answer

Morten Zilmer picture Morten Zilmer · Jul 28, 2013

With overbar notation (like A̅) the function from exercise 4.8-2a is:

F(A, B, C, D) = A̅CD̅ + B̅C + BCD̅

GHDL does only support up to at most VHDL-2000 (according to GHDL features), so none of the VHDL-2008 compare operations with don't care ('-') check are available. An alternative expression for GHDL is the expression:

x <= ((not a) and c and (not d)) or
     ((not b) and c) or
     (b and c and (not d));

However, if VHDL-2008 is available in the tools, then the ?= operator, which checks for don't care, can be used as:

x <= (s ?= "0-10") or (s ?= "-01-") or (s ?= "-110");

Note that this expression also applies VHDL-2008 implicit boolean to std_logic conversion.

Or a case?, which also checks for don't care, can be used as:

process (s) is
begin
  case? s is
    when "0010" | "0110" | "0011" | "1010" | "1011" | "1110" => x <= '1';
    when others => x <= '0';
  end case?;
end process;

There is no with? operator in VHDL-2008 for concurrent case-like assign.

For more information about VHDL-2008 features, there is a nice paper here VHDL-2008: Why It Matters.