From 475dee98673dc35bb8d95f35c0414f3dd0e8638d Mon Sep 17 00:00:00 2001 From: Lenny Truong Date: Wed, 30 Oct 2024 10:41:49 -0700 Subject: [PATCH] Add fault micro code --- fault-micro/.gitignore | 1 + fault-micro/config_alu.py | 37 ++++++++++++++++++++++++++++++++ fault-micro/opt_alu.py | 32 ++++++++++++++++++++++++++++ fault-micro/pe.py | 45 +++++++++++++++++++++++++++++++++++++++ fault-micro/simple_alu.py | 31 +++++++++++++++++++++++++++ 5 files changed, 146 insertions(+) create mode 100644 fault-micro/.gitignore create mode 100644 fault-micro/config_alu.py create mode 100644 fault-micro/opt_alu.py create mode 100644 fault-micro/pe.py create mode 100644 fault-micro/simple_alu.py diff --git a/fault-micro/.gitignore b/fault-micro/.gitignore new file mode 100644 index 00000000..378eac25 --- /dev/null +++ b/fault-micro/.gitignore @@ -0,0 +1 @@ +build diff --git a/fault-micro/config_alu.py b/fault-micro/config_alu.py new file mode 100644 index 00000000..ba63b7a8 --- /dev/null +++ b/fault-micro/config_alu.py @@ -0,0 +1,37 @@ +import magma as m +import fault as f +import hwtypes as ht + +import operator + + +class ConfigALU(m.Circuit): + io = m.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.ClockIO() + + opcode = m.Register(m.Bits[2], has_enable=True)()( + io.config_data, CE=io.config_en + ) + io.c @= m.mux( + [io.a + io.b, io.a - io.b, io.a * io.b, io.b ^ io.a], + opcode + ) + +ops = [operator.add, operator.sub, operator.mul, operator.xor] +tester = f.SynchronousTester(ConfigALU) +tester.circuit.config_en = 1 +for i, op in enumerate(ops): + tester.circuit.config_data = i + tester.circuit.a = a = ht.BitVector.random(16) + tester.circuit.b = b = ht.BitVector.random(16) + tester.step(2) + tester.circuit.c.expect(op(a, b)) + +tester.compile_and_run("verilator", flags=["-Wno-fatal"], + directory="build") + diff --git a/fault-micro/opt_alu.py b/fault-micro/opt_alu.py new file mode 100644 index 00000000..8cfa549e --- /dev/null +++ b/fault-micro/opt_alu.py @@ -0,0 +1,32 @@ +import operator + +import magma as m +import fault as f +import hwtypes as ht + +class OptALU(m.Circuit): + io = m.IO( + a=m.In(m.UInt[16]), + b=m.In(m.UInt[16]), + c=m.Out(m.UInt[16]), + opcode=m.In(m.Bits[2]) + ) + sum_ = io.a + m.mux([io.b, -io.b], io.opcode[0]) + + io.c @= m.mux( + [sum_, sum_, io.a * io.b, io.b ^ io.a], + io.opcode + ) + +ops = [operator.add, operator.sub, operator.mul, operator.xor] +tester = f.Tester(OptALU) +for i, op in enumerate(ops): + tester.circuit.opcode = i + tester.circuit.a = a = ht.BitVector.random(16) + tester.circuit.b = b = ht.BitVector.random(16) + tester.eval() + tester.circuit.c.expect(op(a, b)) + +tester.compile_and_run("verilator", flags=["-Wno-fatal"], + directory="build") + diff --git a/fault-micro/pe.py b/fault-micro/pe.py new file mode 100644 index 00000000..adaddf9c --- /dev/null +++ b/fault-micro/pe.py @@ -0,0 +1,45 @@ +import magma as m +import fault as f +import hwtypes as ht + +import operator + + +class PE(m.Generator2): + def __init__(self, instr_op_map: dict): + n_cfg_bits = max(x.bit_length() for x in instr_op_map.keys()) + self.io = m.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[n_cfg_bits]), config_en=m.In(m.Enable) + ) + m.ClockIO() + + opcode = m.Register(m.Bits[n_cfg_bits], has_enable=True)()( + self.io.config_data, CE=self.io.config_en + ) + curr = None + for instr, op in instr_op_map.items(): + next = op(self.io.a, self.io.b) + if curr is not None: + next = m.mux([curr, next], opcode == instr) + curr = next + self.io.c @= curr + + +ops = m.common.ParamDict({ + 0xDE: operator.add, + 0xAD: operator.sub, + 0xBE: operator.mul, + 0xEF: operator.xor +}) +tester = f.SynchronousTester(PE(ops)) +tester.circuit.config_en = 1 +for inst, op in ops.items(): + tester.circuit.config_data = inst + tester.circuit.a = a = ht.BitVector.random(16) + tester.circuit.b = b = ht.BitVector.random(16) + tester.step(2) + tester.circuit.c.expect(op(a, b)) + +tester.compile_and_run("verilator", flags=["-Wno-fatal"], + directory="build") + diff --git a/fault-micro/simple_alu.py b/fault-micro/simple_alu.py new file mode 100644 index 00000000..6f06cbc6 --- /dev/null +++ b/fault-micro/simple_alu.py @@ -0,0 +1,31 @@ +import operator + +import magma as m +import fault as f +import hwtypes as ht + +class SimpleALU(m.Circuit): + io = m.IO( + a=m.In(m.UInt[16]), + b=m.In(m.UInt[16]), + c=m.Out(m.UInt[16]), + opcode=m.In(m.Bits[2]) + ) + + io.c @= m.mux( + [io.a + io.b, io.a - io.b, io.a * io.b, io.b ^ io.a], + io.opcode + ) + +ops = [operator.add, operator.sub, operator.mul, operator.xor] +tester = f.Tester(SimpleALU) +for i, op in enumerate(ops): + tester.circuit.opcode = i + tester.circuit.a = a = ht.BitVector.random(16) + tester.circuit.b = b = ht.BitVector.random(16) + tester.eval() + tester.circuit.c.expect(op(a, b)) + +tester.compile_and_run("verilator", flags=["-Wno-fatal"], + directory="build") +