Skip to content

Commit 516b536

Browse files
committed
examples/sim: add shift register examples
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.
1 parent 7bc4eb1 commit 516b536

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

examples/sim/sr1.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
from migen import *
2+
3+
4+
class ShiftRegisterParallelToSerial(Module):
5+
"""A parallel-to-serial shift-right register,
6+
where the new value of all bits are shifted in only right before all current bits are shifted out.
7+
"""
8+
def __init__(self):
9+
self.values = values = [
10+
Signal(reset=i%2) for i in range(8)
11+
]
12+
self.o = Signal()
13+
14+
sr = Signal(len(values)*2)
15+
counter = Signal(max=len(values))
16+
self.sync += [
17+
If(counter == 0,
18+
sr.eq(Cat(
19+
sr[1:-len(values)],
20+
[values[i] for i in range(len(values))]
21+
))
22+
).Else(
23+
sr[:-1].eq(sr[1:])
24+
),
25+
If(counter == len(values) - 1,
26+
counter.eq(0)
27+
).Else(
28+
counter.eq(counter + 1)
29+
)
30+
]
31+
self.comb += self.o.eq(sr[0])
32+
33+
34+
def counter_test(dut):
35+
# Assert reset condition:
36+
# - If i is even, values[i] should be 0
37+
# - If i is odd, values[i] should be 1
38+
for i in range(8):
39+
assert (yield dut.values[i]) == i % 2
40+
# Assume t is a counter with a reset of 0
41+
for t in range(32):
42+
# Flip the bits when t=5
43+
# (Note: since no bits are shifted in before t=8,
44+
# i.e. where values[0] of the currently-latched values
45+
# will be shifted out at t=9, the flipped values will
46+
# not be reflected until t=16)
47+
if t == 5:
48+
for i in range(8):
49+
if i % 2:
50+
yield dut.values[i].eq(0)
51+
else:
52+
yield dut.values[i].eq(1)
53+
# Print the output for each cycle
54+
print("t={} : {}".format(t, (yield dut.o)))
55+
# When 0<=t<=7, since the reset values have not been fully shifted in yet,
56+
# the output should stay 0
57+
if t in range(8):
58+
assert (yield dut.o) == 0
59+
# When 8<=t<=15, output (all bits) should correspond to reset condition
60+
if t in range(8, 16):
61+
assert (yield dut.o) == t % 2
62+
# When t>=16, output should correspond to the flipped condition
63+
if t >= 16:
64+
assert (yield dut.o) == (t+1) % 2
65+
yield
66+
67+
68+
if __name__ == "__main__":
69+
dut = ShiftRegisterParallelToSerial()
70+
run_simulation(dut, counter_test(dut), vcd_name="sr1.vcd")

examples/sim/sr2.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
from migen import *
2+
3+
4+
class ShiftRegisterSerialToSerial(Module):
5+
"""A serial-to-serial shift-right register,
6+
where the new value of each next bit is shifted in every cycle.
7+
"""
8+
def __init__(self):
9+
self.values = values = [
10+
Signal(reset=i%2) for i in range(8)
11+
]
12+
self.o = Signal()
13+
14+
sr = Signal(len(values))
15+
counter = Signal(max=len(values))
16+
self.sync += [
17+
If(counter == i,
18+
sr[-1].eq(values[i])
19+
) for i in range(len(values))
20+
]
21+
self.sync += [
22+
If(counter == len(values) - 1,
23+
counter.eq(0)
24+
).Else(
25+
counter.eq(counter + 1)
26+
),
27+
sr[:-1].eq(sr[1:])
28+
]
29+
self.comb += self.o.eq(sr[0])
30+
31+
32+
def counter_test(dut):
33+
# Assert reset condition:
34+
# - If i is even, values[i] should be 0
35+
# - If i is odd, values[i] should be 1
36+
for i in range(8):
37+
assert (yield dut.values[i]) == i % 2
38+
# Assume t is a counter with a reset of 0
39+
for t in range(32):
40+
# Flip the bits when t=5
41+
# (i.e. 2 cycles before values[7] is shifted out,
42+
# and new values[6] is shifted in)
43+
if t == 5:
44+
for i in range(8):
45+
if i % 2:
46+
yield dut.values[i].eq(0)
47+
else:
48+
yield dut.values[i].eq(1)
49+
# Print the output for each cycle
50+
print("t={} : {}".format(t, (yield dut.o)))
51+
# When 0<=t<=7, since the reset values have not been fully shifted in yet,
52+
# the output should stay 0
53+
if t in range(8):
54+
assert (yield dut.o) == 0
55+
# When 8<=t<=13, output (bits 0 to 5) should correspond to reset condition
56+
if t in range(8, 14):
57+
assert (yield dut.o) == t % 2
58+
# When t>=14, output should correspond to the flipped condition (starting on bit 6)
59+
if t >= 14:
60+
assert (yield dut.o) == (t+1) % 2
61+
yield
62+
63+
64+
if __name__ == "__main__":
65+
dut = ShiftRegisterSerialToSerial()
66+
run_simulation(dut, counter_test(dut), vcd_name="sr2.vcd")

0 commit comments

Comments
 (0)