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
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 Wed Apr 18 2018 10:55:28 for AMC13 by
1.8.1