A0 Algorithm¶
Implementation of the A0 compaction algorithm . The only difference with respect to the original A0 algorithm is that in order to validate a removal of an instruction from the STL, the evaluation happens on whether the new test application time is less or equal than the old test application time AND whether the new test coverage is greater or equal than the old test application time. However, with the provided utilities provided with the toolkit this can be extended or modified to the user’s needs. All it takes is a few LoC in the evaluation method of each iteration within the A0 class.
A0¶
- class a0.A0(*args, **kwargs)[source]¶
Bases:
object
Implements the A0 compaction algorithm
- static evaluate(previous_result: tuple[int, float], new_result: tuple[int, float]) bool [source]¶
Evaluates the new results with respect to the previous ones.
Specifically, if new tat <= old tat and if new coverage >= old coverage.
- Parameters:
previous_result (tuple[int, float]) – the old tat value (int) and coverage (float) values.
new_result (tuple[int, float]) – the new tat value (int) and coverage values.
- Returns:
True
if new tat <= old tat and new coverage >= old coverage.False
otherwise- Return type:
bool
- pre_run() tuple[int, float] [source]¶
Extracts the initial test application time and coverage of the STL.
The test application time is extracted by a logic simulation of the STL whereas the coverage is computed by performing a fault simulation.
- Returns:
The test application time (index 0) and the coverage of the STL (index 1)
- Return type:
tuple[int, float]
- Raises:
SystemExit – If HDL sources cannot be compiled (if specified) or if logic simulation cannot be performed.
TimeoutError – if logic or fault simulation timed out.
- run(initial_stl_stats: tuple[int, float], times_to_shuffle: int = 100) None [source]¶
Main loop of the A0 algorithm
Removal of a random instruction
- Cross-compilation
2.1 If FAIL, Restore
- Logic simulation
3.1 If ERROR or TIMEOUT, Restore
- Fault simulation
4.1 If ERROR or TIMEOUT, Restore
Evaluation
Goto 1.
- Parameters:
initial_stl_stats (tuple[int, float]) – The test application time (int) and coverage (float) of the original STL
times_to_shuffle (int, optional) – Number of times to permutate the assembly candidates. Defaults to 100.
- Returns:
None
Preprocessing¶
It is possible to perform preprocessing in the set of assembly candidates to reduce the runtime of the A0 algorithm. The runtime of the algorithm solely depends on the total number of candidates to be considered in each iteration. It is a brute-force approach to the compaction problem. So the idea is the following. What if, after we execute the pre_run() of the A0 algorithm to obtain the initial STL statistics, we are able to assess somehow the impact each Candidate has in terms of faults being detected?
In order to obtain such information a couple of things are required. First, we need a fault report comming from Z01X with includes custom fault attributes. Secondly, we need a trace comming directly from the DUT after the execution of the original STL. The idea is to guide algorithm by leveraging useful state information stemming from the fault detection time of each fault. Assuming that the DUT is a pipelined processor, then this information must include (i) the simulation time and (ii) the program counter value. Then, by examining the contents of the trace, it is possible to map these program counter values and timestamps to instructions in the trace, and identify “hot-zones” of the STL. That is, codeline regions that contribute to the detection of the faults.
Fault Attributes¶
After a Z01X fault simulation, it is possible to enable with report
command the inclusion of the fault attributes by specifying the flag -showallattributes
.
VC Z01X provides the ability to define custom fault attributes using key, value pairs. The fault coverage is reported in the coverage report for each key, value pair.
To add such attributes to each fault one has to modify the strobe.sv
file accordingly. Here is an example of attaching the simulation time and the program counter
to a fault by modifying the strobe file.
cmp = $fs_compare(`TOPLEVEL); // Check for differences between GM and FM
if (1 == cmp) begin
$fs_drop_status("ON", `TOPLEVEL);
$fs_add_attribute(1, "PC", "%h", {`TOPLEVEL.pc_id[31:1], 1'b0}); // Attach program counter
$fs_add_attribute(1, "sim_time", "%t", $time); // Attach simulation time
end else if (2 == cmp) begin
$fs_drop_status("PN", `TOPLEVEL);
$fs_add_attribute(1, "PC", "%h", {`TOPLEVEL.pc_id[31:1], 1'b0}); // Attach program counter
$fs_add_attribute(1, "sim_time", "%t", $time); // Attach simulation time
end
By utilizing the $fs_add_attribute()
directive we can easily add the required attributes to
each detected fault. When the final fault report is generated with the -showallatributes
flag,
then the attributes are attached to every prime fault like this:
< 1> ON 1 {PORT "path.to.fault.site"}(* "testName"->PC="00000004"; "testName"->sim_time=" 10ns"; *)
Execution Trace¶
The execution trace is required in order to search for the hotzones with information stemming from the attributes reported in the fault reports.
By attaching adequate information on each fault, and of course, relevant and acurate(!) to the one present in the trace we can search within
the STL execution trace for instances. For instance, we can search for <PC, Time>
attribute pairs stemming from the fault report to pinpoint
spatially and temporally the sequence of codelines that were executed and led to the fault detectiong. The PC values and times reported in the
attributes of the faults must comming from the exact same signals employed by the trace. Otherwise we may have off-by-one errors in our search
in the trace when trying to associate simulation times and program counter values for example. The trace, during processing, is written into a database,
which can be queried for retrieving rows with information comming from the fault attributes
Preprocessor¶
- class a0.Preprocessor(*args, **kwargs)[source]¶
Bases:
object
Filters out candidate instructions
- query_trace_db(select: str, where: dict[str, str], history: int = 5, allow_multiple: bool = False) list[tuple[str, ...]] [source]¶
Perform a query with the specified parameters.
Assuming that the DB looks like this:
Time || Cycle || PC || Instruction -----||-------||----------||------------ 10ns || 1 || 00000004 || and 20ns || 2 || 00000008 || or <-* 30ns || 3 || 0000000c || xor <-| 40ns || 4 || 00000010 || sll <-| 50ns || 5 || 00000014 || j <-| 60ns || 6 || 0000004c || addi <-* 70ns || 7 || 00000050 || wfi
And you perform a query for the
select="PC"
andwhere={"PC": "0000004c", "Time": "60ns"}
then the search would result in a window of 1+4PC
values, indicated by<-
in the snapshot above. The size of the window defaults to 5 but can be freely selected by the user.- Parameters:
select (str) – The field to select in the query.
where (dict[str, str]) – A dictionary specifying conditions to filter the query.
history (int, optional) – The number of past queries to include. Defaults to 5.
allow_multiple (bool, optional) – Whether to allow multiple results. Defaults to False.
- Returns:
A list of query results (tuples of strings) matching the criteria.
- Return type:
list[tuple[str, …]