AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
Main Page
Design Unit List
Files
File List
All
Classes
Variables
src
common
IPBUS
ipbus_core
hdl
udp_clock_crossing_if.vhd
1
-- Signals crossing clock domain...
2
--
3
-- Dave Sankey, January
2013
4
5
library
ieee
;
6
use
ieee.std_logic_1164.
all
;
7
use
ieee.numeric_std.
all
;
8
9
entity
udp_clock_crossing_if
is
10
generic
(
11
BUFWIDTH
:
natural
:=
0
12
)
;
13
port
(
14
mac_clk
:
in
std_logic
;
15
rst_macclk
:
in
std_logic
;
16
--
17
busy_125
:
in
std_logic
;
18
rx_read_buffer_125
:
in
std_logic_vector
(
BUFWIDTH
-
1
downto
0
)
;
19
rx_req_send_125
:
in
std_logic
;
20
tx_write_buffer_125
:
in
std_logic_vector
(
BUFWIDTH
-
1
downto
0
)
;
21
enable_125:
out
std_logic
;
22
rarp_125
:
out
std_logic
;
23
rst_ipb_125
:
out
std_logic
;
24
rx_ram_sent
:
out
std_logic
;
25
tx_ram_written
:
out
std_logic
;
26
we_125
:
out
std_logic
;
27
--
28
ipb_clk
:
in
std_logic
;
29
rst_ipb
:
in
std_logic
;
30
--
31
enable:
in
std_logic
;
32
pkt_done_read
:
in
std_logic
;
33
pkt_done_write
:
in
std_logic
;
34
RARP
:
in
std_logic
;
35
we
:
in
std_logic
;
36
busy
:
out
std_logic
;
37
pkt_rdy
:
out
std_logic
;
38
rx_read_buffer
:
out
std_logic_vector
(
BUFWIDTH
-
1
downto
0
)
;
39
tx_write_buffer
:
out
std_logic_vector
(
BUFWIDTH
-
1
downto
0
)
40
)
;
41
end
udp_clock_crossing_if
;
42
43
architecture
rtl
of
udp_clock_crossing_if
is
44
45
signal
req_send_tff
,
busy_buf
,
busy_up_tff
,
busy_down_tff
:
std_logic
;
46
signal
enable_buf
,
rarp_buf
,
we_buf
,
rst_ipb_buf
:
std_logic_vector
(
1
downto
0
)
;
47
signal
req_send_buf
,
pkt_done_read_buf
,
pkt_done_write_buf
,
busy_up_buf
,
48
busy_down_buf
,
pkt_done_r_tff
,
pkt_done_w_tff
:
std_logic_vector
(
2
downto
0
)
;
49
signal
rx_read_buf_buf
,
tx_write_buf_buf
:
std_logic_vector
(
BUFWIDTH
-
1
downto
0
)
;
50
51
attribute
KEEP
:
string
;
52
attribute
KEEP
of
busy_down_buf
:
signal
is
"TRUE"
;
53
attribute
KEEP
of
busy_up_buf
:
signal
is
"TRUE"
;
54
attribute
KEEP
of
enable_buf
:
signal
is
"TRUE"
;
55
attribute
KEEP
of
pkt_done_read_buf
:
signal
is
"TRUE"
;
56
attribute
KEEP
of
pkt_done_write_buf
:
signal
is
"TRUE"
;
57
attribute
KEEP
of
rarp_buf
:
signal
is
"TRUE"
;
58
attribute
KEEP
of
req_send_buf
:
signal
is
"TRUE"
;
59
attribute
KEEP
of
rst_ipb_buf
:
signal
is
"TRUE"
;
60
attribute
KEEP
of
rx_read_buf_buf
:
signal
is
"TRUE"
;
61
attribute
KEEP
of
tx_write_buf_buf
:
signal
is
"TRUE"
;
62
attribute
KEEP
of
we_buf
:
signal
is
"TRUE"
;
63
64
begin
65
66
-- clock domain crossing logic based
on
67
-- http://sc.morganisms.net/2010/06/rtl-for-passing-pulse-across-clock-domains-in-vhdl/
68
-- assumption
is
that ipbus clock
is
significantly slower than ethernet mac clock
69
-- so that transitions
in
ipbus clock domain are always caught
in
mac clock domain
70
-- whereas toggle flip flops are used
to
ensure the reciprocal
71
-- but just
to
be safe do the same
for
pkt_done...
72
73
enable_125 <= enable_buf(
1
);
74
rarp_125
<=
rarp_buf
(
1
)
;
75
we_125
<=
we_buf
(
1
)
;
76
rst_ipb_125
<=
rst_ipb_buf
(
1
)
;
77
78
pkt_done_ipb_clk:
process
(ipb_clk)
79
begin
80
if
rising_edge
(
ipb_clk
)
then
81
if
rst_ipb
=
'
1
'
then
82
pkt_done_r_tff
<=
"000"
;
83
pkt_done_w_tff
<=
"000"
;
84
else
85
-- infer a (delayed) toggle flip flop
in
source domain
86
pkt_done_r_tff
<=
pkt_done_r_tff
(
1
downto
0
)
&
(
pkt_done_r_tff
(
0
)
xor
pkt_done_read
)
;
87
pkt_done_w_tff
<=
pkt_done_w_tff
(
1
downto
0
)
&
(
pkt_done_w_tff
(
0
)
xor
pkt_done_write
)
;
88
end
if
;
89
end
if
;
90
end
process
;
91
92
pkt_done_mac_clk:
process
(mac_clk)
93
begin
94
if
rising_edge
(
mac_clk
)
then
95
-- rx_ram_sent
and
tx_ram_written only high
for
1
tick...
96
rx_ram_sent
<=
pkt_done_read_buf
(
2
)
xor
pkt_done_read_buf
(
1
)
;
97
tx_ram_written
<=
pkt_done_write_buf
(
2
)
xor
pkt_done_write_buf
(
1
)
;
98
-- pick up delayed tff from ipbus domain
99
pkt_done_read_buf
<=
pkt_done_read_buf
(
1
downto
0
)
&
pkt_done_r_tff
(
2
)
;
100
pkt_done_write_buf
<=
pkt_done_write_buf
(
1
downto
0
)
&
pkt_done_w_tff
(
2
)
;
101
end
if
;
102
end
process
;
103
104
req_send_mac_clk:
process
(mac_clk)
105
begin
106
if
rising_edge
(
mac_clk
)
then
107
if
rst_macclk
=
'
1
'
then
108
req_send_tff
<=
'
0
'
;
109
else
110
-- infer a toggle flip flop
in
source domain
111
req_send_tff
<=
req_send_tff
xor
rx_req_send_125
;
112
end
if
;
113
end
if
;
114
end
process
;
115
116
req_send_buf_ipb_clk:
process
(ipb_clk)
117
begin
118
if
rising_edge
(
ipb_clk
)
then
119
req_send_buf
<=
req_send_buf
(
1
downto
0
)
&
req_send_tff
;
120
end
if
;
121
end
process
;
122
123
pkt_rdy_ipb_clk:
process
(ipb_clk)
124
variable
pkt_rdy_buf
:
std_logic_vector
(
2
downto
0
)
;
125
begin
126
if
rising_edge
(
ipb_clk
)
then
127
if
rst_ipb
=
'
1
'
then
128
pkt_rdy_buf
:=
(
Others
=
>
'
0
'
)
;
129
elsif
pkt_done_read
=
'
1
'
then
130
pkt_rdy_buf
:=
(
Others
=
>
'
0
'
)
;
131
elsif
(
req_send_buf
(
2
)
xor
req_send_buf
(
1
)
)
=
'
1
'
then
132
pkt_rdy_buf
:=
pkt_rdy_buf
(
1
downto
0
)
&
'
1
'
;
133
else
134
pkt_rdy_buf
:=
pkt_rdy_buf
(
1
downto
0
)
&
pkt_rdy_buf
(
0
)
;
135
end
if
;
136
pkt_rdy
<=
pkt_rdy_buf
(
2
)
;
137
end
if
;
138
end
process
;
139
140
enable_mac_clk:
process
(mac_clk)
141
begin
142
if
rising_edge
(
mac_clk
)
then
143
enable_buf <= enable_buf(
0
) & enable;
144
end
if
;
145
end
process
;
146
147
rarp_mac_clk:
process
(mac_clk)
148
begin
149
if
rising_edge
(
mac_clk
)
then
150
rarp_buf
<=
rarp_buf
(
0
)
&
RARP
;
151
end
if
;
152
end
process
;
153
154
we_mac_clk:
process
(mac_clk)
155
begin
156
if
rising_edge
(
mac_clk
)
then
157
we_buf
<=
we_buf
(
0
)
&
we
;
158
end
if
;
159
end
process
;
160
161
rst_ipb_mac_clk:
process
(mac_clk)
162
begin
163
if
rising_edge
(
mac_clk
)
then
164
rst_ipb_buf
<=
rst_ipb_buf
(
0
)
&
rst_ipb
;
165
end
if
;
166
end
process
;
167
168
busy_mac_clk:
process
(mac_clk)
169
begin
170
if
rising_edge
(
mac_clk
)
then
171
if
rst_macclk
=
'
1
'
then
172
busy_up_tff
<=
'
0
'
;
173
busy_down_tff
<=
'
0
'
;
174
busy_buf
<=
'
0
'
;
175
else
176
-- infer toggle flip flops
in
source domain
177
busy_up_tff
<=
busy_up_tff
xor
(
busy_125
and
not
busy_buf
)
;
178
busy_down_tff
<=
busy_down_tff
xor
(
busy_buf
and
not
busy_125
)
;
179
busy_buf
<=
busy_125
;
180
end
if
;
181
end
if
;
182
end
process
;
183
184
busy_up_down_ipb_clk:
process
(ipb_clk)
185
begin
186
if
rising_edge
(
ipb_clk
)
then
187
busy_up_buf
<=
busy_up_buf
(
1
downto
0
)
&
busy_up_tff
;
188
busy_down_buf
<=
busy_down_buf
(
1
downto
0
)
&
busy_down_tff
;
189
end
if
;
190
end
process
;
191
192
busy_ipb_clk:
process
(ipb_clk)
193
variable
busy_buf
:
std_logic_vector
(
3
downto
0
)
;
194
begin
195
if
rising_edge
(
ipb_clk
)
then
196
if
rst_ipb
=
'
1
'
then
197
busy_buf
:=
(
Others
=
>
'
0
'
)
;
198
elsif
pkt_done_write
=
'
1
'
then
199
busy_buf
:=
(
Others
=
>
'
1
'
)
;
200
elsif
(
busy_up_buf
(
2
)
xor
busy_up_buf
(
1
)
)
=
'
1
'
then
201
busy_buf
:=
(
Others
=
>
'
1
'
)
;
202
end
if
;
203
busy
<=
busy_buf
(
3
)
;
204
if
(
busy_down_buf
(
2
)
xor
busy_down_buf
(
1
)
)
=
'
1
'
then
205
busy_buf
:=
busy_buf
(
2
downto
0
)
&
'
0
'
;
206
else
207
busy_buf
:=
busy_buf
(
2
downto
0
)
&
busy_buf
(
0
)
;
208
end
if
;
209
end
if
;
210
end
process
;
211
212
rx_read_buffer_ipb_clk:
process
(ipb_clk)
213
begin
214
if
rising_edge
(
ipb_clk
)
then
215
rx_read_buf_buf
<=
rx_read_buffer_125
;
216
rx_read_buffer
<=
rx_read_buf_buf
;
217
end
if
;
218
end
process
;
219
220
tx_write_buffer_ipb_clk:
process
(ipb_clk)
221
begin
222
if
rising_edge
(
ipb_clk
)
then
223
tx_write_buf_buf
<=
tx_write_buffer_125
;
224
tx_write_buffer
<=
tx_write_buf_buf
;
225
end
if
;
226
end
process
;
227
228
end
rtl
;
Generated on Wed Apr 18 2018 10:55:28 for AMC13 by
1.8.1