phanrahan / mantle Goto Github PK
View Code? Open in Web Editor NEWmantle library
License: Other
mantle library
License: Other
Outputs are not wired up in the emitted coreir .json
op1 + op2
op1 - op2
carry(op1 op op2, in=None, out=None)
trunc(op1 op op2)
- op1
op1 >>> op2
Arithmetic shiftop1 & op2
op1 ~& op2
op1 | op2
op1 ~| op2
op1 ^ op2
op1 ~^ op2
op1 >> op2
op1 << op2
~ op1
reduce(op, op1)
not op1
can be implemented as ~ reduce(or, op1)
op1 and op2
(Logical And)op1 or op2
(Logical or)op1 == op2
value[slice]
There are some cases where we have multiple implementations of a circuit in common and a target directory.
For example, FullAdder is in common and ice40.
Currently, the common implementation takes precedence over the target implementation. It is imported after the target implementation. However, we do cache circuit definitions. So, this may not work at all.
How should we handle this case?
If I try to import mantle without setting the MANTLE and MANTLE_TARGET environment variables, I get the following error:
test_up.py:1: in <module>
from aetherling.modules.up import UpSequential, UpParallel
../modules/up.py:3: in <module>
from mantle import Register, CounterModM, Mux, Decode
../../../mantle/mantle/__init__.py:25: in <module>
from mantle.common import *
../../../mantle/mantle/common/__init__.py:1: in <module>
from .arith import *
../../../mantle/mantle/common/arith.py:1: in <module>
from mantle import DefineAdd, DefineSub, DefineNegate, DefineASR
E ImportError: cannot import name 'DefineAdd'
This occurs because https://github.com/phanrahan/mantle/blob/master/mantle/__init__.py#L11 imports the verilog version of mantle with this environment setting. This version doesn't have DefineAdd implemented. This used to work for me, so I'm not sure what has changed, but either:
We should define a function to wrap a coreir module (I think @David-Durst already has something similar to this, so maybe we can leverage it) that uses anonymous bits to renamed the in
and out
ports to be consistent with the mantle I
and O
interface. This will remove the extra "wrapper" modules in the generated code.
Mantle tests should only depend on mantle and magma, not loam.
Update the mantle primitives to use the Declare
pattern that was started in https://github.com/phanrahan/mantle/blob/master/mantle/primitives/arith.py
This ensures that all primitives across different implementations conform to the same interface. It also reduces code duplication since the implementations don't need to regenerate a unique name or generate the interface.
Similar to chisel's when
construct, we can add a method chaining implementation.
reg = Register()
reg.when(io.RESET, init)
.when(io.LOAD, io.I)
.else(4)
If no else
case is provided, it could by default wire up the output of the register to the input (so the value doesn't change).
The ordering of the when
statements indicate a precedence, so if io.RESET
is true, the new value will be init
regardless of the value of io.LOAD
. This should match the semantics of a simple mux chain implementation.
When I try to compile the verilator example (./examples/verilator) to verilog it works, but when I adjust it to try to compile it to coreir I get a failure.
The example is:
from magma import *
from magma.verilator.verilator import compile as compileverilator
from mantle.verilog.gates import And, XOr
def f(a, b, c):
return (a & b) ^ c
main = DefineCircuit('main', "a", In(Bit), "b", In(Bit), "c", In(Bit), "d", Out(Bit))
t = And(2)(main.a,main.b)
d = XOr(2)(t,main.c)
wire(d,main.d)
EndCircuit()
compile("main", main)
compileverilator('sim_main.cpp', main, f)
print 'Compiling coreir'
compile("main", main, 'coreir')
and the failure is:
(magma_venv) bash-3.2$ python main.py
import verilog
('compiling', 'main')
Compiling coreir
ERROR: Could not find Instance in library!
Instance: and
Namespace: global
I AM DYING!
mantle/mantle/lattice/mantle40/arith.py
Line 135 in e99d6d3
Proposal: test(mantle.operator.and_, operator.and_, [Bit, Bits, UInt, SInt])
Where test(mantle_primitive_op, python_op, types)
will test mantle_primitive_op
in the Python simulator, Verilator, and coreir simulator using python_op
as a gold function. type
is a list of magma types to test the operations on.
When compiling to CoreIR, CounterModM crashes with the following error:
ERROR: Counter5Mod2: Cannot wire together
inst1.O : Bit
inst0.RESET : coreir.rstIn
My test is: https://github.com/David-Durst/aetherling/blob/master/tests/test_up.py#L83
Through debugging, I've tracked down that this crash occurs while in the compile_definition call for the Counter5Mod2 module (the line https://github.com/phanrahan/magma/blob/master/magma/backend/coreir_.py#L261).
For now I think we can start by making sure they work with mantle40 and coreir.
Proposed strategy:
examples/chisel-tutorial/*.py
notebooks/chisel-tutorial/*.py
https://github.com/leonardt/silica3/blob/master/generate_notebooks.py (seems like this could be wrapped up in a simple python cli tool that converts all scripts in one directory into notebooks in another and executes them)magma
cli tool, as part of an integration level test. This seems like a nice complement to our unit tests of the individual primitives. They're fairly lightweight circuits and if we don't run exhaustive tests they simulate in a reasonable amount of time. We could discuss strategies about whether we need to test these locally or perhaps only on Travis.Shifting by fixed amount can be done "at compile time" by wiring independent of backends
How can we get adders to bulk wire arrays rather than wire individual bits? Is this fundamental to the magma backend?
Solutions are either
-Keep the current behavior and fix it up in a coreir pass
-fix on the magma/mantle side
I would push for the latter since I feel like this goes against the philosophy of our toolchain in which we want to maintain as much high level structure as possible for as long as possible. It seems like the wrong solution to blow out structure at this level and to build it back up at the coreir level.
Thoughts?
When I am using the <<
shift operator or lsl
circuit
from magma import *
set_mantle_target("ice40")
from mantle import*
high_byte = bits(0xFF,8)
shifted = high_byte << bits(8,8)
Gives TypeError: FixedLSL() missing 1 required positional argument: 'shift'
. Not sure if wrong syntax or an actual error though.
This would allow us to define <=
as an assignment operator on input values.
Based on https://github.com/phanrahan/mantle/tree/master/mantle/verilog
coreir primitives: https://github.com/StanfordAHA/Primitives
Should be more robust than regression testing the generator verilog files
These primitives need DefineOp, Op and op versions
Pseudoprimitives (meta-programmed in python)
We should move Decode from common to the target directories. Decode is a variant of EQ where one of the terms is a constant. It requires a reduction, and the form of that reduction depends on the FPGA.
Report from today (5/24/17) using pytest --cov=mantle
---------- coverage: platform darwin, python 3.5.2-final-0 -----------
Name Stmts Miss Cover
---------------------------------------------------------------
mantle/__init__.py 17 6 65%
mantle/altera/__init__.py 5 5 0%
mantle/altera/cyclone4/ALM.py 38 38 0%
mantle/altera/cyclone4/__init__.py 2 2 0%
mantle/altera/mantle4/LUT.py 64 64 0%
mantle/altera/mantle4/__init__.py 4 4 0%
mantle/expressions.py 227 27 88%
mantle/lattice/__init__.py 4 0 100%
mantle/lattice/ice40/IOB.py 2 0 100%
mantle/lattice/ice40/PLB.py 51 2 96%
mantle/lattice/ice40/PLL.py 53 45 15%
mantle/lattice/ice40/RAMB.py 113 102 10%
mantle/lattice/ice40/__init__.py 6 0 100%
mantle/lattice/ice40/simulation.py 113 103 9%
mantle/lattice/mantle40/FF.py 122 83 32%
mantle/lattice/mantle40/IO.py 11 6 45%
mantle/lattice/mantle40/LUT.py 98 50 49%
mantle/lattice/mantle40/MUX.py 87 38 56%
mantle/lattice/mantle40/ROM.py 92 64 30%
mantle/lattice/mantle40/__init__.py 22 0 100%
mantle/lattice/mantle40/adder.py 53 8 85%
mantle/lattice/mantle40/arbiter.py 21 14 33%
mantle/lattice/mantle40/arith.py 40 5 88%
mantle/lattice/mantle40/cascade.py 29 0 100%
mantle/lattice/mantle40/compare.py 56 27 52%
mantle/lattice/mantle40/counter.py 147 97 34%
mantle/lattice/mantle40/decode.py 21 16 24%
mantle/lattice/mantle40/decoder.py 16 11 31%
mantle/lattice/mantle40/encoder.py 22 17 23%
mantle/lattice/mantle40/flatcascade.py 43 35 19%
mantle/lattice/mantle40/logic.py 334 170 49%
mantle/lattice/mantle40/register.py 27 1 96%
mantle/lattice/mantle40/ring.py 49 36 27%
mantle/lattice/mantle40/shift.py 70 54 23%
mantle/peripherals/__init__.py 0 0 100%
mantle/peripherals/display.py 45 45 0%
mantle/peripherals/timer.py 15 6 60%
mantle/silego/__init__.py 3 3 0%
mantle/silego/greenpak4/PLB.py 24 24 0%
mantle/silego/greenpak4/__init__.py 3 3 0%
mantle/util/__init__.py 0 0 100%
mantle/util/debounce.py 13 13 0%
mantle/util/edge.py 10 10 0%
mantle/util/fsm/__init__.py 2 2 0%
mantle/util/fsm/fsm.py 78 78 0%
mantle/util/lfsr/__init__.py 1 1 0%
mantle/util/lfsr/lfsr.py 29 29 0%
mantle/util/lhca/__init__.py 1 1 0%
mantle/util/lhca/lhca.py 37 37 0%
mantle/util/pop/__init__.py 1 1 0%
mantle/util/pop/count.py 48 48 0%
mantle/util/pwm.py 3 3 0%
mantle/util/quad.py 9 9 0%
mantle/verilog/FF.py 24 24 0%
mantle/verilog/__init__.py 3 3 0%
mantle/verilog/gatelogic.py 138 138 0%
mantle/verilog/gates.py 45 45 0%
mantle/verilog/logic.py 138 138 0%
mantle/xilinx/__init__.py 8 8 0%
mantle/xilinx/common/__init__.py 9 9 0%
mantle/xilinx/common/arbiter.py 20 20 0%
mantle/xilinx/common/arith.py 12 12 0%
mantle/xilinx/common/counter.py 79 79 0%
mantle/xilinx/common/decoder.py 16 16 0%
mantle/xilinx/common/encoder.py 22 22 0%
mantle/xilinx/common/register.py 25 25 0%
mantle/xilinx/common/ring.py 49 49 0%
mantle/xilinx/common/shift.py 69 69 0%
mantle/xilinx/cores/__init__.py 0 0 100%
mantle/xilinx/cores/pico3/__init__.py 2 2 0%
mantle/xilinx/cores/pico3/alu.py 50 50 0%
mantle/xilinx/cores/pico3/asm/__init__.py 1 1 0%
mantle/xilinx/cores/pico3/asm/arch.py 56 56 0%
mantle/xilinx/cores/pico3/asm/inst.py 147 147 0%
mantle/xilinx/cores/pico3/asm/mem.py 31 31 0%
mantle/xilinx/cores/pico3/asm/picoinst.py 9 9 0%
mantle/xilinx/cores/pico3/asm/tiny.py 62 62 0%
mantle/xilinx/cores/pico3/io.py 47 47 0%
mantle/xilinx/cores/pico3/pico.py 105 105 0%
mantle/xilinx/cores/pico3/seq.py 27 27 0%
mantle/xilinx/kintex7/IOPAD.py 2 2 0%
mantle/xilinx/kintex7/PS7Wrap.py 12 12 0%
mantle/xilinx/kintex7/__init__.py 3 3 0%
mantle/xilinx/kintex7/mmio.py 20 20 0%
mantle/xilinx/port/__init__.py 7 7 0%
mantle/xilinx/port3/FF.py 56 56 0%
mantle/xilinx/port3/LUT.py 85 85 0%
mantle/xilinx/port3/MUX.py 84 84 0%
mantle/xilinx/port3/RAM.py 6 6 0%
mantle/xilinx/port3/RAMB.py 5 5 0%
mantle/xilinx/port3/ROM.py 112 112 0%
mantle/xilinx/port3/__init__.py 14 14 0%
mantle/xilinx/port3/adder.py 54 54 0%
mantle/xilinx/port3/cascade.py 68 68 0%
mantle/xilinx/port3/compare.py 45 45 0%
mantle/xilinx/port3/decode.py 19 19 0%
mantle/xilinx/port3/flatcascade.py 37 37 0%
mantle/xilinx/port3/fulladder.py 46 46 0%
mantle/xilinx/port3/logic.py 291 291 0%
mantle/xilinx/port6/FF.py 56 56 0%
mantle/xilinx/port6/LUT.py 75 75 0%
mantle/xilinx/port6/MUX.py 78 78 0%
mantle/xilinx/port6/RAM.py 6 6 0%
mantle/xilinx/port6/RAMB.py 5 5 0%
mantle/xilinx/port6/ROM.py 110 110 0%
mantle/xilinx/port6/__init__.py 14 14 0%
mantle/xilinx/port6/adder.py 54 54 0%
mantle/xilinx/port6/cascade.py 60 60 0%
mantle/xilinx/port6/compare.py 57 57 0%
mantle/xilinx/port6/decode.py 18 18 0%
mantle/xilinx/port6/flatcascade.py 37 37 0%
mantle/xilinx/port6/fulladder.py 33 33 0%
mantle/xilinx/port6/logic.py 351 351 0%
mantle/xilinx/port6/ramemory.py 45 45 0%
mantle/xilinx/port6/romemory.py 24 24 0%
mantle/xilinx/spartan/__init__.py 11 11 0%
mantle/xilinx/spartan3/BUF.py 3 3 0%
mantle/xilinx/spartan3/CLB.py 51 51 0%
mantle/xilinx/spartan3/DCM.py 42 42 0%
mantle/xilinx/spartan3/DSP.py 16 16 0%
mantle/xilinx/spartan3/IOB.py 6 6 0%
mantle/xilinx/spartan3/RAM.py 38 38 0%
mantle/xilinx/spartan3/RAMB.py 199 199 0%
mantle/xilinx/spartan3/SRL.py 37 37 0%
mantle/xilinx/spartan3/__init__.py 9 9 0%
mantle/xilinx/spartan6/BUF.py 4 4 0%
mantle/xilinx/spartan6/CLB.py 57 57 0%
mantle/xilinx/spartan6/DCM.py 42 42 0%
mantle/xilinx/spartan6/IOB.py 10 10 0%
mantle/xilinx/spartan6/LUT.py 20 20 0%
mantle/xilinx/spartan6/RAM.py 215 215 0%
mantle/xilinx/spartan6/RAMB.py 219 219 0%
mantle/xilinx/spartan6/ROM.py 13 13 0%
mantle/xilinx/spartan6/SRL.py 33 33 0%
mantle/xilinx/spartan6/__init__.py 10 10 0%
mantle/xilinx/zynq/__init__.py 1 1 0%
mantle/xilinx/zynq/ps7.py 72 72 0%
---------------------------------------------------------------
TOTAL 6672 5734 14%
We will probably want to choose a subset of supported platforms for the initial release.
https://github.com/phanrahan/mantle/blob/master/mantle/lattice/mantle40/LUT.py#L110
https://github.com/phanrahan/mantle/blob/master/mantle/lattice/mantle40/MUX.py#L133
These only handle powers of 2 up to a low limit. They should support all positive integers.
Emit the equivalent Verilog code (in terms of ice40 primitives), compile through Verilator and check against the Python simulation functions
If an output is unwired in CoreIR, it complains. CoreIR has a Term operator that I've ported to Mantle (https://github.com/phanrahan/mantle/blob/master/mantle/coreir/type_helpers.py#L4). All Magma/Mantle backends should complain.
Testing dimensions:
loam
so we have access to the board abstraction)Simulator and hardware tests should integrate with fault
for test vector generation and test bench generation
I'm trying to write a basic test for mantle/common/RAM.py
from magma import *
from mantle import *
from loam.boards.icestick import IceStick
icestick = IceStick()
icestick.Clock.on()
for i in range(1):
icestick.J3[i].output().on()
main = icestick.main()
ram = RAM(16, 1)
waddr = Counter(16)
wdata = Counter(1)
we = 1
raddr = FF()(Counter(16))
ram(raddr, waddr, wdata, we, main.CLKIN)
wire(rdata, main.J3)
However, when I try to build it with magma (magma -b icestick -d build test
), it seems to hang, i.e. I get the output
import lattice ice40
import lattice mantle40
and nothing afterwards. Not sure if this is an issue with magma or mantle or just my implementation.
==
is not implemented because it breaks stuff in the magma internals that use ==
to check for object equality. Offending code should be updated to use is
instead so we can overload the ==
operator.
reg8 = Register(8).when(ce).reset(r)
David has a nice countermodm test here: https://github.com/David-Durst/aetherling/blob/master/tests/test_up.py#L39
We should add it to our test suite.
The logic functions need to be generalized to accept heights which are not a multiple of 4.
The documentation claims that an N-bit LUT has an N-bit 'bits' input I and a 'bit' output O. However, the input is actually separated out into individual bit inputs I0, I1, ... I{N}.
>>> import mantle
>>> mantle.LUT([0,1]*8, 4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 61, in LUT
return DefineLUT(init, N)()
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 28, in DefineLUT
class LUT(Circuit):
File "/home/david/Documents/aha/magmathon/magma/magma/circuit.py", line 421, in __new__
self.definition()
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 33, in definition
lutN = DeclareCoreirLUT(N, init)()
File "/home/david/Documents/aha/magmathon/magma/magma/circuit.py", line 532, in wrapped
result = func(*args, **kwargs)
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 19, in DeclareCoreirLUT
coreir_configargs = {"init": coreir.BitVector(1<<N, init)})
AttributeError: module 'coreir' has no attribute 'BitVector'
>>> lut = mantle.LUT([0,1]*8, 4)
>>> print(mantle.LUT.__doc__)
n-bit LUT
I : In(Bits(n)), O : Out(Bit)
>>> print(lut.IO)
"I0", In(Bit), "I1", In(Bit), "I2", In(Bit), "I3", In(Bit), "O", Out(Bit)
These are missing in the ice40 and coreir backend. Once implemented, the operators should be enabled.
(foobarenv) david@DavidXPS:~$ python3
Python 3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mantle
>>> mantle.LUT([0]*16, N=4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 61, in LUT
return DefineLUT(init, N)()
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 28, in DefineLUT
class LUT(Circuit):
File "/home/david/Documents/aha/magmathon/magma/magma/circuit.py", line 421, in __new__
self.definition()
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 33, in definition
lutN = DeclareCoreirLUT(N, init)()
File "/home/david/Documents/aha/magmathon/magma/magma/circuit.py", line 532, in wrapped
result = func(*args, **kwargs)
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 19, in DeclareCoreirLUT
coreir_configargs = {"init": coreir.BitVector(1<<N, init)})
AttributeError: module 'coreir' has no attribute 'BitVector'
>>> mantle.LUT([0]*16, N=4)
inst0 = LUT4_0()
>>> mantle.LUT([0]*65536, N=16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 61, in LUT
return DefineLUT(init, N)()
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 28, in DefineLUT
class LUT(Circuit):
File "/home/david/Documents/aha/magmathon/magma/magma/circuit.py", line 421, in __new__
self.definition()
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 33, in definition
lutN = DeclareCoreirLUT(N, init)()
File "/home/david/Documents/aha/magmathon/magma/magma/circuit.py", line 532, in wrapped
result = func(*args, **kwargs)
File "/home/david/Documents/aha/magmathon/mantle/mantle/coreir/LUT.py", line 19, in DeclareCoreirLUT
coreir_configargs = {"init": coreir.BitVector(1<<N, init)})
AttributeError: module 'coreir' has no attribute 'BitVector'
>>> mantle.LUT([0]*65536, N=16)
inst0 = LUT16_0()
Will need to generalize to arbitrary heights to support the operators in mantle.common.operator
Not sure why coreir and verilator examples are in this repo.
I am still confused on how to name instances.
how can I name addinst to be "addinst"
addinst = mantle.coreir.DefineCoreirAdd(16)
I am heading into the office now.
Thanks!
Right now common.RAM uses height as the number of bits for the address which is misleading. I think we should either use an address_width
parameter, or have height be the number of entries (so clog2(height) == address_width
).
We should add a ring register test to stress test the simulator. Ring registers have loops between all the DFFs.
The packages
option needs to have a full list of all packages, not just the top-level ones in the project, so it doesn't install properly right now.
Think you should do something like packages=find_packages(exclude=["tests"])
:
https://setuptools.readthedocs.io/en/latest/setuptools.html#using-find-packages
The following primitives still need to be implemented.
The following functions are not implemented in coreir.
Right now the docs say:
The aspect ratio (height x width) of the memory depends on the length of the array rom or ram.
However, the code says:
def RAMB(height, width, ram=None):
return _RAMB(height, width, ram, readonly=False)
def ROMB(height, width, rom=None):
return _RAMB(height, width, rom, readonly=True)
I think we should update the interfaces to support only the rom
/ram
parameter (so automatically derive height/width), or support only the height/width parameters (so automatically initialize to 0s).
They are two separate sets of tests for operators
These should be consolidated and used by both implementations.
I get the following compile error when I try to use DFFs, SRFFs, TFFs, and UpDownCounters:
bash-3.2$ ./testTFFbuild.sh
import mantle lattice ice40
import mantle lattice mantle40
compiling main
ERROR: Parameter inst0.has_set with non-constant value at build/testTFF.v:4!
fatal error: read_blif: failed to open `build/testTFF.blif': No such file or directory
Error: Failed to open input file.
iceprog: can't open 'build/testTFF.bin' for reading: No such file or directory
bash-3.2$
I have created a minimum repro of the bug at https://github.com/David-Durst/CS448H-answers/blob/TFFissue/lab2/testTFF.py. If you checkout that repo, you can run the script testTFFbuild.sh in the lab2 folder to repro the bug. Note that the repo is private since it contains my answers for the two labs and I want to allow you guys to reuse the projects in the future. You all have been invited to collaborate on it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.