DFFs and Registers

This example demonstrates the use of DFFs and registers.


In [1]:
import magma as m

DFF

The fundamental stateful element is a D-flip-flop. The flip-flop has a clock enable, its state will only be updated if the clock enable is true. Similarly, if a flip-flop has a reset signal, it will be reset to its initial value if reset is true.


In [2]:
from mantle import DFF

dff = DFF()

Register

A register is simply an array of flip-flops. To create an instance of a register, call Register with the number of bits n in the register.


In [3]:
from mantle import DefineRegister

Registers and DFFs are very similar to each other. The only difference is that the input and output to a DFF are Bit values, whereas the inputs and the outputs to registers are Bits[n].

Registers with Enables and Resets

Flip-flops and registers can have with clock enables and resets. The flip-flop has a clock enable, its state will only be updated if the clock enable is true. Similarly, if a flip-flop has a reset signal, it will be reset to its initial value if reset is true.

To create registers with these additional inputs, set the optional arguments has_ce and/or has_reset when instancing the register.


In [4]:
Register4 = DefineRegister(4, init=5, has_ce=True, has_reset=True )

To wire the optional clock inputs, clock enable and reset, use named arguments (ce and reset) when you call the register with its inputs. In Magma, clock signals are handled differently than signals.


In [5]:
from magma.simulator import PythonSimulator
from fault import PythonTester

tester = PythonTester(Register4, Register4.CLK)
tester.poke(Register4.RESET, 1)  # reset
tester.step(2)
tester.poke(Register4.RESET, 0)
print(f"Reset Val = {tester.peek(Register4.O)}")
tester.poke(Register4.CE, 1)  # set enable
for i in range(5):
    tester.poke(Register4.I, i)
    tester.step(2)
    print(f"Register4.I = {tester.peek(Register4.I)}, Register4.O = {tester.peek(Register4.O)}")
print("Lowering enable")
tester.poke(Register4.CE, 0)
for i in range(5):
    tester.poke(Register4.I, i)
    tester.step(2)
    print(f"Register4.I = {tester.peek(Register4.I)}, Register4.O = {tester.peek(Register4.O)}")


Reset Val = 5
Register4.I = 0, Register4.O = 0
Register4.I = 1, Register4.O = 1
Register4.I = 2, Register4.O = 2
Register4.I = 3, Register4.O = 3
Register4.I = 4, Register4.O = 4
Lowering enable
Register4.I = 0, Register4.O = 4
Register4.I = 1, Register4.O = 4
Register4.I = 2, Register4.O = 4
Register4.I = 3, Register4.O = 4
Register4.I = 4, Register4.O = 4

In [ ]: