Skip to content

Commit 2efcfdb

Browse files
committed
Add PTP clock simulation model
1 parent e181ea5 commit 2efcfdb

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed

tb/ptp.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
"""
2+
3+
Copyright (c) 2015-2019 Alex Forencich
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.
22+
23+
"""
24+
25+
from myhdl import *
26+
27+
class PtpClock(object):
28+
def __init__(self):
29+
self.period_ns = 0x6
30+
self.period_fns = 0x6666
31+
self.drift_ns = 0x0
32+
self.drift_fns = 0x0002
33+
self.drift_rate = 5
34+
35+
self.set_96_l = []
36+
self.set_64_l = []
37+
38+
def set_96(self, ts):
39+
self.set_96_l.append(ts)
40+
41+
def set_64(self, ts):
42+
self.set_64_l.append(ts)
43+
44+
def create_logic(self,
45+
clk,
46+
rst,
47+
ts_96=Signal(intbv(0)[96:]),
48+
ts_64=Signal(intbv(0)[64:]),
49+
ts_step=Signal(bool(0))
50+
):
51+
52+
@instance
53+
def logic():
54+
55+
ts_96_s = 0
56+
ts_96_ns = 0
57+
ts_96_fns = 0
58+
59+
ts_64_ns = 0
60+
ts_64_fns = 0
61+
62+
drift_cnt = 0
63+
64+
while True:
65+
yield clk.posedge, rst.posedge
66+
67+
if rst:
68+
ts_96_s = 0
69+
ts_96_ns = 0
70+
ts_96_fns = 0
71+
ts_64_ns = 0
72+
ts_64_fns = 0
73+
drift_cnt = 0
74+
ts_96.next = 0
75+
ts_64.next = 0
76+
else:
77+
ts_step.next = 0
78+
79+
t = ((ts_96_ns << 16) + ts_96_fns) + ((self.period_ns << 16) + self.period_fns)
80+
81+
if drift_cnt > 0:
82+
t += (self.drift_ns << 16) + self.drift_fns
83+
ts_step.next = 1
84+
85+
if t > (1000000000<<16):
86+
ts_96_s += 1
87+
t -= (1000000000<<16)
88+
89+
ts_96_fns = t & 0xffff
90+
ts_96_ns = t >> 16
91+
92+
if self.set_96_l:
93+
ts = self.set_96_l.pop(0)
94+
95+
ts_96_s = ts >> 48
96+
ts_96_ns = (ts >> 16) & 0x3fffffff
97+
ts_96_fns = ts & 0xffff
98+
99+
ts_step.next = 1
100+
101+
ts_96.next = (ts_96_s << 48) | (ts_96_ns << 16) | (ts_96_fns)
102+
103+
t = ((ts_64_ns << 16) + ts_64_fns) + ((self.period_ns << 16) + self.period_fns)
104+
105+
if drift_cnt > 0:
106+
t += ((self.drift_ns << 16) + self.drift_fns)
107+
ts_step.next = 1
108+
109+
ts_64_fns = t & 0xffff
110+
ts_64_ns = t >> 16
111+
112+
if self.set_64_l:
113+
ts = self.set_64_l.pop(0)
114+
115+
ts_64_ns = ts >> 16
116+
ts_64_fns = ts & 0xffff
117+
118+
ts_step.next = 1
119+
120+
ts_64.next = (ts_64_ns << 16) | ts_64_fns
121+
122+
if drift_cnt > 0:
123+
drift_cnt -= 1
124+
else:
125+
drift_cnt = self.drift_rate-1
126+
127+
return instances()

0 commit comments

Comments
 (0)