Recently, I changed from ModelSim from Mentor Graphics to VCS_MX from Synopsys to run the fault injection simulation campaign.
Before, the fault injection is done through the force (noforce) command in the script supported by ModelSim (and examine command if the fault to be injected is Bit Flip). Though this approach works fine, but the speed is slow. I made a wrong decision of using C to generate the script and start the fault injection simulation, which involves a lot string handling, and I was not able to do that elegantly in a short time.
And then again, the DUT we used in the group is miniMIPS (kinda outdated, not actively updated in openCores), the original ROM/RAM module is size-limited, and to enlarge the size directly in VHDL code will cause simulator to infer large register array and leads to huge memory cost and simulation speed decrease (it happens to me several times that ModelSim report out of memory).
Another approach is to use foreign language interface to emulate the behavior of memory module:
1) the external program will communicate with the DUT directly: read outputs from DUT and assign inputs to DUT just as a VHDL module. Timing, delay etc. are directly controllable in the external program.2) Use a VHDL wrapper, in which external functions are called as memory read/memory write. Timing, delay controlled in the VHDL wrapper (easier than the first solution) as following.
————in the VHDL wrapper ————————
if r_w /= '1' then -- Reading in memory read_mem(vAddr, vData); data_inout <= std_logic_vector(to_signed(vData, 32)); else vData := to_integer(signed(data_inout)); write_mem(vAddr, vData);
———–the foreign function declarations in VHDL———–
package memc_pkg is procedure read_mem(addr : in integer; -- integer address (32bit); data : out integer); -- integer data out (32bit instruction) attribute foreign of read_mem : procedure is "read_mem ./mem.sl"; procedure write_mem(addr : in integer; -- integer address (32bit); data : in integer); -- integer data out (32bit instruction) attribute foreign of write_mem : procedure is "write_mem ./mem.sl"; procedure write_img; attribute foreign of write_img : procedure is "write_img ./mem.sl"; procedure reload_program; attribute foreign of reload_program : procedure is "reload_program ./mem.sl"; end; package body memc_pkg is procedure read_mem(addr : in integer;data : out integer ) is begin assert false report "ERROR: foreign subprogram read_mem not called" severity note; end; procedure write_mem(addr : in integer;data : in integer ) is begin assert false report "ERROR: foreign subprogram write_mem not called" severity note; end; procedure write_img is begin assert false report "ERROR: foreign subprogram write_img not called" severity note; end; procedure reload_program is beginassert false report "ERROR: foreign subprogram clean_ram not called" severity note; end; end;
——————Example Makefile for C program —————-
.PHONY: cleanall : mem.sl memc.o: mem_v2.c gcc -c -g -I$(MTI_HOME)/include $^ -o $@ -fPIC -fno-stack-protector mem.sl : memc.o -lsqlite3ld -shared -E -o $@ $^ clean: rm -f memc.o memc.sl
$MTI_HOME should be set to point to the modeltech folder of your ModelSim installation.
Then to get all the fault site to inject, for example, SA0/1, dump a VCD file, and parse the VCD file afterwards to get all the signals in the design you can use force/noforce and examine commands. (This is not exactly the fault site list, however, can be used as see fit)To get fault sites for Bit Flip faults (at Gate Level), extract all the signals end with “/Q” in the design (this depends on the library used, all and only FF in the library we used will end with “/Q”, I’m not sure it’s true with other library).
Generate the script to be executed by ModelSim to inject faults and collect results.
Problem:The restart command by ModelSim may not be enough (or I missed some arguments to the restart command) to release all memory (or my external C program contains memory leak), memory consumption increase along the fault injection simulation campaign, so I split the script to run 500-1000 fault inject and then quit vsim and start again.