Close

Generalised fault injection

A project log for VHDL library for gate-level verification

Collection of ASIC cells and ProASIC3 "tiles" in VHDL so I can design and verify optimised code without the proprietary libraries

yann-guidon-ygdesYann Guidon / YGDES 06/07/2019 at 19:400 Comments

Christos has modified the original DFF gates to inject faults and evaluate/validate the fault-tolerant memory cells used by the CERN.

Meanwhile, I created this library to help with ASIC design, which is a different beast and methodology. I have no bit-flip issue (at least, directy) but "Design For Test" requires the design and evaluation of testing methods, such as BIST (at chip power-on) and post-factory pass/fail (for binning). A brand new fabbed chip must be thoroughly tested to ensure ALL the gates and wires work correctly under nominal conditions and a test rig must include all the necessary test vectors.

This is a different fault model, because the changes (usually) don't occur at run time. However the software structure is almost the same, and the fault can be set during startup at random (or under guidance from command line parameters), instead of while simulating.

The faults can be summarized to a simple model : stuck to 0 or stuck to 1. The wires could also be broken, thus float and pick up some neighbouring signal, but it can still be simplified down to : "not getting the expected value".

But how do you change a logic gate ? And how to keep things simple ? And how do we ensure only THAT gate (or a list thereof) is altered ? Well, a good understanding of GHDL and VHDL can do wonders :-D


There are tens of logic gates but they all have the same overall structure : 1, 2 or 3 inputs, then some "computation", then one output.

It's easy to stick the output to 0 or 1 (or even invert it though it's not useful) but it wouldn't be perfectly complete (because there could be faults inside the gate where the changes are conditional) and we can do even better.

The "computation" part can be a performed by a single table lookup. For 3 inputs, the output can be defined by 2^3=8 bits, the description fits in a byte. Each type of gate can thus be implemented as one call to a generic C function in VHPI, with the following parameters :

For now the library implements each gate as a direct boolean computation, it will take some effort to convert all the gates and check them for accuracy but it's not difficult.

The lookup table is usually represented as a string of bits, which is seen as a character string in VHDL. It's not convenient at all so the lookup table needs to be converted to "integer" in a way or another. The gate is easy to alter : simply flip (XOR) one bit of the lookup table.

To prevent conversion problems, and since the gates' functions are already defined and tested, the boolean function can be transformed into an actual VHDL function, that is passed/called by another function, to scan the inputs and create a "generic" during elaboration. This way, we don't have to calculate anything by hand. I'll have to find how to pass a function to another in VHDL... or something like that.


Now we need something else : we need to address each gate, to apply a fault only to one. We need to index/register all the gates to cover, and give each an ID. By default, ID=0 and no fault is applied.

But we also need to locate WHICH gate is faulted, because giving an arbitrary number won't be useful if it can't be matched with the code.

Furthermore, we don't want to have to modify the code and the system MUST register the gates independently, automatically.

Fortunately, VHDL already forces code to include labels to entities. There must be a way to get it, pass it to the generic definition and then to some C code that will perform some filtering.

I will reuse some of the tricks I have implemented for the framebuffer interface, with generics initialised with the return value of a C function that provides new values each time.


It's only the first thoughts and there are still many little details to check and validate. However my experience with GHDL shows that many underlying principles already work :

However so far I have not tried several other things...


OK, enough rants, let's code.

In the INC8 unit, we have lines like this :

e_R7A: entity AND3 port map(A=>A012, B=>A3456, C=>A(7),  Y=>   V);

Ideally, there is nothing to change, all the code works like before, we just use a different version of the entity.

There should be a way to get the name of the label from within the entity, then pass that string to a C function via VHPI. I'll see if I can use these predefined attributes:

E'SIMPLE_NAME  is a string containing the name of entity E.
E'INSTANCE_NAME  is a string containing the design hierarchy including E.
E'PATH_NAME  is a string containing the design hierarchy of E to design root.

 ...

Then the AND3 entity is defined in proasic3/gate_AND3.vhdl by:

entity AND3 is
  port( A, B, C : in std_logic;
              Y : out std_logic);
end AND3;

architecture rtl of AND3 is
begin
  Y <= (A and B) and C after gate_delay;
end rtl;

Nothing fancy but all the gates are a variation of this code, with a different truth table, here it would be : "10000000" or 0x80 in short form.

The trick is : how to generate the truth table from within the file, without duplicating too much code ?

entity AND3 is
  generic(
      TruthTable : integer := 0x80;
      EntName : string := something'instance_name
  )
  port( A, B, C : in std_logic;
              Y : out std_logic);
end AND3;

architecture rtl of AND3 is
begin
  Y <= VHP_lookup(A, B, C, lookup ) after gate_delay;
end rtl;

...

Discussions