1 # Copyright (C) 2012 Vermeer Manufacturing Co.
2 # License: GPLv3 with additional permissions (see README).
4 from random
import Random
6 from migen
.fhdl
.structure
import *
7 from migen
.fhdl
import autofragment
8 from migen
.bus
.transactions
import *
9 from migen
.bus
import wishbone
10 from migen
.sim
.generic
import Simulator
11 from migen
.sim
.icarus
import Runner
14 # Python generators let us program bus transactions in an elegant sequential style.
18 # Write to the first addresses.
22 print("Wrote in " + str(t
.latency
) + " cycle(s)")
23 # Insert some dead cycles to simulate bus inactivity.
24 for delay
in range(prng
.randrange(0, 3)):
27 # Read from the first addresses.
31 print("Read " + str(t
.data
) + " in " + str(t
.latency
) + " cycle(s)")
32 for delay
in range(prng
.randrange(0, 3)):
36 # All transactions complete with a random delay.
37 # Reads return address + 4. Writes are simply acknowledged.
40 self
.bus
= wishbone
.Interface()
41 self
.ack_en
= Signal()
42 self
.prng
= Random(763627)
44 def do_simulation(self
, s
):
45 # Only authorize acks on certain cycles to simulate variable latency.
46 s
.wr(self
.ack_en
, self
.prng
.randrange(0, 2))
48 def get_fragment(self
):
50 self
.bus
.ack
.eq(self
.bus
.cyc
& self
.bus
.stb
& self
.ack_en
),
51 self
.bus
.dat_r
.eq(self
.bus
.adr
+ 4)
53 return Fragment(comb
, sim
=[self
.do_simulation
])
56 # The "wishbone.Initiator" library component runs our generator
57 # and manipulates the bus signals accordingly.
58 master
= wishbone
.Initiator(my_generator())
60 slave
= MyPeripheral()
61 # The "wishbone.Tap" library component examines the bus at the slave port
62 # and displays the transactions on the console (<TRead...>/<TWrite...>).
63 tap
= wishbone
.Tap(slave
.bus
)
64 # Connect the master to the slave.
65 intercon
= wishbone
.InterconnectPointToPoint(master
.bus
, slave
.bus
)
66 # A small extra simulation function to terminate the process when
67 # the initiator is done (i.e. our generator is exhausted).
68 def end_simulation(s
):
69 s
.interrupt
= master
.done
70 fragment
= autofragment
.from_local() + Fragment(sim
=[end_simulation
])
71 sim
= Simulator(fragment
, Runner())
77 # <TWrite adr:0x0 dat:0x0>
79 # <TWrite adr:0x1 dat:0x2>
81 # <TWrite adr:0x2 dat:0x4>
83 # <TWrite adr:0x3 dat:0x6>
85 # <TWrite adr:0x4 dat:0x8>
87 # <TWrite adr:0x5 dat:0xa>
90 # <TRead adr:0x0 dat:0x4>
91 # Read 4 in 2 cycle(s)
92 # <TRead adr:0x1 dat:0x5>
93 # Read 5 in 2 cycle(s)
94 # <TRead adr:0x2 dat:0x6>
95 # Read 6 in 1 cycle(s)
96 # <TRead adr:0x3 dat:0x7>
97 # Read 7 in 1 cycle(s)