Testing memories for faults

As the VLSI memories are shrinking in their size, the density of cells which holds data is increasing exponentially. If one is making a living out of manufacturing them then he must make sure product he is releasing in the market is fault free. So he must hire some trained person to test memories of how much they are faulty. I wish I could do that with my natural memory . So at least he can make an informed decision whether he should sell his faulty product. In memories many kind of faults can occur. Most prominent of those are stuck-at faults (when some bit is permanently stuck to 0 or 1 value); coupling faults (write in in one location of memory can change the values at some other location), and Pattern Sensitive Faults (a certain pattern in some locations of memory will not allow to write at some address.) Another kind of faults are Decoder faults in which decoder itself have some faults (thus more than one addresses are mapped onto one address and any write will write at multiple locations). Not all of these faults can be test by a single test. Testing for all the faults are time consuming because they are so many of them. However if certain combination of tests, will limited yet sufficient coverage, does not detect faults in memory then one can be pretty sure that this memory does not contain many faults which are undetected. See this
Here in this post, We give some primitive tests  to detect these faults. Lets say following is my memory block.
[sourcecode language="text"]
entity MemBlock is
generic(has_decoder_fault, has_stuck_at_fault, has_psf, has_cf: boolean := false);
port(addr, data_in: in bit_vector(7 downto 0);
read_en, write_en: in bit;
data_out: out bit_vector(7 downto 0));
end entity;
architecture Behave of MemBlock is
type MemArray is array (natural range <>) of bit_vector(7 downto 0);
— procedure that models the update of the memory array,
— given an incoming word (data_in) and a row index (I)
procedure Update_Mem(signal mem_array: inout MemArray;I: in integer; data_in: in bit_vector(7 downto 0)) is
variable cword: bit_vector(7 downto 0);
variable uI, dI: integer;
variable aflag : boolean; — set true when write is over.
begin
aflag := false;
— PSF
if(I = 128 and has_psf) then
uI := 129;
dI := 127;
cword := mem_array(I);
for J in 7 downto 0 loop
— here is the PSF
if not ( mem_array(uI)(J) = ‘1’ and mem_array(dI)(J) = ‘1’) then
mem_array(I)(J) <= data_in(J);
end if;
end loop;
aflag := true;
end if;
if(I=127 and has_cf) then
if(mem_array(127)(0) = ‘0’ and data_in(0) = ‘1’) then
mem_array(128)(0) <= ‘1’;
end if;
mem_array(127) <= data_in;
aflag := true;
end if;
if(I=129 and has_cf) then
if(mem_array(129)(0) = ‘0’ and data_in(0) = ‘1’) then
mem_array(128)(0) <= ‘0’;
end if;
mem_array(129) <= data_in;
aflag := true;
end if;
if(not aflag) then
mem_array(I) <= data_in;
end if;
if(has_stuck_at_fault) then
mem_array(129)(0) <= ‘1’;
mem_array(128)(0) <= ‘0’;
end if;
end procedure;
— converts bit vector to a natural number
function To_Natural(x: bit_vector) return natural is
variable ret_var : natural := 0;
alias lx: bit_vector(x’length downto 1) is x;
begin
for I in 1 to lx’length loop
if(lx(I) = ‘1’) then
ret_var := ret_var + (2**(I-1));
end if;
end loop;
return(ret_var);
end To_Natural;
— output of the decoder
signal decode_sig: bit_vector(255 downto 0);
— memory array
signal mem_array: MemArray(0 to 255);
begin
— decoder process
process(addr)
begin
decode_sig <= (others => ‘0’);
for I in 0 to 255 loop
if(I=To_Natural(addr)) then
decode_sig(I) <= ‘1’;
if(I=128 and has_decoder_fault) then
decode_sig(I+1) <= ‘1’;
end if;
end if;
end loop;
end process;
— memory array access process
process(addr, data_in, read_en, write_en)
variable data_out_var: bit_vector(7 downto 0);
begin
data_out_var := (others => ‘0’);
for I in 0 to 255 loop
if decode_sig(I) = ‘1’ then
if(read_en = ‘1’) then
data_out_var := data_out_var or mem_array(I); — Wired OR
elsif write_en = ‘1’ then
Update_Mem(mem_array,I,data_in);
end if;
end if;
end loop;
data_out <= data_out_var;
end process;
end Behave;
[/sourcecode]
Now here is another file which instantiate these memory blocks with faults in it.
[sourcecode language="text"]
entity MemTest is
end entity MemTest;
architecture Behave of MemTest is
— utility function: to increment an address
function Increment(x: bit_vector) return bit_vector is
alias lx: bit_vector(1 to x’length) is x;
variable ret_var: bit_vector(1 to x’length);
variable carry: bit;
begin
carry := ‘1’;
for I in x’length downto 1 loop
ret_var(I) := lx(I) xor carry;
carry := carry and lx(I);
end loop;
return(ret_var);
end Increment;
signal addr, data_in, data_out_df, data_out_saf, data_out_psf,data_out_cf : bit_vector(7 downto 0);
signal read_en, write_en: bit;
— memory block
— array of 8 bit words, with 8 bit address.
— with the following behaviour.

-- if read_en = '1' then
--      data_out = memory_contents(addr);
-- elsif write_en = '1' then
--      memory_contents(addr) = data_in;
    --
component MemBlock
    generic(has_decoder_fault, has_stuck_at_fault, has_psf, has_cf: boolean := false);
    port(addr, data_in: in bit_vector(7 downto 0);
            read_en, write_en: in bit;
            data_out: out bit_vector(7 downto 0));
end component;
constant zero8: bit_vector(7 downto 0) := (others => '0');
-- utility procedures
-- Write addr/data pair into memory using write_en
procedure Write(signal addr: out bit_vector(7 downto 0);
        signal data: out bit_vector(7 downto 0);
        signal write_en: out bit;
        addr_var: in bit_vector(7 downto 0);
        data_var: in bit_vector(7 downto 0)) is
begin
        addr <= addr_var;
        data <= data_var;
        wait for 1 ns;
        write_en <= '1';
        wait for 1 ns;
        write_en <= '0';
        wait for 1 ns;
end procedure;
-- Read data from memory using read_en, addr.
-- NOTE: data must be present on data_out signal on
--       completion of procedure.
procedure Read(signal addr: out bit_vector(7 downto 0);
    signal read_en: out bit;
    addr_var: bit_vector(7 downto 0)) is
begin
    addr <= addr_var;
    wait for 1 ns;
    read_en <= '1';
    wait for 1 ns;
    read_en <= '0';
end procedure;

begin
— four memory blocks, each of which has one type of fault in it.
— this has a decoder-fault
mb_df: MemBlock generic map(has_decoder_fault => true, has_stuck_at_fault => false,
has_psf => false, has_cf => false)
port map(addr => addr, data_in => data_in,
data_out => data_out_df, read_en => read_en,
write_en => write_en);
— this has stuck-at-faults in the array
mb_saf: MemBlock generic map(has_decoder_fault => false, has_stuck_at_fault => true,
has_psf => false, has_cf => false)
port map(addr => addr, data_in => data_in,
data_out => data_out_saf, read_en => read_en,
write_en => write_en);
— this has a pattern-sensitive-fault in the array. The neighbourhood for the
— fault is adjacent bits in the same column of the array.
mb_psf: MemBlock generic map(has_decoder_fault => false, has_stuck_at_fault => false,
has_psf => true, has_cf => false)
port map(addr => addr, data_in => data_in,
data_out => data_out_psf, read_en => read_en,
write_en => write_en);
— this has some coupling faults in the array
mb_cf: MemBlock generic map(has_decoder_fault => false, has_stuck_at_fault => false,
has_psf => false, has_cf => true)
port map(addr => addr, data_in => data_in,
data_out => data_out_cf, read_en => read_en,
write_en => write_en);
————- test process ————————————————
process
variable curr_addr, next_addr: bit_vector(7 downto 0);
variable err_flag : boolean := false;
begin

    --                          TEST SEQUENCE STARTS HERE
    ----------------------------------------------------------------------------------------
    read_en <= '0'; write_en <= '0';
    wait for 1 ns;
    curr_addr := (others => '0');
    while true loop
        -- write followed by read
        Write(addr,data_in,write_en,curr_addr,curr_addr);
        Read(addr,read_en,curr_addr);
        -- check data_out
        assert (data_out_df = curr_addr) report
            "Data mismatch in memory with decoder fault" severity ERROR;
        assert (data_out_saf = curr_addr) report
            "Data mismatch in memory with stuck-at-fault" severity ERROR;
        assert (data_out_psf = curr_addr) report
            "Data mismatch in memory with pattern-sensitive-fault" severity ERROR;
        assert (data_out_cf = curr_addr) report
            "Data mismatch in memory with coupling-fault" severity ERROR;
        err_flag := err_flag or (data_out_df /= curr_addr) or (data_out_saf /= curr_addr) or
                (data_out_psf /= curr_addr) or (data_out_cf /= curr_addr);
        next_addr := Increment(addr);
        if(next_addr = zero8) then
            exit;
        end if;
        curr_addr := next_addr;
    end loop;
    ----------------------------------------------------------------------------------------
    --                               TEST SEQUENCE ENDS HERE
    ----------------------------------------------------------------------------------------
    assert not err_flag report "Test Failed" severity ERROR;
    assert err_flag report "Test Passed" severity NOTE;
    wait;
