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.

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;

Now here is another file which instantiate these memory blocks with faults in it.


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;

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

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;

Solution

Use following commands to run the test.

ghdl -i *.vhd
ghdl -m memtest
ghdl -r memtest --stop-time=40ms --vcd=dilawar.vcd
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s