Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions models/cache/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class Cache(st.Component):

"""

def __init__(self, parent, name, nb_sets_bits, nb_ways_bits, line_size_bits, refill_latency=0, refill_shift=0, nb_ports=1, add_offset=0, enabled=False, cache_v2=False):
def __init__(self, parent, name, nb_sets_bits, nb_ways_bits, line_size_bits, refill_latency=0, refill_shift=0, nb_ports=1, add_offset=0, enabled=False, cache_v2=False, fic_enabled=False):

super(Cache, self).__init__(parent, name)

Expand All @@ -45,7 +45,8 @@ def __init__(self, parent, name, nb_sets_bits, nb_ways_bits, line_size_bits, ref
'refill_latency': refill_latency,
'add_offset': add_offset,
'refill_shift': refill_shift,
'enabled': enabled
'enabled': enabled,
'fic_enabled': fic_enabled,
})

def i_INPUT(self) -> st.SlaveItf:
Expand Down
31 changes: 31 additions & 0 deletions models/cache/cache_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
* Authors: Germain Haugou, GreenWaves Technologies (germain.haugou@greenwaves-technologies.com)
*/

#ifdef CONFIG_FAULT_INJECTION
#include <vp/fault_injector.hpp>
#endif
#include <vp/vp.hpp>
#include <vp/queue.hpp>
#include <vp/itf/io.hpp>
Expand Down Expand Up @@ -130,6 +133,10 @@ class Cache : public vp::Component
void enable(bool enable);
void flush();
void flush_line(unsigned int addr);

#ifdef CONFIG_FAULT_INJECTION
bool registered_with_fic;
#endif
};

void Cache::reset(bool active)
Expand All @@ -139,6 +146,30 @@ void Cache::reset(bool active)
this->flush();
this->enabled = this->enabled_at_reset;
this->refill_event.release();

#ifdef CONFIG_FAULT_INJECTION
if (!this->registered_with_fic)
{
bool fic_enabled = this->get_js_config()->get_child_bool("fic_enabled");
if (fic_enabled)
{
// FIC does not know this struct. So pass it the relative offsets needed
cache_line_t line = this->lines[0];

uint64_t base = (uint64_t) &line;
uint64_t tag_off = ((uint64_t) &(line.tag)) - base;
uint64_t dirty_off = ((uint64_t) &(line.dirty)) - base;
uint64_t data_off = ((uint64_t) &(line.data)) - base;

uint64_t nb_lines = this->nb_ways * this->nb_sets;

vp::FIC_registrator *fic = (vp::FIC_registrator *) this->get_service("FIC");
fic->register_cache(this, (uint8_t *) lines, nb_lines, this->line_size_bits,
this->nb_sets_bits, sizeof(cache_line_t), tag_off, dirty_off, data_off);
this->registered_with_fic = true;
}
}
#endif
}
}

Expand Down
3 changes: 3 additions & 0 deletions models/cpu/iss_v2/include/prefetch/prefetch_single_line.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,7 @@ class PrefetchSingleLine

iss_reg_t current_pc;

#ifdef CONFIG_PREFETCHER_FI
bool registered_with_fic=false;
#endif
};
6 changes: 6 additions & 0 deletions models/cpu/iss_v2/include/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,10 @@ class Vector
uint8_t mant;

uint8_t vregs[ISS_NB_VREGS][CONFIG_ISS_VLEN/8];

#ifdef CONFIG_REGFILE_FI
private:
Iss &iss;
bool registered_with_fic=false;
#endif
};
13 changes: 13 additions & 0 deletions models/cpu/iss_v2/riscv.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,10 @@ class RiscvCommon(st.Component):
A dictionnay describing all the power models used to estimate power consumption in the ISS (default: {})
power_models_file : file, optional
A path to a file describing all the power models used to estimate power consumption in the ISS (default: None)
regfile_fi: bool, optional
True if the register files of this core are fault-injected
prefetcher_fi: bool, optional
True if the prefetcher buffer of this core is fault-injected
cluster_id : int, optional
The cluster ID of the core simulated by the ISS (default: 0).
"""
Expand Down Expand Up @@ -347,6 +351,8 @@ def __init__(self,
zfinx: bool=False,
zdinx: bool=False,
fp_width: int | None = None,
regfile_fi: bool=False,
prefetcher_fi: bool=False,
modules: dict[str, IssModule] | None = None
):

Expand Down Expand Up @@ -456,6 +462,12 @@ def __init__(self,
if zdinx or isa.has_extension('zdinx'):
self.add_c_flags(['-DCONFIG_GVSOC_ISS_ZDINX=1'])

if regfile_fi:
self.add_c_flags(['-DCONFIG_REGFILE_FI=1'])

if prefetcher_fi:
self.add_c_flags(['-DCONFIG_PREFETCHER_FI=1'])

fp_size = fp_width if fp_width is not None else 64 if isa.has_isa('rvd') else 32
self.add_c_flags([f'-DCONFIG_GVSOC_ISS_FP_WIDTH={fp_size}'])

Expand Down Expand Up @@ -531,6 +543,7 @@ def __init__(self,
'fetch_enable': config.fetch_enable,
'boot_addr': config.boot_addr,
'has_double': isa.has_isa('rvd'),
'regfile_fi': regfile_fi,
})

self.htif = config.htif
Expand Down
15 changes: 15 additions & 0 deletions models/cpu/iss_v2/src/prefetch/prefetch_single_line.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
* Authors: Germain Haugou, GreenWaves Technologies (germain.haugou@greenwaves-technologies.com)
*/

#ifdef CONFIG_PREFETCHER_FI
#include <vp/fault_injector.hpp>
#endif
#include <vp/vp.hpp>

PrefetchSingleLine::PrefetchSingleLine(Iss &iss)
Expand All @@ -37,6 +40,18 @@ void PrefetchSingleLine::reset(bool active)
{
this->flush();
this->prefetch_insn = NULL;
#ifdef CONFIG_PREFETCHER_FI
if (!this->registered_with_fic)
{
bool fic_enabled = this->iss.top.get_js_config()->get_child_bool("prefetcher_fi");
if (fic_enabled)
{
vp::FIC_registrator *fic = (vp::FIC_registrator *) this->iss.top.get_service("FIC");
fic->register_prefetcher(&this->iss.top, this->data, ISS_PREFETCHER_SIZE);
}
this->registered_with_fic = true;
}
#endif
}
}

Expand Down
24 changes: 24 additions & 0 deletions models/cpu/iss_v2/src/vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,21 @@
* Authors: Germain Haugou (germain.haugou@gmail.com)
*/

#ifdef CONFIG_REGFILE_FI
#include <vp/fault_injector.hpp>
#include "cpu/iss_v2/include/iss.hpp"
#endif

#ifdef CONFIG_REGFILE_FI
Vector::Vector(Iss &iss)
: iss(iss)
{
}
#else
Vector::Vector(Iss &iss)
{
}
#endif

void Vector::reset(bool active)
{
Expand All @@ -33,4 +44,17 @@ void Vector::reset(bool active)
}
}
}
#ifdef CONFIG_REGFILE_FI
if (!this->registered_with_fic)
{
bool fic_enabled = this->iss.get_js_config()->get_child_bool("regfile_fi");
if (fic_enabled)
{
vp::FIC_registrator *fic = (vp::FIC_registrator *) this->iss.get_service("FIC");
fic->register_regfile(&this->iss, VP_FI_VREG, (void *) this->vregs,
ISS_NB_VREGS, CONFIG_ISS_VLEN);
}
this->registered_with_fic = true;
}
#endif
}
51 changes: 51 additions & 0 deletions models/fault_injection/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Overview

The main functionality of FIC consists in storing, parsing, and distributing the fault requests in a meaningful way. Additionally, it may perform other related functionality such as computing hashes for integrity checks.

The model takes `faults_path` parameter which specifies file containing faults.

To integrate a memory device into fault injection campaign, pass `fic_enabled=True` to probed device. The probed device must then register with FIC at `reset`. See `../memory/memory.{py,cpp}` for an example.

## Functionality

- Store and inject faults

- Hashing for integrity checks.

- Dump relevant data for fault campaign: indices, paths, sizes, etc. of the connected target devices.

## Internals

FIC registers itself as a service in GVSOC core. Enabled devices register themselves with FIC using `vp::FIC_registrator::register_{device type}`. This way, enabled devices expose all relevant information needed for injecting faults.

For now, there is no option of manual ID assignment for target memory devices. It is assumed that all relevant information is to be extracted from the golden run.

The faults are read from file into a sorted `faults_queue`. Upon leaving the reset state for the first time, FIC checks whether the queue is non-empty. If so, it sets its event timer `event` to the timestamp of the first injection. Upon waking up and handling the fault injection, it again sets the timer to the timestamp of next fault injection.

Most logic is bookkeeping and the fault application in `FIC::inject_fault()`.

## What about commands?

The commands must be passed through a file specified by `faults_path`.

**Note**: Only memories and VRF registers have been calibrated against RTL. Other targets are tentative.

| Numerical command | Description |
|---------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 0 0 0 -1 `addr` `bit` 0 0 `cycle` `nb_bits` 0 | Flip sequence of `nb_bits` bits starting from `bit` in byte at `addr` in global addres space in `cycle` cycle |
| 0 0 0 `mem_id` `addr` `bit` 0 0 `cycle` `nb_bits` 0 | Flip sequence of `nb_bits` bits starting from `bit` in byte at `addr` within `mem_id`-th memory deivce in `cycle` cycle |
| 0 0 1 `regfile_id` `reg` `bit` 0 0 `cycle` `nb_bits` 0 | Flip sequence of `nb_bits` bits starting from `bit` within `reg`-th register in `regfile_id`-th register file in `cycle` cycle |
| 0 0 2 `pref_id` `byte` `bit` 0 0 `cycle` `nb_bits` 0 | Flip sequence of `nb_bits` bits starting from `bit` within `byte`-th byte in `pref_id`-th prefetcher's buffer in `cycle` cycle |
| 0 0 3 `cache_id` `pos` `bit` 0 0 `cycle` `nb_bits` 0 | Flip sequence of `nb_bits` bits starting from `bit` within `pos % line_size`-th data byte in `pos / line_size`-th entry of `cache_id`-th cache in `cycle` cycle |
| 0 0 4 `cache_id` `line_nr` `bit` 0 0 `cycle` `nb_bits` 0 | Flip sequence of `nb_bits` bits starting from `bit` within `line_nr`-th entry tag of `cache_id`-th cache in `cycle` cycle |
| 0 0 5 `cache_id` `line_nr` 0 0 0 `cycle` 0 0 | Flip the dirty bit of `line_nr`-th entry of `cache_id`-th cache in `cycle` cycle |
| 0 1 0 `mem_id` `addr` `bit` `duration` `is_high` `cycle` 0 0 | Intermittent stuck-at: tie `bit`-th bit of byte at `addr` in `mem_id`-th memory device to `is_high` for `duration` cycles starting in cycle `cycle` |
| 0 1 0 `mem_id` `addr` `bit` 0 `is_high` 0 0 0 | Permanent stuck-at: tie `bit`-th bit of byte at `addr` in `mem_id`-th memory device to `is_high` |
| 1 0 0 -1 `addr` 0 0 0 0 `length` `id` | In the end of the simulation, output hash of memory region starting at `addr` of `length` bytes in global address space. <br> The output is directed into `hashes_<sanitized FIC path>` file. <br> The line format as `id <hash>` |
| 1 0 0 `mem_id` `addr` 0 0 0 0 `length` `id` | Idem but for `mem_id`-th memory device |
| 1 0 0 `mem_id` 0 0 0 0 0 0 `id` | Idem but the complete memory for `mem_id`-th memory device |
| 2 0 0 0 0 0 0 0 0 0 0 | In the end of the simulation, output info on all memory devices connected to this FIC. <br> The output is directed into `memories_data_<sanitized FIC path>` file. <br> The line format is `mem_id <memory device path> <size>` |
| 3 0 0 0 0 0 0 0 0 0 0 | In the end of the simulation, output the cycle count in the clock domain of FIC. <br> The output is directed into `cycle_count_<sanitized FIC path>` file. <br> The line format is `<cycle count>` |
| 4 0 0 0 0 0 0 0 0 0 0 | In the end of the simulation, output info on all register devices connected to this FIC. <br> The output is directed into `regfiles_data_<sanitized FIC path>` file. <br> The line format is `<regfile id> <parent core device path> <type> <register bitwidth> <number of registers>`. <br> The `<type>` can be `0` (REG), `1` (FREG), or `2` (VREG). |
| 6 0 0 0 0 0 0 0 0 0 0 | In the end of the simulation, output info on all prefetcher devices connected to this FIC. <br>The output is directed into `prefetchers_data_<sanitized FIC path>` file. <br>The line format is `<pref id> <parent core device path> <size>`. |
| 7 0 0 0 0 0 0 0 0 0 0 | In the end of the simulation, output info on all cache devices connected to this FIC. <br>The output is directed into `caches_data_<sanitized FIC path>` file. <br>The line format is `<cache id> <cache device path> <number of lines> <line size> <tag bitwidth>`. |
Loading