end process;

end Behave;
[/sourcecode]
If you run the simulation using the algorithm in this existing test bench, the memory block seems to be functioning correctly. However, each of the memory blocks has faults present in it (as you can verify by examining the VHDL code). Why did the test fail to detect the errors? Now one needs to modify the test-bench to use a single test (sequence of reads and writes) that can detect any decoder/stuck-at/coupling/pattern-sensitive fault in MemBlock. Pattern-sensitive faults may be assumed to be for a neighbourhood which consists of adjacent bits in the same column of the 256×8 array. Confirm that this modified test-bench detects that each of the MemBlock instances is faulty.
This was given as an assignment in Verification and Testing of VLSI course offered by Prof M. P. Desai at IIT Bombay.
Attached is the detailed solution to this problem. We attach the VHDL code which is my solution. However, in my solution, I make an assumption that only adjacent cells can cause coupling/pattern sensitive/decoder faults. In practice, situation is much worse than that. We have used ghdl compiler to test it.
solution_memory_testing
[sourcecode language="text"]
use std.textio.all;
entity MemTest is
end entity MemTest;
architecture Behave of MemTest is
— utility function: to increment an address
function Increment(x: bit_vector) return bit_vector is
alias lx: bit_vector(1 to x’length) is x;
variable ret_var: bit_vector(1 to x’length);
variable carry: bit;
begin
carry := ‘1’;
for I in x’length downto 1 loop
ret_var(I) := lx(I) xor carry;
carry := carry and lx(I);
end loop;
return(ret_var);
end Increment;
signal addr, addr2, data_in, data_out_df, data_out_saf, data_out_psf,data_out_cf : bit_vector(7 downto 0);
signal read_en, write_en: bit;
component MemBlock
generic(has_decoder_fault, has_stuck_at_fault, has_psf, has_cf: boolean := false);
port(addr, data_in: in bit_vector(7 downto 0);
read_en, write_en: in bit;
data_out: out bit_vector(7 downto 0));
end component;
constant zero8: bit_vector(7 downto 0) := (others => ‘0’);
— utility procedures
— Write addr/data pair into memory using write_en
procedure Write(signal addr: out bit_vector(7 downto 0);
signal data: out bit_vector(7 downto 0);
signal write_en: out bit;
addr_var: in bit_vector(7 downto 0);
data_var: in bit_vector(7 downto 0)) is
begin
addr <= addr_var;
data <= data_var;
wait for 1 ns;
write_en <= ‘1’;
wait for 1 ns;
write_en <= ‘0’;
wait for 1 ns;
end procedure;
— Read data from memory using read_en, addr.
— NOTE: data must be present on data_out signal on
— completion of procedure.
procedure Read(signal addr: out bit_vector(7 downto 0);
signal read_en: out bit; addr_var: bit_vector(7 downto 0)) is
begin
addr <= addr_var;
wait for 1 ns;
read_en <= ‘1’;
wait for 1 ns;
read_en <= ‘0’;
end procedure;
begin
— four memory blocks, each of which has one type of fault in it.
— this has a decoder-fault
mb_df: MemBlock generic map(has_decoder_fault => true, has_stuck_at_fault => false,
has_psf => false, has_cf => false)
port map(addr => addr, data_in => data_in,
data_out => data_out_df, read_en => read_en,
write_en => write_en);
— this has stuck-at-faults in the array
mb_saf: MemBlock generic map(has_decoder_fault => false, has_stuck_at_fault => true,
has_psf => false, has_cf => false)
port map(addr => addr, data_in => data_in,
data_out => data_out_saf, read_en => read_en,
write_en => write_en);
— this has a pattern-sensitive-fault in the array. The neighbourhood for the
— fault is adjacent bits in the same column of the array.
mb_psf: MemBlock generic map(has_decoder_fault => false, has_stuck_at_fault => false,
has_psf => true, has_cf => false)
port map(addr => addr, data_in => data_in,
data_out => data_out_psf, read_en => read_en,
write_en => write_en);
— this has some coupling faults in the array
mb_cf: MemBlock generic map(has_decoder_fault => false, has_stuck_at_fault => false,
has_psf => false, has_cf => true)
port map(addr => addr, data_in => data_in,
data_out => data_out_cf, read_en => read_en,
write_en => write_en);
————- test process ————————————————
process
variable curr_addr, next_addr, temp_n_addr, temp_nn_addr, temp_data, next_data: bit_vector(7 downto 0);
variable err_flag : boolean := false;
variable err_add, l_psf, l_df, l_saf, l_cf : line;
begin

        --        TEST SEQUENCE STARTS HERE
        -----------------------------------------------------------
        read_en <= '0'; write_en <= '0';
        wait for 1 ns;
        curr_addr := (others => '0');
        while true loop
            -----------------------------------------------------
            --  This test will test the stuck at 1/0 faults.
            -----------------------------------------------------
            temp_data := (others => '0');
            next_data := (others => '1');
            -- test for s-a-1 faults.
            Write(addr, data_in, write_en, curr_addr, temp_data);
            Read(addr, read_en, curr_addr);
            -- assert yourself.
            assert (data_out_saf = temp_data) report
            "Data mismatch in memory with stuck-at-1-fault" severity ERROR;
            -- log this error.
            if data_out_saf /= temp_data then
                write(l_saf, String'("A: "));
                write(l_saf, curr_addr);
                write(l_saf, String'(" D: "));
                write(l_saf, temp_data);
                write(l_saf, String'(" saf1: "));
                write(l_saf, data_out_saf);
                writeline(output, l_saf);
            end if;
            Write(addr, data_in, write_en, curr_addr, next_data);
            Read(addr, read_en, curr_addr);
            -- assert yourself.
            assert (data_out_saf = next_data) report
            "Data mismatch in memory with stuck-at-0-fault" severity ERROR;
            -- log this error.
            if data_out_saf /= next_data then
                write(l_saf, String'("A: "));
                write(l_saf, curr_addr);
                write(l_saf, String'(" D: "));
                write(l_saf, next_data);
                write(l_saf, String'(" saf0: "));
                write(l_saf, data_out_saf);
                writeline(output, l_saf);
            -- NOTE : Must reset this cell while doing cf testing. Else
            --    problem might occur in first and last cells.
            end if;
           --            while true loop
            temp_data := (others => '0');
            next_data := (others => '1');
            temp_n_addr := Increment(curr_addr);
            -- reset the cell we are going to test.
            Write(addr, data_in, write_en, temp_n_addr, temp_data);
            -- give an up-transition at left location and read data. If there isa
            -- coupling faults. This should change the value of cell from 0 to 1
            Write(addr, data_in, write_en, curr_addr, temp_data);
            Write(addr, data_in, write_en, curr_addr, next_data);
            Read(addr, read_en, temp_n_addr); -- read the next address.
            -- Assert yourserf if you got it right.
            assert (data_out_cf = temp_data) report
            "Data mismatch in memory with coupling l_at_0_u faults" severity ERROR;
            -- log this error.
            if data_out_cf /= temp_data then
                write(l_cf, String'("A: "));
                write(l_cf, temp_n_addr);
                write(l_cf, String'(" 0lu "));
                write(l_cf, data_out_cf);
                writeline(output, l_cf);
                -- reset the memory cell.
                Write(addr, data_in, write_en, temp_n_addr, temp_data);
            end if;
            -- give a low transition at left location and read data. If there is a
            -- coupling fault then this should change the value of cell from 0 to 1
            Write(addr, data_in, write_en, curr_addr, temp_data);
            Read(addr, read_en, temp_n_addr); -- read the next address.
            -- Assert yourserf if you got it right.
            assert (data_out_cf = temp_data) report
            "Data mismatch in memory with coupling l_at_0_d faults" severity ERROR;
            -- log this error.
            if data_out_cf /= temp_data then
                write(l_cf, String'("A: "));
                write(l_cf, temp_n_addr);
                write(l_cf, String'(" 0ld "));
                write(l_cf, data_out_cf);
                writeline(output, l_cf);
                -- reset the memory cell.
                Write(addr, data_in, write_en, temp_n_addr, temp_data);
            end if;
            -- REPEAT IT FROM RIGHT SIDE
            temp_nn_addr := Increment(temp_n_addr);
            -- give an up-transition at right location and read data. If there isa
            -- coupling faults. This should change the value of cell from 0 to 1
            Write(addr, data_in, write_en, temp_nn_addr, next_data);
            Read(addr, read_en, temp_n_addr); -- read the next address.
            assert (data_out_cf = temp_data) report
            "Data mismatch in memory with coupling r_at_0_u faults" severity ERROR;
            -- log this error.
            if data_out_cf /= temp_data then
                write(l_cf, String'("A: "));
                write(l_cf, temp_n_addr);
                write(l_cf, String'(" 0ru "));
                write(l_cf, data_out_cf);
                writeline(output, l_cf);
                -- reset the memory cell.
                Write(addr, data_in, write_en, temp_n_addr, temp_data);
            end if;
            -- give a low transition at right location and read data. If there is a
            -- coupling fault then this should change the value of cell from 0 to 1
            Write(addr, data_in, write_en, temp_nn_addr, temp_data);
            Read(addr, read_en, temp_n_addr); -- read the next address.
            -- Assert yourserf if you are right.
            assert (data_out_cf = temp_data) report
            "Data mismatch in memory with coupling r_at_0_d faults" severity ERROR;
            -- log this error.
            if data_out_cf /= temp_data then
                write(l_cf, String'("A: "));
                write(l_cf, temp_n_addr);
                write(l_cf, String'(" 0rd "));
                write(l_cf, data_out_cf);
                writeline(output, l_cf);
                -- reset the memory cell.
                Write(addr, data_in, write_en, temp_n_addr, temp_data);
            end if;
            temp_data := "00000000";
            next_data := "11111111";
            temp_n_addr := Increment(curr_addr);
            temp_nn_addr := Increment(temp_n_addr);
            -- Following line will write 1 in next adress.
            Write(addr, data_in, write_en, temp_n_addr, next_data);
            -- Give an up transition at left location and read for fault.
            Write(addr, data_in, write_en, curr_addr, next_data);
            Read(addr, read_en, temp_n_addr);
            -- assert it.
            assert (data_out_cf = next_data) report
            "Data mismatch in memory with coupling l_at_1_u faults" severity ERROR;
            -- log this error.
            if data_out_cf /= next_data then
                write(l_cf, String'("A: "));
                write(l_cf, temp_n_addr);
                write(l_cf, String'(" 1lu "));
                write(l_cf, data_out_cf);
                -- reset the memory cell.
                Write(addr, data_in, write_en, temp_n_addr, next_data);
            end if;
            -- Give a down transition at left location. And read for faults.
            Write(addr, data_in, write_en, curr_addr, temp_data);
            Read(addr, read_en, temp_n_addr);
            -- Assert yourserf if you are right.
            assert (data_out_cf = next_data) report
            "Data mismatch in memory with coupling l_at_1_d faults" severity ERROR;
            -- log this error.
            if data_out_cf /= next_data then
                write(l_cf, String'("A: "));
                write(l_cf, temp_n_addr);
                write(l_cf, String'(" 1lu "));
                write(l_cf, data_out_cf);
                -- reset the memory cell.
                Write(addr, data_in, write_en, temp_n_addr, next_data);
            end if;
            -- Give an up transition at right location.
            Write(addr, data_in, write_en, temp_nn_addr, next_data);
            Read(addr, read_en, temp_n_addr);
            -- Assert yourserf if you are right.
            assert (data_out_cf = next_data) report
            "Data mismatch in memory with coupling r_at_1_u faults" severity ERROR;
            -- log this error.
            if data_out_cf /= next_data then
                write(l_cf, String'("A: "));
                write(l_cf, temp_n_addr);
                write(l_cf, String'(" 1ru "));
                write(l_cf, data_out_cf);
                writeline(output, l_cf);
                -- reset the memory cell.
                Write(addr, data_in, write_en, temp_n_addr, next_data);
            end if;
            -- Give a down transition at right location.
            Write(addr, data_in, write_en, temp_nn_addr, temp_data);
            Read(addr, read_en, temp_n_addr);
            -- Assert yourserf if you are right.
            assert (data_out_cf = next_data) report
            "Data mismatch in memory with coupling r_at_1_d faults" severity ERROR;
            -- log this error.
            if data_out_cf /= next_data then
                write(l_cf, String'("A: "));
                write(l_cf, temp_n_addr);
                write(l_cf, String'(" 1rd "));
                write(l_cf, data_out_cf);
                -- reset the memory cell.
                Write(addr, data_in, write_en, temp_n_addr, next_data);
            end if;
            ----------------------------------------------
            -- Test pattern for Pattern Sensitive Faults.
            ----------------------------------------------
            temp_data := (others => '0');
            next_data := (others => '1');
            temp_n_addr := Increment(curr_addr);
            temp_nn_addr := Increment(temp_n_addr);
            -- reset the cell we are going to test.
            Write(addr, data_in, write_en, temp_n_addr, temp_data);
            ------- case 1
            -- Write 1 in left and 0 in right and check for PSF.
            Write(addr, data_in, write_en, curr_addr, next_data);
            Write(addr, data_in, write_en, temp_nn_addr, temp_data);
            -- Now write 1 in the cell and read the same value.
            Write(addr, data_in, write_en, temp_n_addr, next_data);
            Read(addr, read_en, temp_n_addr);
            assert (data_out_psf = next_data) report
            "Data can not be written due to l1r0 PSF." severity ERROR;
            -- log this error.
            if data_out_psf /= next_data then
                write(l_psf, String'("A "));
                write(l_psf, temp_n_addr);
                write(l_psf, String'(" l1r0 "));
                write(l_psf, data_out_psf);
                writeline(output, l_psf);
            end if;
            -- write 0 in the cell and check for the PSF.
            Write(addr, data_in, write_en, temp_n_addr, temp_data);
            Read(addr, read_en, temp_n_addr);
            assert (data_out_psf = temp_data) report
            "Data can not be written due to l1r0 PSF." severity ERROR;
            -- log this error.
            if data_out_psf /= temp_data then
                write(l_psf, String'("A "));
                write(l_psf, temp_n_addr);
                write(l_psf, String'(" l1r0 "));
                write(l_psf, data_out_psf);
                writeline(output, l_psf);
            end if;
            -------- case 2
            -- Write 1 in left and 1 in right and check for PSF
            Write(addr, data_in, write_en, curr_addr, next_data);
            Write(addr, data_in, write_en, temp_nn_addr, next_data);
            -- Now write 1 in the cell and read the same value.
            Write(addr, data_in, write_en, temp_n_addr, next_data);
            Read(addr, read_en, temp_n_addr);
            assert (data_out_psf = next_data) report
            "Data can not be written due to l1r1 PSF." severity ERROR;
            -- log this error.
            if data_out_psf /= next_data then
                write(l_psf, String'("A "));
                write(l_psf, temp_n_addr);
                write(l_psf, String'(" l1r1 "));
                write(l_psf, data_out_psf);
                writeline(output, l_psf);
            end if;
            -- write 0 in the cell and check for the PSF.
            Write(addr, data_in, write_en, temp_n_addr, temp_data);
            Read(addr, read_en, temp_n_addr);
            assert (data_out_psf = temp_data) report
            "Data can not be written due to l1r1 PSF." severity ERROR;
            -- log this error.
            if data_out_psf /= temp_data then
                write(l_psf, String'("A "));
                write(l_psf, temp_n_addr);
                write(l_psf, String'(" l1r1 "));
                write(l_psf, data_out_psf);
                writeline(output, l_psf);
            end if;
            -------- case 3
            -- Write 0 in left and 1 in right and check for PSF
            Write(addr, data_in, write_en, curr_addr, temp_data);
            Write(addr, data_in, write_en, temp_nn_addr, next_data);
            -- Now write 1 in the cell and read the same value.
            Write(addr, data_in, write_en, temp_n_addr, next_data);
            Read(addr, read_en, temp_n_addr);
            assert (data_out_psf = next_data) report
            "Data can not be written due to l0r1 PSF." severity ERROR;
            -- log this error.
            if data_out_psf /= next_data then
                write(l_psf, String'("A "));
                write(l_psf, temp_n_addr);
                write(l_psf, String'(" l1r1 "));
                write(l_psf, data_out_psf);
                writeline(output, l_psf);
            end if;
            -- write 0 in the cell and check for the PSF.
            Write(addr, data_in, write_en, temp_n_addr, temp_data);
            Read(addr, read_en, temp_n_addr);
            assert (data_out_psf = temp_data) report
            "Data can not be written due to l0r1 PSF." severity ERROR;
            -- log this error.
            if data_out_psf /= temp_data then
                write(l_psf, String'("A "));
                write(l_psf, temp_n_addr);
                write(l_psf, String'(" l0r1 "));
                write(l_psf, data_out_psf);
                writeline(output, l_psf);
            end if;
            -------- case 4
            -- Write 0 in left and 0 in right and check for PSF
            Write(addr, data_in, write_en, curr_addr, temp_data);
            Write(addr, data_in, write_en, temp_nn_addr, temp_data);
            -- Now write 1 in the cell and read the same value.
            Write(addr, data_in, write_en, temp_n_addr, next_data);
            Read(addr, read_en, temp_n_addr);
            assert (data_out_psf = next_data) report
            "Data can not be written due to l0r0 PSF." severity ERROR;
            -- log this error.
            if data_out_psf /= next_data then
                write(l_psf, String'("A "));
                write(l_psf, temp_n_addr);
                write(l_psf, String'(" l0r0 "));
                write(l_psf, data_out_psf);
                writeline(output, l_psf);
            end if;
            -- write 0 in the cell and check for the PSF.
            Write(addr, data_in, write_en, temp_n_addr, temp_data);
            Read(addr, read_en, temp_n_addr);
            assert (data_out_psf = temp_data) report
            "Data can not be written due to l0r0 PSF." severity ERROR;
            -- log this error.
            if data_out_psf /= temp_data then
                write(l_psf, String'("A "));
                write(l_psf, temp_n_addr);
                write(l_psf, String'(" l0r0 "));
                write(l_psf, data_out_psf);
                writeline(output, l_psf);
            end if;
            -------------------------------------
            -- Decoder fault.
            ------------------------------------
            -- NOTE : Ideally one should write 0 to a cell and write 1 to
            -- all the cells which are 1 hamming distance away to cover all
            -- the stuck-at-fautls in decoder. Here, we check immediate left
            -- and right cell for fautls.
            Write(addr, data_in, write_en, temp_n_addr, next_data);
            -- write all 1 in left and right cell.
            Write(addr, data_in, write_en, curr_addr, temp_data);
            Write(addr, data_in, write_en, temp_nn_addr, temp_data);
            Read(addr, read_en, temp_n_addr);
            assert (data_out_df = next_data) report
            "Decoder fault - value written into some adjacent cell." severity ERROR;
            -- log this error
            if data_out_df /= next_data then
                write(l_df, String'("To "));
                write(l_df, temp_n_addr);
                write(l_df, String'(" From "));
                write(l_df, curr_addr);
                write(l_df, String'(" DF "));
                write(l_df, data_out_df);
                writeline(output, l_df);
            -- reset cells for next test.
                Write(addr, data_in, write_en, temp_n_addr, temp_data);
                Write(addr, data_in, write_en, temp_nn_addr, temp_data);
                -- to make sure this does not interfere with other test.
                Write(addr, data_in, write_en, curr_addr, temp_data);
            end if;
            next_addr := temp_n_addr;
            -- if all addresses have been reached, exit
            if(next_addr = "11111111") then
                exit;
            end if;
            curr_addr := next_addr;
        end loop;
        assert false report "Test completed." severity NOTE;
        wait;
    end process;
end Behave;

[/sourcecode]

Solution

Use following commands to run the test.
[sourcecode language="text"]
ghdl -i *.vhd
ghdl -m memtest
ghdl -r memtest –stop-time=40ms –vcd=dilawar.vcd
[/sourcecode]

Leave a Reply

Scroll to Top