Skip to content

Commit

Permalink
examples/sim: add shift register examples
Browse files Browse the repository at this point in the history
2 shift register examples are introduced. Both examples stores 8 bit of values at a time.

* `sr1.py`: Parallel-to-serial - uses 16-bit shift-right register. When the counter equals 0, new values of all the 8 bits are shifted into the 8 MSBs of the register; when the counter equals i, the i-th values previously shifted into the register is outputted as its LSB.

* `sr2.py`: Serial-to-serial - uses 8-bit shift-right register. When the counter equals i, the i-th value shifted into the register is outputted as its LSB, while the ((i-1) mod 8)-th value at the previous clock cycle gets shifted into the register as its MSB.
  • Loading branch information
HarryMakes committed Aug 27, 2020
1 parent 7bc4eb1 commit 516b536
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 0 deletions.
70 changes: 70 additions & 0 deletions examples/sim/sr1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from migen import *


class ShiftRegisterParallelToSerial(Module):
"""A parallel-to-serial shift-right register,
where the new value of all bits are shifted in only right before all current bits are shifted out.
"""
def __init__(self):
self.values = values = [
Signal(reset=i%2) for i in range(8)
]
self.o = Signal()

sr = Signal(len(values)*2)
counter = Signal(max=len(values))
self.sync += [
If(counter == 0,
sr.eq(Cat(
sr[1:-len(values)],
[values[i] for i in range(len(values))]
))
).Else(
sr[:-1].eq(sr[1:])
),
If(counter == len(values) - 1,
counter.eq(0)
).Else(
counter.eq(counter + 1)
)
]
self.comb += self.o.eq(sr[0])


def counter_test(dut):
# Assert reset condition:
# - If i is even, values[i] should be 0
# - If i is odd, values[i] should be 1
for i in range(8):
assert (yield dut.values[i]) == i % 2
# Assume t is a counter with a reset of 0
for t in range(32):
# Flip the bits when t=5
# (Note: since no bits are shifted in before t=8,
# i.e. where values[0] of the currently-latched values
# will be shifted out at t=9, the flipped values will
# not be reflected until t=16)
if t == 5:
for i in range(8):
if i % 2:
yield dut.values[i].eq(0)
else:
yield dut.values[i].eq(1)
# Print the output for each cycle
print("t={} : {}".format(t, (yield dut.o)))
# When 0<=t<=7, since the reset values have not been fully shifted in yet,
# the output should stay 0
if t in range(8):
assert (yield dut.o) == 0
# When 8<=t<=15, output (all bits) should correspond to reset condition
if t in range(8, 16):
assert (yield dut.o) == t % 2
# When t>=16, output should correspond to the flipped condition
if t >= 16:
assert (yield dut.o) == (t+1) % 2
yield


if __name__ == "__main__":
dut = ShiftRegisterParallelToSerial()
run_simulation(dut, counter_test(dut), vcd_name="sr1.vcd")
66 changes: 66 additions & 0 deletions examples/sim/sr2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from migen import *


class ShiftRegisterSerialToSerial(Module):
"""A serial-to-serial shift-right register,
where the new value of each next bit is shifted in every cycle.
"""
def __init__(self):
self.values = values = [
Signal(reset=i%2) for i in range(8)
]
self.o = Signal()

sr = Signal(len(values))
counter = Signal(max=len(values))
self.sync += [
If(counter == i,
sr[-1].eq(values[i])
) for i in range(len(values))
]
self.sync += [
If(counter == len(values) - 1,
counter.eq(0)
).Else(
counter.eq(counter + 1)
),
sr[:-1].eq(sr[1:])
]
self.comb += self.o.eq(sr[0])


def counter_test(dut):
# Assert reset condition:
# - If i is even, values[i] should be 0
# - If i is odd, values[i] should be 1
for i in range(8):
assert (yield dut.values[i]) == i % 2
# Assume t is a counter with a reset of 0
for t in range(32):
# Flip the bits when t=5
# (i.e. 2 cycles before values[7] is shifted out,
# and new values[6] is shifted in)
if t == 5:
for i in range(8):
if i % 2:
yield dut.values[i].eq(0)
else:
yield dut.values[i].eq(1)
# Print the output for each cycle
print("t={} : {}".format(t, (yield dut.o)))
# When 0<=t<=7, since the reset values have not been fully shifted in yet,
# the output should stay 0
if t in range(8):
assert (yield dut.o) == 0
# When 8<=t<=13, output (bits 0 to 5) should correspond to reset condition
if t in range(8, 14):
assert (yield dut.o) == t % 2
# When t>=14, output should correspond to the flipped condition (starting on bit 6)
if t >= 14:
assert (yield dut.o) == (t+1) % 2
yield


if __name__ == "__main__":
dut = ShiftRegisterSerialToSerial()
run_simulation(dut, counter_test(dut), vcd_name="sr2.vcd")

0 comments on commit 516b536

Please sign in to comment.