Skip to main content

A Python package for testing hardware (part of the magma ecosystem)

Project description

# Fault
[![Build Status](https://travis-ci.com/leonardt/fault.svg?branch=master)](https://travis-ci.com/leonardt/fault)
[![Coverage Status](https://coveralls.io/repos/github/leonardt/fault/badge.svg?branch=master)](https://coveralls.io/github/leonardt/fault?branch=master)

A Python package for testing hardware (part of the magma ecosystem).

[API Documentation](http://truong.io/fault/)

[CHANGELOG](./CHANGELOG.md)

## Documentation
* [Actions](https://github.com/leonardt/fault/blob/master/doc/actions.md)
* [Tester](https://github.com/leonardt/fault/blob/master/doc/tester.md)

## Example
Here is a simple ALU defined in magma.
```python
import magma as m
import mantle


class ConfigReg(m.Circuit):
IO = ["D", m.In(m.Bits(2)), "Q", m.Out(m.Bits(2))] + \
m.ClockInterface(has_ce=True)

@classmethod
def definition(io):
reg = mantle.Register(2, has_ce=True, name="conf_reg")
io.Q <= reg(io.D, CE=io.CE)


class SimpleALU(m.Circuit):
IO = ["a", m.In(m.UInt(16)),
"b", m.In(m.UInt(16)),
"c", m.Out(m.UInt(16)),
"config_data", m.In(m.Bits(2)),
"config_en", m.In(m.Enable),
] + m.ClockInterface()

@classmethod
def definition(io):
opcode = ConfigReg(name="config_reg")(io.config_data, CE=io.config_en)
io.c <= mantle.mux(
[io.a + io.b, io.a - io.b, io.a * io.b, io.a / io.b], opcode)
```

Here's an example test in fault that uses the configuration interface, expects
a value on the internal register, and checks the result of performing the
expected operation.

```python
import operator
import fault

ops = [operator.add, operator.sub, operator.mul, operator.floordiv]
tester = fault.Tester(SimpleALU, SimpleALU.CLK)
tester.circuit.CLK = 0
tester.circuit.config_en = 1
for i in range(0, 4):
tester.circuit.config_data = i
tester.step(2)
tester.circuit.a = 3
tester.circuit.b = 2
tester.eval()
tester.circuit.c.expect(ops[i](3, 2))
```

We can run this with three different simulators

```python
tester.compile_and_run("verilator", flags=["-Wno-fatal"], directory="build")
tester.compile_and_run("system-verilog", simulator="ncsim", directory="build")
tester.compile_and_run("system-verilog", simulator="vcs", directory="build")
```

### Working with internal signals
Fault supports peeking, expecting, and printing internal signals. For the
`verilator` target, you should use the keyword argument `magma_opts` with
`"verilator_debug"` set to true. This will cause coreir to compile the verilog
with the required debug comments. Example:
```python
tester.compile_and_run("verilator", flags=["-Wno-fatal"],
magma_opts={"verilator_debug": True}, directory="build")
```

If you're using `mantle.Register` from the `coreir` implementation, you can
also poke the internal register value directly using the `value` field. Notice
that `conf_reg` is defined in `ConfigReg` to be an instance of
`mantle.Register` and the test bench pokes it by setting `confg_reg.value`
equal to `1`.

```python
tester = fault.Tester(SimpleALU, SimpleALU.CLK)
tester.circuit.CLK = 0
# Initialize
tester.step(2)
for i in reversed(range(4)):
tester.circuit.config_reg.conf_reg.value = i
tester.step(2)
tester.circuit.config_reg.conf_reg.O.expect(i)
```

## FAQ

### How do I generate waveforms with fault?

Fault supports generating `.vcd` dumps when using the `verilator` and
`system-verilog/ncsim` target.

For the `verilator` target, use the `flags` keyword argument to pass the
`--trace` flag. For example,

tester.compile_and_run("verilator", flags=["-Wno-fatal", "--trace"])

The `--trace` flag must be passed through to verilator so it generates code
that supports waveform dumping. The test harness generated by fault will
include the required logic for invoking `tracer->dump(main_time)` for every
call to `eval` and `step`. `main_time` is incremented for every call to step.
The output `.vcd` file will be saved in the file `logs/{circuit_name}` where
`circuit_name` is the name of the ciruit passed to `Tester`. The `logs`
directory will be placed in the same directory as the generated harness, which
is controlled by the `directory` keyword argument (by default this is
`"build/"`).

For the `system-verilog/ncsim` target, tracing is enabled by default. For
`ncsim`, the trace will be placed in a file called `verilog.vcd` in the same
directory as the generated harness.

Project details


Release history Release notifications | RSS feed

This version

2.0.2

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fault-2.0.2.tar.gz (25.2 kB view details)

Uploaded Source

Built Distribution

fault-2.0.2-py3-none-any.whl (34.2 kB view details)

Uploaded Python 3

File details

Details for the file fault-2.0.2.tar.gz.

File metadata

  • Download URL: fault-2.0.2.tar.gz
  • Upload date:
  • Size: 25.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Python-urllib/3.7

File hashes

Hashes for fault-2.0.2.tar.gz
Algorithm Hash digest
SHA256 fbbb9d5f88219c50cfdd5951fad6f27068f31b829f284d15ecd1f54950de47e4
MD5 2bde21223880a723d6fcefc00691a3dc
BLAKE2b-256 90a3bfd4bf00680a3266a6dcad016720da9010b4b279931f9130988e6fbcb23b

See more details on using hashes here.

File details

Details for the file fault-2.0.2-py3-none-any.whl.

File metadata

  • Download URL: fault-2.0.2-py3-none-any.whl
  • Upload date:
  • Size: 34.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Python-urllib/3.7

File hashes

Hashes for fault-2.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 f88e66c2202c5705e9b06a2c609fa619f9cbc3e7d045a07f4a0a95140058bfb9
MD5 af5523e82fec142e1be82af6770295e2
BLAKE2b-256 cf8c277a13cd8156d0635ed1632b492f68c597f0e3d3103793b1330864141861

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page