-
Notifications
You must be signed in to change notification settings - Fork 7
/
Spi.py
87 lines (67 loc) · 2.58 KB
/
Spi.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import random
import cocotb
from cocotb.decorators import coroutine
from cocotb.result import TestFailure, ReturnValue
from cocotb.triggers import RisingEdge, Edge, Timer
from cocotblib.TriState import TriStateOutput
from cocotblib.misc import log2Up, BoolRandomizer, assertEquals, testBit
class SpiMaster:
def __init__(self, dut, name):
self.sclk = dut.__getattr__(name + "_sclk")
self.mosi = dut.__getattr__(name + "_mosi")
self.miso = dut.__getattr__(name + "_miso")
self.ss = dut.__getattr__(name + "_ss")
class SpiSlave:
def __init__(self, dut, name):
self.sclk = dut.__getattr__(name + "_sclk")
self.mosi = dut.__getattr__(name + "_mosi")
self.miso = TriStateOutput(dut,name + "_miso")
self.ss = dut.__getattr__(name + "_ss")
class SpiSlaveMaster:
def __init__(self, spi):
self.spi = spi
self.cpol = False
self.cpha = False
self.baudPeriode = 1000
self.dataWidth = 8
def init(self, cpol, cpha, baudrate, dataWidth = 8):
self.spi.ss <= True
self.cpol = cpol
self.cpha = cpha
self.baudPeriode = baudrate
self.dataWidth = dataWidth
self.spi.sclk <= cpol
@coroutine
def enable(self):
self.spi.ss <= False
yield Timer(self.baudPeriode)
@coroutine
def disable(self):
yield Timer(self.baudPeriode)
self.spi.ss <= True
yield Timer(self.baudPeriode)
@coroutine
def exchange(self, masterData):
buffer = ""
if not self.cpha:
for i in range(self.dataWidth):
self.spi.mosi <= testBit(masterData, self.dataWidth - 1 - i)
yield Timer(self.baudPeriode >> 1)
buffer = buffer + str(self.spi.miso.write) if bool(self.spi.miso.writeEnable) else "x"
self.spi.sclk <= (not self.cpol)
yield Timer(self.baudPeriode >> 1)
self.spi.sclk <= (self.cpol)
else:
for i in range(self.dataWidth):
self.spi.mosi <= testBit(masterData, self.dataWidth -1 - i)
self.spi.sclk <= (not self.cpol)
yield Timer(self.baudPeriode >> 1)
buffer = buffer + str(self.spi.miso.write) if bool(self.spi.miso.writeEnable) else "x"
self.spi.sclk <= (self.cpol)
yield Timer(self.baudPeriode >> 1)
raise ReturnValue(buffer)
@coroutine
def exchangeCheck(self, masterData, slaveData):
c = self.exchange(masterData)
yield c
assert slaveData == int(c.retval,2)