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
transactor_sm.vhd
1
-- The state machine which controls the ipbus itself
2
--
3
-- This version
for
ipbus
2
.
0
4
--
5
--
All
details
of
the ipbus transaction protocol itself are
in
here.
6
-- However, the module knows nothing about the
transport
layer,
and
7
-- just processes the transactions it's handed.
8
--
9
-- Dave Newbold, October
2012
10
11
library
ieee
;
12
use
ieee.std_logic_1164.
all
;
13
use
ieee.numeric_std.
all
;
14
15
library
work
;
16
use
work.
ipbus
.
all
;
17
18
entity
transactor_sm
is
19
port
(
20
clk
:
in
std_logic
;
21
rst
:
in
std_logic
;
22
rx_data
:
in
std_logic_vector
(
31
downto
0
)
;
-- Input packet data
23
rx_ready
:
in
std_logic
;
-- Asserted
when
valid input packet data
is
available
24
rx_next
:
out
std_logic
;
--
New
input packet data please
25
tx_data
:
out
std_logic_vector
(
31
downto
0
)
;
-- Output packet data
26
tx_we
:
out
std_logic
;
-- Valid output word
27
tx_hdr
:
out
std_logic
;
-- Marks a transaction header
28
tx_err
:
out
std_logic
;
-- Asserted
if
we
end
the packet early due
to
error
29
ipb_out
:
out
ipb_wbus
;
30
ipb_in
:
in
ipb_rbus
;
31
cfg_we
:
out
std_logic
;
-- local
bus
write enable
32
cfg_addr
:
out
std_logic_vector
(
1
downto
0
)
;
-- local
bus
addr
33
cfg_din
:
in
std_logic_vector
(
31
downto
0
)
;
-- local
bus
data
34
cfg_dout
:
out
std_logic_vector
(
31
downto
0
)
35
)
;
36
37
end
transactor_sm
;
38
39
architecture
rtl
of
transactor_sm
is
40
41
constant
TIMEOUT
:
integer
:=
255
;
42
43
constant
TRANS_RD
:
std_logic_vector
(
3
downto
0
)
:=
X
"0"
;
44
constant
TRANS_WR
:
std_logic_vector
(
3
downto
0
)
:=
X
"1"
;
45
constant
TRANS_RDN
:
std_logic_vector
(
3
downto
0
)
:=
X
"2"
;
46
constant
TRANS_WRN
:
std_logic_vector
(
3
downto
0
)
:=
X
"3"
;
47
constant
TRANS_RMWB
:
std_logic_vector
(
3
downto
0
)
:=
X
"4"
;
48
constant
TRANS_RMWS
:
std_logic_vector
(
3
downto
0
)
:=
X
"5"
;
49
constant
TRANS_RD_CFG
:
std_logic_vector
(
3
downto
0
)
:=
X
"6"
;
50
constant
TRANS_WR_CFG
:
std_logic_vector
(
3
downto
0
)
:=
X
"7"
;
51
52
type
state_type
is
(
ST_IDLE
,
ST_HDR
,
ST_ADDR
,
ST_BUS_CYCLE
,
ST_RMW_1
,
ST_RMW_2
)
;
53
signal
state
:
state_type
;
54
55
signal
rx_ready_d
,
start
,
rmw_cyc
,
cfg_cyc
,
rmw_write
,
write
,
strobe
,
ack
,
last_wd
:
std_logic
;
56
signal
trans_type
:
std_logic_vector
(
3
downto
0
)
;
57
signal
addr
:
unsigned
(
31
downto
0
)
;
58
signal
words_todo
,
words_done
:
unsigned
(
7
downto
0
)
;
59
signal
timer
:
unsigned
(
7
downto
0
)
;
60
signal
rmw_coeff
,
rmw_input
,
rmw_result
,
data_out
:
std_logic_vector
(
31
downto
0
)
;
61
signal
err
,
err_d
:
std_logic_vector
(
3
downto
0
)
;
62
signal
hdr
:
std_logic_vector
(
31
downto
0
)
;
63
64
begin
65
66
process
(clk)
67
begin
68
if
rising_edge
(
clk
)
then
69
if
rst
=
'
1
'
then
70
state
<=
ST_IDLE
;
71
else
72
case
state
is
73
-- Starting state
74
when
ST_IDLE
=
>
75
if
start
=
'
1
'
then
76
state
<=
ST_HDR
;
77
end
if
;
78
-- Decode header word
79
when
ST_HDR
=
>
80
if
rx_ready
=
'
0
'
or
err
/=
X
"0"
or
err_d
/=
X
"0"
then
81
state
<=
ST_IDLE
;
82
else
83
state
<=
ST_ADDR
;
84
end
if
;
85
-- Load address counter
86
when
ST_ADDR
=
>
87
if
words_todo
/=
X
"00"
then
88
state
<=
ST_BUS_CYCLE
;
89
else
90
state
<=
ST_HDR
;
91
end
if
;
92
-- The
bus
transaction
93
when
ST_BUS_CYCLE
=
>
94
if
err
/=
X
"0"
then
95
state
<=
ST_HDR
;
96
elsif
ack
=
'
1
'
and
last_wd
=
'
1
'
then
97
if
rmw_cyc
=
'
1
'
and
rmw_write
=
'
0
'
then
98
state
<=
ST_RMW_1
;
99
else
100
state
<=
ST_HDR
;
101
end
if
;
102
elsif
timer
=
TIMEOUT
then
103
state
<=
ST_HDR
;
104
end
if
;
105
-- RMW operations
106
when
ST_RMW_1
=
>
107
if
trans_type
=
TRANS_RMWB
then
108
state
<=
ST_RMW_2
;
109
else
110
state
<=
ST_BUS_CYCLE
;
111
end
if
;
112
113
when
ST_RMW_2
=
>
114
state
<=
ST_BUS_CYCLE
;
115
116
end
case
;
117
end
if
;
118
119
end
if
;
120
end
process
;
121
122
process
(clk)
123
begin
124
if
rising_edge
(
clk
)
then
125
126
rx_ready_d
<=
rx_ready
;
127
128
if
state
=
ST_HDR
then
129
hdr
<=
rx_data
;
130
end
if
;
131
132
if
state
=
ST_ADDR
then
133
addr
<=
unsigned
(
rx_data
)
;
134
elsif
ack
=
'
1
'
and
(
trans_type
=
TRANS_RD
or
trans_type
=
TRANS_WR
)
then
135
addr
<=
addr
+
1
;
136
end
if
;
137
138
if
state
=
ST_HDR
then
139
words_todo
<=
unsigned
(
rx_data
(
15
downto
8
)
)
;
140
elsif
state
=
ST_RMW_1
then
141
words_todo
<=
(
others
=
>
'
0
'
)
;
142
elsif
state
<=
ST_ADDR
or
ack
=
'
1
'
then
143
words_todo
<=
words_todo
-
1
;
144
end
if
;
145
146
if
state
=
ST_HDR
then
147
words_done
<=
(
others
=
>
'
0
'
)
;
148
elsif
ack
=
'
1
'
and
(
rmw_cyc
=
'
0
'
or
rmw_write
=
'
1
'
)
then
149
words_done
<=
words_done
+
1
;
150
end
if
;
151
152
if
state
=
ST_ADDR
or
state
=
ST_RMW_1
or
ack
=
'
1
'
then
153
timer
<=
(
others
=
>
'
0
'
)
;
154
elsif
strobe
=
'
1
'
then
155
timer
<=
timer
+
1
;
156
end
if
;
157
158
if
state
=
ST_HDR
then
159
rmw_write
<=
'
0
'
;
160
elsif
state
=
ST_RMW_1
then
161
rmw_write
<=
'
1
'
;
162
end
if
;
163
164
if
state
=
ST_RMW_1
then
165
rmw_coeff
<=
rx_data
;
166
rmw_result
<=
std_logic_vector
(
unsigned
(
rmw_input
)
+
unsigned
(
rx_data
)
)
;
167
elsif
state
=
ST_RMW_2
then
168
rmw_result
<=
(
rmw_input
and
rmw_coeff
)
or
rx_data
;
169
end
if
;
170
171
if
ack
=
'
1
'
then
172
rmw_input
<=
ipb_in
.
ipb_rdata
;
173
end
if
;
174
175
if
state
=
ST_IDLE
then
176
err_d
<=
X
"0"
;
177
else
178
err_d
<=
err
;
179
end
if
;
180
181
end
if
;
182
end
process
;
183
184
start
<=
rx_ready
and
not
rx_ready_d
;
185
last_wd
<=
'
1
'
when
words_todo
=
0
else
'
0
'
;
186
trans_type
<=
hdr
(
7
downto
4
)
;
187
188
strobe
<=
'
1
'
when
state
=
ST_BUS_CYCLE
and
cfg_cyc
=
'
0
'
else
'
0
'
;
189
write
<=
'
1
'
when
trans_type
=
TRANS_WR
or
trans_type
=
TRANS_WRN
or
trans_type
=
TRANS_WR_CFG
190
or
rmw_write
=
'
1
'
else
'
0
'
;
191
rx_next
<=
'
1
'
when
state
=
ST_HDR
or
state
=
ST_RMW_1
or
state
=
ST_RMW_2
or
192
(
state
=
ST_ADDR
and
(
write
=
'
1
'
or
words_todo
=
X
"00"
)
)
or
193
(
state
=
ST_BUS_CYCLE
and
(
ack
and
(
strobe
or
cfg_cyc
)
and
(
write
or
last_wd
)
and
not
rmw_write
)
=
'
1
'
)
194
else
'
0
'
;
195
rmw_cyc
<=
'
1
'
when
trans_type
=
TRANS_RMWB
or
trans_type
=
TRANS_RMWS
else
'
0
'
;
196
cfg_cyc
<=
'
1
'
when
trans_type
=
TRANS_RD_CFG
or
trans_type
=
TRANS_WR_CFG
else
'
0
'
;
197
198
process
(state, rx_data, ipb_in.ipb_err, timer, write)
199
begin
200
err
<=
X
"0"
;
201
if
state
=
ST_HDR
then
202
if
rx_data
(
31
downto
28
)
/=
X
"2"
or
rx_data
(
3
downto
0
)
/=
X
"f"
then
203
err
<=
"0001"
;
204
end
if
;
205
elsif
state
=
ST_BUS_CYCLE
then
206
if
ipb_in
.
ipb_err
=
'
1
'
then
207
err
<=
"010"
&
write
;
208
elsif
timer
=
TIMEOUT
then
209
err
<=
"011"
&
write
;
210
end
if
;
211
end
if
;
212
end
process
;
213
214
ack
<=
ipb_in
.
ipb_ack
or
ipb_in
.
ipb_err
or
cfg_cyc
;
215
216
ipb_out
.
ipb_addr
<=
std_logic_vector
(
addr
)
;
217
ipb_out
.
ipb_write
<=
write
;
218
ipb_out
.
ipb_strobe
<=
strobe
;
219
ipb_out
.
ipb_wdata
<=
rx_data
when
rmw_cyc
=
'
0
'
else
rmw_result
;
220
221
data_out
<=
ipb_in
.
ipb_rdata
when
cfg_cyc
=
'
0
'
else
cfg_din
;
222
223
tx_data
<=
(
hdr
(
31
downto
16
)
&
std_logic_vector
(
words_done
)
&
hdr
(
7
downto
4
)
&
err_d
)
when
state
=
ST_HDR
else
data_out
;
224
tx_we
<=
'
1
'
when
state
=
ST_HDR
or
(
state
=
ST_BUS_CYCLE
and
(
ack
and
not
write
)
=
'
1
'
)
else
'
0
'
;
225
tx_hdr
<=
'
1
'
when
state
=
ST_HDR
else
'
0
'
;
226
tx_err
<=
'
1
'
when
err_d
/=
X
"0"
else
'
0
'
;
227
228
cfg_addr
<=
std_logic_vector
(
addr
(
1
downto
0
)
)
;
229
cfg_we
<=
'
1
'
when
state
=
ST_BUS_CYCLE
and
trans_type
=
TRANS_WR_CFG
else
'
0
'
;
230
cfg_dout
<=
rx_data
;
231
232
end
rtl
;
Generated on Sun Mar 6 2016 12:24:20 for AMC13 by
1.8.1