phanrahan / magma Goto Github PK
View Code? Open in Web Editor NEWmagma circuits
License: Other
magma circuits
License: Other
Make it obvious that this is generating a register with a clock enable, not that we are wiring up a clock enable.
This should be done to all primitives with clock signals (including counters, shift registers, etc.)
These features are very powerful but a bit hard to understand, would be great to have:
The magma programming model has an existing section discussing this, but I think it needs to be expanded. There may also be some useful examples in the 488H lecture slides.
Can pass the values/state directly to the function to make them simpler
$ magma lut4.py
From Python docs:
object.format(self, format_spec)
Called by the format() built-in function (and by extension, the format() method of class str) to produce a “formatted” string representation of an object. The format_spec argument is a string that contains a description of the formatting options desired. The interpretation of the format_spec argument is up to the type implementing format(), however most classes will either delegate formatting to one of the built-in types, or use a similar formatting option syntax.
See Format Specification Mini-Language for a description of the standard formatting syntax.
This should be useful for simulation, but the specification might need to be blocked until we begin integrating the magma simulation code and have a better understanding of how we might use this.
I suggest all type conversions be done in a way similar to standard python type conversions. For example int(x) converts the string s to an int. There are other options like int(s, base).
In particular, we would implement bits(), uint(), and sint().
Here are some variants for bits. Similar versions would exist for uint and sint.
bits(i,n) - convert the python integer i to a magma Bits(n)
bits(b0, b1, ..., bn) - convert n Bit values to a Bits(n) value
bits(uint) - converts a UInt(n) to a Bits(n)
bits(sint) - converts a Sint(n) to Bits(n)
This issue is related to #37
They introduce anonymous Bit
s which are troublesome for debuggability.
Project Repo: https://github.com/bjmnbraun/icestick_fastio
Final Paper: fastio_final_paper.docx
Example printf app: https://github.com/bjmnbraun/icestick_fastio/blob/master/test/src/printf_app.py
Should we memoize DeclareCircuit and DefineCircuit?
If so, I think we can remove the cache in the Circuit metaclass.
Base diff from class project: https://github.com/phanrahan/magma/compare/simulator
Test code: https://github.com/shacklettbp/magmasimulator
array(val)
and type.as_array()
bits(val)
and type.as_bits()
uint(val)
and type.as_uint()
sint(val)
and type.as_sint()
We should have two Bit types.
One type, say Bit, should only be wireable.
The other type, say Bool, should implement logical operations such as And, Or, Xor, Not.
We should be able to convert between the two.
Clock would be a subtype of Bit. You can only wire clock signals. To perform logical operations on Clock would require it to be converted to a Bool.
In terms of naming, the above suggestions is not ideal. We currently allow logical operations on Bits(n), which by analogy means we should allow logical operations on Bit. Not sure what to name the type which is just wireable.
It should also be possible to simulate pure combinational circuits.
These primitives need DefineOp, Op and op versions
Pseudoprimitives (meta-programmed in python)
Past projects I've worked on have used 90% coverage as a target which seems pretty reasonable.
Report from today (5/24/17) obtained via pytest --cov=magma
Name Stmts Miss Cover
-------------------------------------------------------------
magma/__init__.py 22 1 95%
magma/array.py 193 48 75%
magma/backend/__init__.py 0 0 100%
magma/backend/blif.py 104 86 17%
magma/backend/verilog.py 134 38 72%
magma/bit.py 101 20 80%
magma/bits.py 49 37 24%
magma/bitwise.py 37 30 19%
magma/board.py 8 4 50%
magma/circuit.py 285 81 72%
magma/compatibility.py 7 2 71%
magma/compile.py 54 29 46%
magma/compile_abstract.py 78 78 0%
magma/config.py 6 0 100%
magma/debug.py 14 1 93%
magma/error.py 23 4 83%
magma/fpga.py 43 34 21%
magma/higher.py 216 50 77%
magma/interface.py 206 43 79%
magma/ir.py 13 0 100%
magma/part.py 10 6 40%
magma/peripheral.py 9 5 44%
magma/port.py 105 25 76%
magma/python_simulator.py 160 127 21%
magma/ref.py 60 8 87%
magma/scope.py 26 17 35%
magma/simulator.py 19 8 58%
magma/simulator_interactive_frontend.py 252 222 12%
magma/t.py 58 6 90%
magma/tests.py 11 0 100%
magma/transforms.py 147 128 13%
magma/tuple.py 174 42 76%
magma/wire.py 96 49 49%
-------------------------------------------------------------
TOTAL 2720 1229 55%
Also, add some tests for it
mux(cond, *args)
with len(cond) == log2(len(args))
a[s]
Proposal: test(magma.operator.and_, operator.and_, [Bit, Bits, UInt, SInt])
Where test(magma_primitive_op, python_op, types)
will test magma_primitive_op
in the Python simulator and Verilator using python_op
as a gold function. type
is a list of magma types to test the operations on.
I think it would make more sense to have the ice40 simulator primitives be part of mantle/lattice/ice40.
We can also test the mantle40 code using the yosys implementations of the ice40 primitives. This would allow is to test the mantle40 implementations using verilator.
The find
function is used by the backends to find circuit definitions to be compiled. This could be factored out into an analysis module.
Can use intbv
from myhdl as a starting point
Can we remove the classmethod definition
requirement?
In chisel you can write:
class Mux2 extends Module {
val io = IO(new Bundle{
val sel = Input(UInt(1.W))
val in0 = Input(UInt(1.W))
val in1 = Input(UInt(1.W))
val out = Output(UInt(1.W))
})
io.out := (io.sel & io.in1) | (~io.sel & io.in0)
}
hypothetical python version
class Mux2(Circuit):
io = IO({
"sel" : In(Bit),
"in0" : In(Bit),
"in1" : In(Bit),
"out" : Out(Bit)
})
io.out = (io.sel & io.in1) | (~io.sel & io.in0)
ir.py
to the __repr__
methods of ports and circuits.compile(main, output="dot")
We should define single Bit types for FFs and change the wireclock logic in compile to test for the type rather than use string names (which is fragile since different vendors use different names for these signals).
Unique names for circuit definitions are needed for implementing caching.
Two possibilites:
Begin with two abstract inputs:
I0 = In(Array(2, Bit))
I1 = In(Array(2, Bit))
Pattern 1: DefineName(args)
defines a circuit, which can be instanced and wired up normally
Add2 = DefineAdd(width=2)
add2 = Add2(**instance_args)
add2_O = add2(I0, I1)
Pattern 2: Name(args)
defines or retrieves a cached definition of the circuit and instances it
add2 = Add(2, **instance_args)
add2_O = add2(I0, I1)
Pattern 3: name(args)
infers the widths of the inputs, defines or retrieves a cached definition of the circuit, instances it, wires up inputs, and returns output
add2_O = add(I0, I1, **instance_args)
from magma import *
from loam.boards.icestick import IceStick
from magma.python_simulator import PythonSimulator
from magma.scope import *
icestick = IceStick()
icestick.Clock.on()
for i in range(4): icestick.PMOD0[i].input().on()
main = icestick.main()
EndCircuit()
sim = PythonSimulator(main)
scope = Scope()
sim.set_value(main.PMOD0[0], scope, True)
error on last line:
import lattice ice40
import lattice mantle40
Traceback (most recent call last):
File "/Users/osnr/dev/magmacore/magma/transforms.py", line 35, in get_new_bit
return self.orig_to_new[QualifiedBit(bit=orig_bit, scope=scope)]
KeyError: QualifiedBit(bit=main.PMOD0[0], scope=<magma.scope.Scope object at 0x102b44d68>)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "tests/test_simulator.py", line 18, in <module>
sim.set_value(main.PMOD0[0], scope, True)
File "/Users/osnr/dev/magmacore/magma/python_simulator.py", line 223, in set_value
newbit = self.txfm.get_new_bit(bit, scope)
File "/Users/osnr/dev/magmacore/magma/transforms.py", line 37, in get_new_bit
raise MagmaTransformException("Could not find bit in transform mapping. bit={}, scope={}".format(orig_bit, scope))
magma.transforms.MagmaTransformException: Could not find bit in transform mapping. bit=main.PMOD0[0], scope=<magma.scope.Scope object at 0x102b44d68>
but works if you icestick.D1.on()
and wire(main.D1, main.PMOD0[0])
, so I guess it's the fact that PMOD0[0]
wasn't wired in the example?
I'd find setting unwired inputs useful if I'm commenting out parts of the circuit or doing automatic circuit generation. I guess I could just ignore that exception, since the input doesn't matter anyway.
From https://github.com/ucb-bar/chisel-tutorial/tree/release/src/main/scala/examples
One example using mako: https://github.com/ucb-sejits/ctree/tree/master/ctree/tools/generators
Print out In(Bits(n)) yields "Bits(n)". Should probably be "In(Bits(n))". Same for Out(Bits(n)).
Similarly, In(UInt(n)) and In(SInt(n)) should print the direction.
See Chisel types
Proposed type hierarchy
Bit (Bool = Bit)
Bits(n) = Array(n,Bit)
UInt(n) \subclass Bits(n)
SInt(n) \subclass Bits(n)
Like constarray
. Could be useful for building arithmetic against fixed constants. Related to #35.
Example: watch counter.O == 20 and reg.CE == 1
Support dumping to a .vcd
file for viewing through a standard tool
Generate trace of python simulator
Look into wavedrom and jupyter wavedrom
Example:
from magma import *
from mantle.lattice.mantle40 import Counter
hello = DefineCircuit('hello', 'O', Out(Bit), 'CLK', In(Bit))
counter = Counter(8)
wire(hello.O, counter.O < constarray(3, 8)) # binop with 1-bit output
from magma.python_simulator import PythonSimulator
from magma.scope import Scope
sim = PythonSimulator(hello)
scope = Scope()
sim.evaluate()
print(sim.get_value(hello.O, scope))
yields AssertionError in ValueStore.set_value
because "Can only set boolean values".
I think the problem is that the binop simulate
implementation in primitives.py always calls as_bool_list()
to generate newval
, even if newval
needs to be just one bool instead of a list of bools.
Would it be better to do this in set_value
:
elif isinstance(newval, list) and len(newval) == 1:
newval = newval[0]
or to dispatch on the out_type
in simulate
?
Reference (from Ross): https://www.doulos.com/knowhow/sysverilog/tutorial/assertions/
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.