help icon Matching Don’t Care’s ('-') in Expressions


Question: I am trying to write a VHDL model to represent a PLA. I have a logic minimised truth table to define the PLA, and as such there are don't care states on the inputs, as follows:

   Inputs   Outputs 
  X1X10X1  100000100
  1X01011  001100000
  0X111X1  100001000

and so on.

So far I have tried two methods to implement this format, as follows:

  -- METHOD A
  case PLA_IN is
  when "-1-10-1" => 
    PLA_OUT <= "100000100";
  when "1-01011" => 
    PLA_OUT <= "001100000";
  -- etc

  -- METHOD B
  case PLA_IN is
  when ('0'|'1','1','0'|'1','1','0','0'|'1','1') =>
    PLA_OUT <= "100000100";
  when ('1','0'|'1','0','1','0','1','1') =>
    PLA_OUT <= "001100000";
  -- etc

Method A compiles but does not simulate correctly because the case statement is doing a string compare. Method B does not even compile. So, how can I implement a logic minimised PLA which includes don't care states on the inputs?

Answer: As you correctly surmise, method A does not work because the case statement matches the characters in the input vector PLA_IN with the characters in the when part such that only a '-' in the input vector will match a '-' in the when vector. For example, "-1-10-1" will match "-1-10-1", but "1111011" will not match "-1-10-1". The don't care value of the type Std_ulogic (from the IEEE 1164 standard) is intended to represent output don't cares; outputs should be given the value '-' to avoid overspecifying the logic function.

Method B does not compile because you just cannot do that in VHDL! According to the VHDL Language Reference Manual, the choices given in the when parts of a case statement must be locally static expressions. This mumbo jumbo means that you cannot write a list of values enclosed in brackets (called an aggregate) in the when part. What is more, each value in an aggregate must be an expression, and the vertical bar cannot be used within an expression, so something like ('0'|'1','1','0'|'1','1','0','0'|'1','1') does not make sense in VHDL anyway. The vertical bar can only be used to separate alternative choices, so when "0101001" | "1101001" => is OK, and (0|2 => '0', 1|3 => '1') is OK, but ('0'|'1','0'|'1') is not.

To describe input don't cares in VHDL, we need to write some kind of pattern matching algorithm to tell the VHDL simulator to match any character with a '-'. There are many different ways of doing this, but the harsh fact of life is that you must do it yourself: pattern matching does not come for free with the VHDL language. Perhaps the neatest way to do this in VHDL is as a reusable function with unconstrained array inputs, such that the same function can be reused without modification for any PLA table. An example is given below:

  library ieee;
  use ieee.std_logic_1164.all;
  
  package pla is
    type tabletype is 
      array (natural range , natural range <>) of std_logic;
    function lookup (table: in tabletype;
                     input: in std_logic_vector) return std_logic_vector;
  end;
  
  package body pla is
    function lookup (table: in tabletype;
                     input: in std_logic_vector) return std_logic_vector is
      variable result: std_logic_vector(1 to table'length(2) - input'length)
                       := (others => 'X');
      constant offset: natural := input'length;
      constant tab:    tabletype(1 to table'length(1), 1 to table'length(2))
                       := table;
      constant ip: std_logic_vector(1 to input'length) := input;
    begin
      scantable: for i in tab'range(1) loop
        for j in ip'range loop
          next scantable when ip(j) /= tab(i,j) and tab(i,j) /= '-';
        end loop;
        for j in result'range loop
          result(j) := tab(i, offset + j);
        end loop;
        exit scantable;
      end loop;
      return result;
    end lookup;
  end;
  
  library ieee;
  use ieee.std_logic_1164.all;
  use work.pla.all;
  
  entity hw is
    port (pla_in:  in  std_logic_vector(6 downto 0);
          pla_out: out std_logic_vector(8 downto 0));
  end;
  
  architecture v1 of hw is
    constant pla: tabletype(1 to 6, 15 downto 0) :=
     ("-1-10-1100000100",
      "1-01011001100000",
      "0-111-1100001000",
      "--111--000000011",
      "010001-110000011",
      "-100011110000011");
  begin
        pla_out <= lookup(pla, pla_in);
  end;

The package pla provides a function lookup that is called with a PLA table and in input vector, and returns an output vector. Each row of the table contains an input vector and an output vector joined end to end. The input vector may include don't cares, and the function finds the first match in the table. The design entity hw shows how the function can be called.

Incidentally, the VHDL code given here is synthesizable with an RTL synthesis tool (given suitable modifications to allow for the limited VHDL language support of some tools), so that PLA tables can be used to specify the functionality of blocks within a synthesized gate array or FPGA implementation.


help iconVHDL FAQ
xDoulos Training Courses
author iconBack to “Your VHDL Problems Answered” Index


river sceneDoulos Home Page

Copyright 1995-1996 Doulos
This page was last updated 9th February 1996.

mail iconWe welcome your e-mail comments. Please contact us at: webmaster@doulos.co.uk