Here we present some ideas following the Built-in Self Test (BIST) theme.
These circuits will enable you to incorporate BIST into your designs using the principles of signature analysis.
At the heart of this BIST approach lies a pseudo-random binary sequence (PRBS) generator and a signature register. The PRBS generator is most easily implemented using a linear feedback shift register (LFSR). A PRBS generator allows us to generate all (well, almost all) of the required binary patterns for the circuit under test. The LFSR can be used to both generate the test sequence for the design that is to incorporate BIST and with slight modification can be used to capture the response of the design and generate a signature (the bit pattern held in the signature register).
The signature in the signature register can be compared to a known good signature. Within certain realms of mathematical probability, if the signature for the circuit being tested is the same as the known good signature, then the tested circuit is deemed as being functionally correct. There is a little maths involved in discovering the known good value for the signature of the circuit being tested but that's a subject for another day. Just now we are going to concentrate on the design of an LFSR and one kind of signature register.
First of all, let's build ourselves an LFSR. One can build many kinds of LFSR but for BIST the most interesting kind is the so-called maximal length LFSR (ML-LFSR). An ML-LFSR enables us to create a PRBS generator. Remember that this enables us to generate almost all of the binary patterns we could want.
This ML-LFSR is going to be a 10-bit design. The principles outlined for this 10-bit design apply to any N-bit ML-LFSR. In order for the 10-bit LFSR to be maximal length, the choice of the inputs to the lfsr_tap is defined by the characteristic polynomial which in this case tells us to take bits 6 and 9 as input to the XOR gate.
Figure 1. Maximal-length LFSR construction
The maximal length LFSR generates data that is almost random (hence the term ‘pseudo-random'). The output of the LFSR can be taken in parallel-out form or as a serial bit stream. The serial bit stream is usually taken from the MSB of the LFSR. Given taps 6 and 9, it turns out that the only pattern not generated is all zeroes. It is a fairly simple task to add a little extra circuitry to generate this pattern, but we won't tackle this just yet. Naturally this would give us a RBS generator, not a pseudo to be seen!
You are welcome to use the source code we provide but you must keep the copyright notice with the code (see the Notices page for details).
library IEEE; use IEEE.std_logic_1164.all; entity maximal_length_lfsr is port ( clock : std_logic; reset : std_logic; data_out : out std_logic_vector(9 downto 0) ); end maximal_length_lfsr; architecture modular of maximal_length_lfsr is signal lfsr_reg : std_logic_vector(9 downto 0); begin process (clock) variable lfsr_tap : std_logic; begin if RISING_EDGE(clock) then if reset = '1' then lfsr_reg <= (others => '1'); else lfsr_tap := lfsr_reg(6) xor lfsr_reg(9); lfsr_reg <= lfsr_reg(8 downto 0) & lfsr_tap; end if; end if; end process; data_out <= lfsr_reg; end modular;
Next, we have to come up with the signature register. This is a modified version of the LFSR, with an extra XOR gate on the data input to the LSB of the register.
library IEEE; use IEEE.std_logic_1164.all; entity signature_register is port ( data_in : std_logic; clock : std_logic; reset : std_logic; data_out : out std_logic_vector(9 downto 0) ); end signature_register; architecture RTL of signature_register is signal lfsr_reg : std_logic_vector(9 downto 0); begin process (clock) variable lfsr_tap : std_logic; begin if RISING_EDGE(clock) then if reset = '1' then lfsr_reg <= (others => '0'); else lfsr_tap := lfsr_reg(6) xor lfsr_reg(9); lfsr_reg <= lfsr_reg(8 downto 0) & (lfsr_tap xor data_in); end if; end if; end process; data_out <= lfsr_reg; end RTL;
By combining these two designs, a stand-alone generator and tester circuit can be created:
library IEEE; use IEEE.std_logic_1164.all; entity stand_alone_bist is port ( serial_in : std_logic; clock : std_logic; reset : std_logic; lfsr_out : out std_logic_vector(9 downto 0); signature_out : out std_logic_vector(9 downto 0) ); end stand_alone_bist; library DFT; architecture modular of stand_alone_bist is use DFT.all; component maximal_length_lfsr port ( clock : std_logic; reset : std_logic; data_out : out std_logic_vector(9 downto 0) ); end component; component signature_register port ( data_in : std_logic; clock : std_logic; reset : std_logic; data_out : out std_logic_vector(9 downto 0) ); end component; begin generator: maximal_length_lfsr port map (clock, reset, lfsr_out); analyzer: signature_register port map (serial_in, clock, reset, signature_out); end modular;
We are thus able to add a BIST capability to a design with a single output.
Here is a skeleton testbench architecture that can be used for testing designs. This particular testbench creates a 10-bit parallel data path for input to the faulty circuit and analyzes the single bit output from the faulty circuit.
architecture modular of sisr_tb is -- declarations begin tester: stand_alone_bist port map (serial_in, clock, reset, lfsr_out, parallel_out); dut: fault_circuit port map (lfsr_out, serial_in); -- testbench stimulus and respose-checking end modular;
To download the VHDL source code for this model, click here.