2015-02-28 03:41:20 -05:00
|
|
|
from migen.fhdl.std import *
|
|
|
|
from migen.genlib.record import *
|
|
|
|
from migen.sim.generic import run_simulation
|
|
|
|
|
|
|
|
from misoclib.com.spi import SPIMaster
|
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2015-02-28 03:41:20 -05:00
|
|
|
class SPISlave(Module):
|
2015-04-13 10:19:55 -04:00
|
|
|
def __init__(self, pads, width):
|
|
|
|
self.pads = pads
|
|
|
|
self.width = width
|
2015-02-28 03:41:20 -05:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
###
|
2015-02-28 03:41:20 -05:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
self.mosi = 0
|
|
|
|
self.miso = 0
|
2015-02-28 03:41:20 -05:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
self.last_cs_n = 1
|
|
|
|
self.last_clk = 0
|
2015-02-28 03:41:20 -05:00
|
|
|
|
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
def get_mosi(self):
|
|
|
|
return self.mosi
|
2015-02-28 03:41:20 -05:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
def set_miso(self, value):
|
|
|
|
self.miso = value
|
2015-02-28 03:41:20 -05:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
def do_simulation(self, selfp):
|
|
|
|
# detect edges
|
|
|
|
cs_n_rising = 0
|
|
|
|
cs_n_falling = 0
|
|
|
|
clk_rising = 0
|
|
|
|
clk_falling = 0
|
|
|
|
if selfp.pads.cs_n and not self.last_cs_n:
|
|
|
|
cs_n_rising = 1
|
|
|
|
if not selfp.pads.cs_n and self.last_cs_n:
|
|
|
|
cs_n_falling = 1
|
|
|
|
if selfp.pads.clk and not self.last_clk:
|
|
|
|
clk_rising = 1
|
|
|
|
if not selfp.pads.clk and self.last_clk:
|
|
|
|
clk_falling = 1
|
2015-02-28 03:41:20 -05:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
# input mosi
|
|
|
|
if clk_falling and not selfp.pads.cs_n:
|
|
|
|
self.mosi = self.mosi << 1
|
|
|
|
self.mosi |= selfp.pads.mosi
|
2015-02-28 03:41:20 -05:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
# output miso
|
|
|
|
if (clk_rising and not selfp.pads.cs_n):
|
|
|
|
selfp.pads.miso = (self.miso >> (self.width-1)) & 0x1
|
|
|
|
self.miso = self.miso << 1
|
2015-02-28 03:41:20 -05:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
# save signal states
|
|
|
|
self.last_cs_n = selfp.pads.cs_n
|
|
|
|
self.last_clk = selfp.pads.clk
|
2015-02-28 03:41:20 -05:00
|
|
|
|
|
|
|
|
|
|
|
def spi_access(selfp, length, mosi):
|
2015-04-13 10:19:55 -04:00
|
|
|
selfp.spi_master._mosi.storage = mosi
|
|
|
|
yield
|
|
|
|
selfp.spi_master._ctrl.r = (length << 8) | 1
|
|
|
|
selfp.spi_master._ctrl.re = 1
|
|
|
|
yield
|
|
|
|
selfp.spi_master._ctrl.r = 0
|
|
|
|
selfp.spi_master._ctrl.re = 0
|
|
|
|
yield
|
|
|
|
while not (selfp.spi_master._status.status & 0x1):
|
|
|
|
yield
|
2015-02-28 03:41:20 -05:00
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2015-02-28 03:41:20 -05:00
|
|
|
class TB(Module):
|
2015-04-13 10:19:55 -04:00
|
|
|
def __init__(self):
|
|
|
|
pads = Record([("cs_n", 1), ("clk", 1), ("mosi", 1), ("miso", 1)])
|
|
|
|
self.submodules.spi_master = SPIMaster(pads, 24, 4)
|
|
|
|
self.submodules.spi_slave = SPISlave(pads, 24)
|
|
|
|
|
|
|
|
def gen_simulation(self, selfp):
|
|
|
|
for i in range(16):
|
|
|
|
yield
|
|
|
|
self.spi_slave.set_miso(0x123457)
|
|
|
|
yield from spi_access(selfp, 8, 0x123457)
|
|
|
|
print("{:08x}".format(self.spi_slave.get_mosi()))
|
|
|
|
print("{:08x}".format(selfp.spi_master._miso.status))
|
2015-02-28 03:41:20 -05:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2015-04-13 11:02:59 -04:00
|
|
|
run_simulation(TB(), ncycles=1000, vcd_name="my.vcd", keep_files=True)
|