When coding with Migen, we manipulate “Signal”. A Signal is what a reg or wire is in verilog. Migen will decide itself how to deal with it. Let's for example have a led, which is a 1 bit signal:
led = Signal()
Keep in mind that a led is seen as an output signal, from the FPGA point of view.
Let's declare a 4 bit counter
counter = Signal(4)
Let's declare a push button:
button = Signal()
Of course, those declaration don't do much so far.
Let's for example do a design that whenever the button is pressed, the led is on. The logic would be something like this:
led.eq(button)
This assignment is done with the keyword “eq” which means “equal”. and this whole statement is what we will call a “fragment”.
We can see a more complex fragment that would do the same thing with a If and Else statement:
If(button == 1, led.eq(1)).Else( led.eq(0))
This whole statement is still a Fragment. And here is again a more complex fragment.
If(button == 1, led.eq(1)).Elif(button == 0, led.eq(0))
A fragment on its own doesn't do much. But it is a python object which could be manipulated.
leds = [Signal() for _ in range(8)] buttons = [Signal() for _ in range(8)] table = [] for i in range(8): table.append( leds[i].eq(button[i]) )
This whole code still does nothing so far. But it is interesting to see how we manipulate those “Signals” and “Fragment” with python objects such as with for loops, dictionary and tables. And that is where Migen is powerful compared to Verilog.