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
Files
Variables
src
common
IPBUS
ipbus2
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 Sun Mar 6 2016 12:24:20 for AMC13 by
1.8.1