User Tools

Site Tools


migen:migen_fragment_list

Migen Fragment List

Here we are going to describe the set of Fragment that migen supports. Writing a FHDL code for an FPGA is done by adding to the “sync” and “comb” table of a module, a set of those fragment.

eq (equal)

Direct value assignment.

frag = a.eq(0x42)

Indirect assignment of another signal

frag = a.eq(b)

If

frag = If(a == 3, foo.eq(bar))
frag = If(a == 3, foo.eq(bar), a.eq(3), b.eq(4), c.eq(d))
frag = If(a > b, c.eq(3))

Else

The else statement goes with a If

frag = If(a == 3, foo.eq(bar)).Else(foo.eq(3))
frag = If(a > b, c.eq(3)).Else(d.eq(4))

Elif

The Elif statement goes with a If

frag = If(a == 3, foo.eq(bar)).Elif(a > 3, (foo.eq(4))
frag = If(a > b, c.eq(3)).Elif(a < b, d.eq(4)).Else(d.eq(5))

Often for clarity reason, here is how the code could be indented:

        frag = If(a > b,
            c.eq(3)
	).Elif(a < b,
	    d.eq(4),
            e.eq(4),
            f.eq(z)
	).Else(
	    d.eq(5),
            x.eq(y)
	)

Example

MyIfElifElse.py
from migen import *
 
class MyFHDL(Module):
    def __init__(self):
        self.foo = foo = Signal(8)
        self.bar = bar = Signal(8)
 
        self.comb += [
            If(foo < 5,
                bar.eq(1)
            ).Elif(foo == 5,
                bar.eq(2)
            ).Elif(foo == 6,
                bar.eq(3)
            ).Else(
                bar.eq(4)
            )
        ]
 
def testbench(dut):
    for i in range(10):
        yield dut.foo.eq(i)
        yield
        print("foo:{} bar:{}".format(i, (yield dut.bar)))
 
dut = MyFHDL()
run_simulation(dut, testbench(dut))

Here is an example that takes a value “foo” and apply the If statement in a combinatory way. As one can see, the results are as expected.

Case

Case takes a dictionary and apply a cases to it.

foo = Signal(8)
sel = Signal(3)
cases = {foo.eq(2), foo.eq(3), foo.eq(5), foo.eq(7), foo.eq(11), foo.eq(13), foo.eq(17), foo.eq(19)}
 
frag = Case(sel, cases)

Although this way of writing the code is really ugly, let's write the same code with the help of python, that is where migen is really handy:

 primes = [2, 3, 5, 7, 11, 13, 17, 19]
 cases = {}
 for i in range(8):
    cases[i] = foo.eq(primes[i])
 
 frag = Case(sel, cases)

As one can see, we use the for loop to construct the cases dictionary with fragments coming from the primes table. Then do our Case. That is handy when those dictionary are built for example using complex mathematical tools coming from python.

MyCase.py
from migen import *
 
 
class MyFHDL(Module):
    def __init__(self):
        self.foo = foo = Signal(8)
        prime = [2, 3, 5, 7, 11, 13, 17, 19]
        counter = Signal(3)
 
        cases = {}
        for i in range(8):
            cases[i] = foo.eq(prime[i])
 
        self.sync += counter.eq(counter + 1)        
        self.comb += Case(counter, cases)
 
def testbench(dut):
    for i in range(32):
        print((yield dut.foo))
        yield
 
dut = MyFHDL()
run_simulation(dut, testbench(dut))

In this example, we have a counter on 3 bits that counts from 0 to 7 then loop. The value of this counter is our selection for the Case. As it increments at each clock tick, it will continuously select one of the Fragment that has been constructed in our “cases” dictionary.

migen/migen_fragment_list.txt · Last modified: 2018/01/10 18:40 by po