-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/master' into nd-set-index
- Loading branch information
Showing
13 changed files
with
272 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,7 @@ | ||
import pytest | ||
from magma.config import config as magma_config | ||
from magma.util import reset_global_context | ||
|
||
|
||
def pytest_configure(config): | ||
magma_config.compile_dir = 'callee_file_dir' | ||
# TODO(leonardt): Enable this globally for testing | ||
# Revert a3a2452168f2251277a14548d053a9ca7a45bff7 for golds. | ||
# | ||
# magma_config.use_namer_dict = True | ||
magma_config.use_uinspect = True | ||
|
||
|
||
@pytest.fixture(autouse=True) | ||
def magma_test(): | ||
reset_global_context() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import magma as m | ||
from .full_adder import FullAdder | ||
|
||
|
||
class Adder(m.Generator): | ||
""" | ||
n-bit adder with a carry-in and carry-out | ||
""" | ||
def __init__(self, n: int): | ||
self.io = io = m.IO( | ||
A=m.In(m.UInt[n]), | ||
B=m.In(m.UInt[n]), | ||
CIN=m.In(m.Bit), | ||
SUM=m.Out(m.UInt[n]), | ||
COUT=m.Out(m.Bit) | ||
) | ||
curr_cin = io.CIN | ||
for i in range(n): | ||
next_sum, curr_cin = FullAdder()(io.A[i], io.B[i], curr_cin) | ||
io.SUM[i] @= next_sum | ||
io.COUT @= curr_cin | ||
|
||
|
||
class Adder2(m.Generator): | ||
""" | ||
As higher-order circuit | ||
""" | ||
def __init__(self, n: int): | ||
self.io = io = m.IO( | ||
A=m.In(m.UInt[n]), | ||
B=m.In(m.UInt[n]), | ||
CIN=m.In(m.Bit), | ||
SUM=m.Out(m.UInt[n]), | ||
COUT=m.Out(m.Bit) | ||
) | ||
cout, _sum = m.braid( | ||
(FullAdder() for _ in range(n)), | ||
joinargs=["A", "B", "C"], | ||
foldargs={"cin": "cout"} | ||
)(io.A, io.B, io.CIN) | ||
io.SUM @= _sum | ||
io.COUT @= cout |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import magma as m | ||
|
||
|
||
class FullAdder(m.Circuit): | ||
# Interface ports are declared using the m.IO object | ||
# A port has a name (appears before the =) and a type (appears after | ||
# the =) | ||
# The type must have a direction (In, Out, or InOut) | ||
io = m.IO( | ||
a=m.In(m.Bit), | ||
b=m.In(m.Bit), | ||
|
||
cin=m.In(m.Bit), | ||
sum_=m.Out(m.Bit), | ||
cout=m.Out(m.Bit) | ||
) | ||
# We can assign references to output wires to temporary python | ||
# variables (in this case, a_xor_b refers to the output of the XOr | ||
|
||
# circuit instanced by using the `^` (xor) operator) | ||
|
||
a_xor_b = io.a ^ io.b | ||
# To wire the output of an instance (e.g. the output of the instance | ||
# created by a_xor_b ^ cin) to an output port (sum_), we use the `@=` | ||
# operator | ||
io.sum_ @= a_xor_b ^ io.cin | ||
|
||
# Here's another example of assignment (for python variables) and | ||
# wiring (for magma ports). We assign three temporaries for the | ||
# outputs of various & (and) operators. Then we wire the result of | ||
# "or"ing (|) these together to the `cout` output port | ||
a_and_b = io.a & io.b | ||
b_and_cin = io.b & io.cin | ||
a_and_cin = io.a & io.cin | ||
io.cout @= a_and_b | b_and_cin | a_and_cin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import magma as m | ||
|
||
|
||
class RegisterFile(m.Generator): | ||
def __init__(self, n: int, T: m.Type, has_read_enable: bool = False): | ||
addr_len = m.bitutils.clog2(n) | ||
self.io = m.IO( | ||
raddr=m.In(m.Bits[addr_len]), | ||
rdata=m.Out(T), | ||
wen=m.In(m.Enable), | ||
waddr=m.In(m.Bits[addr_len]), | ||
wdata=m.In(T) | ||
) + m.ClockIO() | ||
if has_read_enable: | ||
self.io += m.IO(ren=m.In(m.Enable)) | ||
|
||
|
||
class RegisterFileWhen(RegisterFile): | ||
def __init__(self, n: int, T: m.Type, has_read_enable: bool = False): | ||
super().__init__(n, T, has_read_enable) | ||
|
||
regs = [m.Register(T)() for _ in range(n)] | ||
|
||
rdata = T() | ||
rdata @= 0 | ||
for i, reg in enumerate(regs): | ||
with m.when((self.io.waddr == i) & self.io.wen): | ||
reg.I @= self.io.wdata | ||
|
||
with m.when(self.io.raddr == i): | ||
rdata @= reg.O | ||
|
||
if has_read_enable: | ||
rdata = m.Register(T, has_enable=True)()(rdata, self.io.ren) | ||
|
||
self.io.rdata @= rdata | ||
|
||
|
||
class RegisterFileComprehension(RegisterFile): | ||
def __init__(self, n: int, T: m.Type, has_read_enable: bool = False): | ||
super().__init__(n, T, has_read_enable) | ||
|
||
regs = [ | ||
m.Register(T, has_enable=True)()( | ||
self.io.wdata, (self.io.waddr == i) & self.io.wen | ||
) | ||
for i in range(n) | ||
] | ||
|
||
rdata = T() | ||
rdata @= 0 | ||
for i, reg in enumerate(regs): | ||
with m.when(self.io.raddr == i): | ||
rdata @= reg | ||
|
||
if has_read_enable: | ||
rdata = m.Register(T, has_enable=True)()(rdata, self.io.ren) | ||
|
||
self.io.rdata @= rdata | ||
|
||
|
||
class RegisterFileBraid(RegisterFile): | ||
def __init__(self, n: int, T: m.Type, has_read_enable: bool = False): | ||
super().__init__(n, T, has_read_enable) | ||
|
||
enables = m.array( | ||
[(self.io.waddr == i) & self.io.wen for i in range(n)] | ||
) | ||
regs = m.braid( | ||
[m.Register(T, has_enable=True)() for _ in range(n)], | ||
forkargs=['I'] | ||
)(self.io.wdata, enables) | ||
|
||
rdata = T() | ||
rdata @= 0 | ||
for i, reg in enumerate(regs): | ||
with m.when(self.io.raddr == i): | ||
rdata @= reg | ||
|
||
if has_read_enable: | ||
rdata = m.Register(T, has_enable=True)()(rdata, self.io.ren) | ||
|
||
self.io.rdata @= rdata |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import random | ||
import pytest | ||
|
||
import fault as f | ||
from hwtypes import BitVector | ||
|
||
|
||
from ..adder import Adder, Adder2 | ||
|
||
|
||
@pytest.mark.parametrize("N", [random.randint(1, 16) for _ in range(4)]) | ||
@pytest.mark.parametrize("_Adder", [Adder, Adder2]) | ||
def test_adder(N, _Adder): | ||
tester = f.Tester(_Adder(N)) | ||
tester.circuit.A = A = BitVector.random(N) | ||
tester.circuit.B = B = BitVector.random(N) | ||
tester.circuit.CIN = CIN = BitVector.random(1) | ||
|
||
tester.eval() | ||
tester.circuit.SUM.expect(A + B + CIN.zext(N - 1)) | ||
tester.circuit.COUT.expect( | ||
(A.zext(1) + B.zext(1) + CIN.zext(N))[-1] | ||
) | ||
tester.compile_and_run("verilator", magma_output="mlir-verilog") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
from ..full_adder import FullAdder | ||
import fault as f | ||
from hwtypes import BitVector | ||
|
||
|
||
def test_full_adder(): | ||
tester = f.Tester(FullAdder) | ||
for _ in range(4): | ||
tester.circuit.a = a = BitVector.random(1) | ||
tester.circuit.b = b = BitVector.random(1) | ||
|
||
tester.circuit.cin = cin = BitVector.random(1) | ||
tester.eval() | ||
tester.circuit.sum_.expect(a ^ b ^ cin) | ||
tester.circuit.cout.expect((a & b) | (b & cin) | (a & cin)) | ||
|
||
tester.compile_and_run("verilator", magma_output="mlir-verilog") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import tempfile | ||
import pytest | ||
import random | ||
|
||
from ..register_file import ( | ||
RegisterFileWhen, RegisterFileComprehension, RegisterFileBraid | ||
) | ||
|
||
import fault as f | ||
from hwtypes import BitVector | ||
import magma as m | ||
|
||
|
||
@pytest.mark.parametrize('has_read_enable', [True, False]) | ||
@pytest.mark.parametrize('RegisterFile', [RegisterFileWhen, | ||
RegisterFileComprehension, | ||
RegisterFileBraid]) | ||
def test_register_file(RegisterFile, has_read_enable): | ||
tester = f.SynchronousTester(RegisterFile(4, m.Bits[4], has_read_enable)) | ||
data = [BitVector.random(4) for _ in range(4)] | ||
for i in random.sample(range(4), 4): | ||
tester.circuit.waddr = i | ||
tester.circuit.wdata = data[i] | ||
tester.circuit.wen = 1 | ||
tester.advance_cycle() | ||
tester.circuit.wen = 0 | ||
for i in random.sample(range(4), 4): | ||
tester.circuit.raddr = i | ||
if has_read_enable: | ||
tester.circuit.ren = 1 | ||
tester.advance_cycle() | ||
tester.circuit.rdata.expect(data[i]) | ||
if has_read_enable: | ||
last = data[i] | ||
for i in range(3): | ||
tester.circuit.raddr = BitVector.random(2) | ||
tester.circuit.ren = 0 | ||
tester.advance_cycle() | ||
tester.circuit.rdata.expect(last) | ||
with tempfile.TemporaryDirectory() as tmp_dir: | ||
tester.compile_and_run( | ||
"verilator", | ||
directory=tmp_dir, | ||
magma_output="mlir-verilog" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from magma.config import config as magma_config | ||
|
||
|
||
def pytest_configure(config): | ||
magma_config.compile_dir = 'callee_file_dir' | ||
# TODO(leonardt): Enable this globally for testing | ||
# Revert a3a2452168f2251277a14548d053a9ca7a45bff7 for golds. | ||
# | ||
# magma_config.use_namer_dict = True | ||
magma_config.use_uinspect = True |