Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit core collection
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
30
Issues
30
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
White Rabbit core collection
Commits
25e16479
Commit
25e16479
authored
Nov 14, 2013
by
Wesley W. Terpstra
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eca: update to new etherbone API and ECA hardware
parent
007b38c9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
597 additions
and
626 deletions
+597
-626
Makefile
modules/wr_eca/Makefile
+14
-6
eca-ctl.cpp
modules/wr_eca/eca-ctl.cpp
+67
-48
eca-table.cpp
modules/wr_eca/eca-table.cpp
+32
-55
eca.h
modules/wr_eca/eca.h
+88
-69
eca.vhd
modules/wr_eca/eca.vhd
+9
-5
hw-channel.cpp
modules/wr_eca/lib/hw-channel.cpp
+101
-39
hw-eca.cpp
modules/wr_eca/lib/hw-eca.cpp
+9
-42
hw-eca.h
modules/wr_eca/lib/hw-eca.h
+66
-14
hw-stream.cpp
modules/wr_eca/lib/hw-stream.cpp
+11
-15
load-queue.cpp
modules/wr_eca/lib/load-queue.cpp
+0
-97
load-search.cpp
modules/wr_eca/lib/load-search.cpp
+0
-81
load-table.cpp
modules/wr_eca/lib/load-table.cpp
+71
-13
probe-eca.cpp
modules/wr_eca/lib/probe-eca.cpp
+25
-45
program-walk.cpp
modules/wr_eca/lib/program-walk.cpp
+0
-74
store-table.cpp
modules/wr_eca/lib/store-table.cpp
+64
-11
table.cpp
modules/wr_eca/lib/table.cpp
+40
-12
No files found.
modules/wr_eca/Makefile
View file @
25e16479
PREFIX
?=
/usr/local
STAGING
?=
EB
?=
../../ip_cores/etherbone-core/api
EB
?=
no
ifeq
($(EB),no))
EB_LIB
?=
-letherbone
EB_INC
?=
else
EB_LIB
?=
-L
$(EB)
-letherbone
EB_INC
?=
-I
$(EB)
endif
CXX
=
g++
CXXFLAGS
=
-Wall
-O2
-I
.
-I
$(EB
)
CXXFLAGS
=
-Wall
-O2
-I
.
$(EB_INC
)
TARGETS
=
lib/version.h libeca.a eca-ctl eca-table
all
:
$(TARGETS)
...
...
@@ -18,14 +26,14 @@ clean:
rm
-f
$(TARGETS)
*
.o lib/
*
.o git.
*
eca-ctl
:
eca-ctl.o libeca.a
$(CXX)
$(CXXFLAGS)
-o
$@
$^
-
L
$(EB)
-Wl
,-rpath,
$(PREFIX)
/lib
-letherbone
$(CXX)
$(CXXFLAGS)
-o
$@
$^
-
Wl
,-rpath,
$(PREFIX)
/lib
$(EB_LIB)
eca-table
:
eca-table.o libeca.a
$(CXX)
$(CXXFLAGS)
-o
$@
$^
-
L
$(EB)
-Wl
,-rpath,
$(PREFIX)
/lib
-letherbone
$(CXX)
$(CXXFLAGS)
-o
$@
$^
-
Wl
,-rpath,
$(PREFIX)
/lib
$(EB_LIB)
libeca.a
:
lib/hw-eca.o lib/hw-stream.o lib/hw-channel.o
\
lib/load-
search.o lib/load-walk.o lib/load-queue.o lib/load-eca
.o
\
lib/
program-search.o lib/program-walk.o lib/program-table
.o
lib/load-
table.o lib/store-table
.o
\
lib/
table.o lib/probe-eca
.o
rm
-f
$@
ar rcs
$@
$^
ranlib
$@
...
...
modules/wr_eca/eca-ctl.cpp
View file @
25e16479
This diff is collapsed.
Click to expand it.
modules/wr_eca/eca-table.cpp
View file @
25e16479
...
...
@@ -67,8 +67,10 @@ static void die(eb_status_t status, const char* what) {
exit
(
1
);
}
static
void
dump
(
const
ECA
&
eca
,
const
ReverseTable
&
rt
)
{
std
::
vector
<
TableEntry
>
t
=
rt
.
reverse
();
static
void
dump
(
const
ECA
&
eca
,
const
Table
&
table
)
{
std
::
vector
<
TableEntry
>
t
;
table
.
get
(
t
);
if
(
!
quiet
)
{
if
(
numeric
)
{
...
...
@@ -94,6 +96,7 @@ static void dump(const ECA& eca, const ReverseTable& rt) {
}
}
#if 0
if (verbose) {
if (numeric) {
printf("--------------------------------------------------------------\n");
...
...
@@ -108,6 +111,7 @@ static void dump(const ECA& eca, const ReverseTable& rt) {
printf("Table usage: %d/%d search and %d/%d walk\n",
(int)st.size(), (int)eca.table_size*2, (int)wt.size(), (int)eca.table_size);
}
#endif
}
int
main
(
int
argc
,
char
**
argv
)
{
...
...
@@ -220,7 +224,7 @@ int main(int argc, char** argv) {
}
std
::
vector
<
ECA
>
ecas
;
if
((
status
=
ECA
::
load
(
device
,
ecas
))
!=
EB_OK
)
die
(
status
,
"ECA::load"
);
if
((
status
=
ECA
::
probe
(
device
,
ecas
))
!=
EB_OK
)
die
(
status
,
"ECA::load"
);
if
(
ecas
.
empty
())
{
fprintf
(
stderr
,
"%s: no ECA units found
\n
"
,
program
);
...
...
@@ -289,9 +293,7 @@ int main(int argc, char** argv) {
te
.
channel
=
channel
;
}
std
::
vector
<
SearchEntry
>
st
;
std
::
vector
<
WalkEntry
>
wt
;
ReverseTable
rt
;
Table
table
;
if
(
!
strcasecmp
(
command
,
"dump"
))
{
if
(
verbose
)
{
...
...
@@ -299,13 +301,10 @@ int main(int argc, char** argv) {
eca_id
,
eca
.
name
.
c_str
(),
eca
.
address
);
}
if
((
status
=
eca
.
loadSearch
(
device
,
false
,
st
))
!=
EB_OK
)
die
(
status
,
"ECA::loadSearch(inactive)"
);
if
((
status
=
eca
.
loadWalk
(
device
,
false
,
wt
))
!=
EB_OK
)
die
(
status
,
"ECA::loadWalk(inactive)"
);
if
((
status
=
eca
.
load
(
false
,
table
))
!=
EB_OK
)
die
(
status
,
"ECA::load(inactive)"
);
rt
.
load
(
st
,
wt
);
dump
(
eca
,
rt
);
dump
(
eca
,
table
);
}
if
(
!
strcasecmp
(
command
,
"dump-active"
))
{
...
...
@@ -314,13 +313,10 @@ int main(int argc, char** argv) {
eca_id
,
eca
.
name
.
c_str
(),
eca
.
address
);
}
if
((
status
=
eca
.
loadSearch
(
device
,
true
,
st
))
!=
EB_OK
)
die
(
status
,
"ECA::loadSearch(active)"
);
if
((
status
=
eca
.
loadWalk
(
device
,
true
,
wt
))
!=
EB_OK
)
die
(
status
,
"ECA::loadWalk(active)"
);
if
((
status
=
eca
.
load
(
true
,
table
))
!=
EB_OK
)
die
(
status
,
"ECA::load(active)"
);
rt
.
load
(
st
,
wt
);
dump
(
eca
,
rt
);
dump
(
eca
,
table
);
}
if
(
!
strcasecmp
(
command
,
"flip-active"
))
{
...
...
@@ -329,24 +325,19 @@ int main(int argc, char** argv) {
eca_id
,
eca
.
name
.
c_str
(),
eca
.
address
);
}
if
((
status
=
eca
.
flipTables
(
device
))
!=
EB_OK
)
if
((
status
=
eca
.
flipTables
())
!=
EB_OK
)
die
(
status
,
"ECA::flipTables"
);
}
if
(
!
strcasecmp
(
command
,
"flush"
))
{
rt
.
compile
(
st
,
wt
);
/* rt is empty */
if
(
verbose
)
{
printf
(
"Table usage now %d/%d search and %d/%d walk
\n
"
,
(
int
)
st
.
size
(),
(
int
)
eca
.
table_size
*
2
,
(
int
)
wt
.
size
(),
(
int
)
eca
.
table_size
);
printf
(
"Flushing inactive table on ECA #%d
\"
%s
\"
(0x%"
EB_ADDR_FMT
"):
\n
"
,
eca_id
,
eca
.
name
.
c_str
(),
eca
.
address
);
}
if
((
status
=
eca
.
programSearch
(
device
,
st
))
!=
EB_OK
)
die
(
status
,
"ECA::programSearch"
);
if
((
status
=
eca
.
programWalk
(
device
,
wt
))
!=
EB_OK
)
die
(
status
,
"ECA::programWalk"
);
/* table is empty */
if
((
status
=
eca
.
store
(
table
))
!=
EB_OK
)
die
(
status
,
"ECA::store"
);
}
if
(
!
strcasecmp
(
command
,
"add"
))
{
...
...
@@ -361,30 +352,23 @@ int main(int argc, char** argv) {
eca_id
,
eca
.
name
.
c_str
(),
eca
.
address
);
}
if
((
status
=
eca
.
loadSearch
(
device
,
false
,
st
))
!=
EB_OK
)
die
(
status
,
"ECA::loadSearch(inactive)"
);
if
((
status
=
eca
.
loadWalk
(
device
,
false
,
wt
))
!=
EB_OK
)
die
(
status
,
"ECA::loadWalk(inactive)"
);
if
((
status
=
eca
.
load
(
false
,
table
))
!=
EB_OK
)
die
(
status
,
"ECA::load(inactive)"
);
rt
.
load
(
st
,
wt
);
if
((
error
=
rt
.
add
(
te
))
>
0
)
{
if
(
table
.
add
(
te
)
>
0
)
{
fprintf
(
stderr
,
"%s: new rule has a tag conflict with existing overlapping rules
\n
"
,
program
);
return
1
;
}
rt
.
compile
(
st
,
wt
);
/* Do the hard work */
if
(
verbose
)
{
printf
(
"Table usage now %d/%d search and %d/%d walk
\n
"
,
(
int
)
st
.
size
(),
(
int
)
eca
.
table_size
*
2
,
(
int
)
wt
.
size
()
,
(
int
)
eca
.
table_size
);
//
printf("Table usage now %d/%d search and %d/%d walk\n",
// searchs, (int)eca.table_size*2, walks
, (int)eca.table_size);
printf
(
"Programming inactive table on ECA #%d
\"
%s
\"
(0x%"
EB_ADDR_FMT
"):
\n
"
,
eca_id
,
eca
.
name
.
c_str
(),
eca
.
address
);
}
if
((
status
=
eca
.
programSearch
(
device
,
st
))
!=
EB_OK
)
die
(
status
,
"ECA::programSearch"
);
if
((
status
=
eca
.
programWalk
(
device
,
wt
))
!=
EB_OK
)
die
(
status
,
"ECA::programWalk"
);
if
((
status
=
eca
.
store
(
table
))
!=
EB_OK
)
die
(
status
,
"ECA::program"
);
}
if
(
!
strcasecmp
(
command
,
"del"
))
{
...
...
@@ -393,30 +377,23 @@ int main(int argc, char** argv) {
eca_id
,
eca
.
name
.
c_str
(),
eca
.
address
);
}
if
((
status
=
eca
.
loadSearch
(
device
,
false
,
st
))
!=
EB_OK
)
die
(
status
,
"ECA::loadSearch(inactive)"
);
if
((
status
=
eca
.
loadWalk
(
device
,
false
,
wt
))
!=
EB_OK
)
die
(
status
,
"ECA::loadWalk(inactive)"
);
if
((
status
=
eca
.
load
(
false
,
table
))
!=
EB_OK
)
die
(
status
,
"ECA::load(inactive)"
);
rt
.
load
(
st
,
wt
);
if
((
error
=
rt
.
remove
(
te
))
==
0
)
{
if
((
error
=
table
.
del
(
te
))
==
0
)
{
fprintf
(
stderr
,
"%s: no rules were removed
\n
"
,
program
);
return
1
;
}
rt
.
compile
(
st
,
wt
);
/* Do the hard work */
if
(
verbose
)
{
printf
(
"Table usage now %d/%d search and %d/%d walk
\n
"
,
(
int
)
st
.
size
(),
(
int
)
eca
.
table_size
*
2
,
(
int
)
wt
.
size
(),
(
int
)
eca
.
table_size
);
//
printf("Table usage now %d/%d search and %d/%d walk\n",
//
(int)st.size(), (int)eca.table_size*2, (int)wt.size(), (int)eca.table_size);
printf
(
"Programming inactive table on ECA #%d
\"
%s
\"
(0x%"
EB_ADDR_FMT
"):
\n
"
,
eca_id
,
eca
.
name
.
c_str
(),
eca
.
address
);
}
if
((
status
=
eca
.
programSearch
(
device
,
st
))
!=
EB_OK
)
die
(
status
,
"ECA::programSearch"
);
if
((
status
=
eca
.
programWalk
(
device
,
wt
))
!=
EB_OK
)
die
(
status
,
"ECA::programWalk"
);
if
((
status
=
eca
.
store
(
table
))
!=
EB_OK
)
die
(
status
,
"ECA::program"
);
}
device
.
close
();
...
...
modules/wr_eca/eca.h
View file @
25e16479
...
...
@@ -28,25 +28,42 @@
#include <etherbone.h>
#include <string>
#include <vector>
#include <map>
namespace
GSI_ECA
{
using
namespace
etherbone
;
typedef
uint64_t
Time
;
typedef
uint64_t
Event
;
typedef
uint32_t
Tag
;
typedef
uint32_t
Param
;
typedef
uint8_t
Channel
;
typedef
uint64_t
Event
;
typedef
int16_t
Index
;
typedef
uint64_t
Param
;
typedef
uint32_t
Tag
;
typedef
uint32_t
Tef
;
typedef
uint64_t
Time
;
struct
ECA
;
/* An Event sent to the ECA has these fields */
struct
EventEntry
{
Event
event
;
Param
param
;
Tef
tef
;
Time
time
;
EventEntry
(
Event
e
=
0
,
Param
p
=
0
,
Tef
t
=
0
,
Time
i
=
0
)
:
event
(
e
),
param
(
p
),
tef
(
t
),
time
(
i
)
{
}
};
/* An action queued to be executed has these fields */
struct
ActionEntry
{
Event
event
;
Time
time
;
Tag
tag
;
Param
param
;
Tag
tag
;
Tef
tef
;
Time
time
;
ActionEntry
(
Event
e
=
0
,
Param
p
=
0
,
Tag
a
=
0
,
Tef
t
=
0
,
Time
i
=
0
)
:
event
(
e
),
param
(
p
),
tag
(
a
),
tef
(
t
),
time
(
i
)
{
}
};
/* Software condition table entry fields */
...
...
@@ -56,52 +73,33 @@ struct TableEntry {
Tag
tag
;
Channel
channel
;
uint8_t
event_bits
;
TableEntry
(
Event
e
=
0
,
Time
o
=
0
,
Tag
t
=
0
,
Channel
c
=
0
,
uint8_t
b
=
0
)
:
event
(
e
),
offset
(
o
),
tag
(
t
),
channel
(
c
),
event_bits
(
b
)
{
}
};
/* Hardware condition search table fields */
struct
SearchEntry
{
Event
event
;
Index
first
;
/* -1 if end-of-list */
};
/* Hardware condition walk table fields */
struct
WalkEntry
{
Time
offset
;
Tag
tag
;
Index
next
;
/* -1 if end-of-list */
Channel
channel
;
};
/* A useful intermediate format for the condition table */
struct
ReverseTable
{
/* Condition table */
class
Table
{
private
:
struct
Impl
;
Impl
*
impl
;
public
:
/* Returns the number of conflicting records overwritten by this new record */
int
add
(
const
TableEntry
&
te
);
int
add
(
Event
begin
,
Event
end
,
Time
,
Channel
,
Tag
);
/* Returns the number of records removed/modified */
int
remove
(
const
TableEntry
&
te
);
/* ignores tag */
int
remove
(
Event
begin
,
Event
end
,
Time
,
Channel
);
Table
();
Table
(
const
Table
&
table
);
~
Table
();
/* Convert it to user-friendly form */
std
::
vector
<
TableEntry
>
reverse
()
const
;
/* Compile it for loading to hardware */
void
compile
(
std
::
vector
<
SearchEntry
>&
s
,
std
::
vector
<
WalkEntry
>&
w
)
const
;
void
swap
(
Table
&
table
);
Table
&
operator
=
(
Table
x
);
/* Bulk load it from user-friendly table; returns count of conflicting records */
int
load
(
const
std
::
vector
<
TableEntry
>&
t
);
/* Bulk load it from hardware tables; returns count of conflicting records */
int
load
(
const
std
::
vector
<
SearchEntry
>&
s
,
const
std
::
vector
<
WalkEntry
>&
w
);
protected
:
struct
EventRange
{
Event
end
;
/* [key, end] */
Tag
tag
;
};
typedef
std
::
map
<
Event
,
EventRange
>
EventFilter
;
typedef
std
::
map
<
Time
,
EventFilter
>
TableActions
;
typedef
std
::
vector
<
TableActions
>
ChannelMap
;
int
add
(
const
TableEntry
&
te
);
/* Returns # records overwritten (conflict) */
int
del
(
const
TableEntry
&
te
);
/* Returns # records removed/modified */
ChannelMap
data
;
/* Bulk import/export of entries */
int
set
(
const
std
::
vector
<
TableEntry
>&
vect
);
void
get
(
std
::
vector
<
TableEntry
>&
vect
)
const
;
friend
struct
ECA
;
};
/* ======================================================================= */
...
...
@@ -111,7 +109,6 @@ struct ActionChannel {
/* ------------------------------------------------------------------- */
/* Constant hardware values */
/* ------------------------------------------------------------------- */
eb_address_t
address
;
/* Wishbone base address of channel */
std
::
string
name
;
/* Channel instance name */
/* ------------------------------------------------------------------- */
...
...
@@ -121,20 +118,27 @@ struct ActionChannel {
bool
frozen
;
/* Queue is frozen; nothing enters/exits */
uint16_t
fill
;
/* Current number of entries in the queue */
uint16_t
max_fill
;
/* Maximum entries in the queue since reset */
uint32_t
valid
;
/* How many valid actions have been sent */
uint32_t
late
;
/* How many late actions have been sent */
/* ------------------------------------------------------------------- */
/* Access/modify the underlying hardware */
/* ------------------------------------------------------------------- */
ECA
*
eca
;;
/* ECA which contains this channel */
Channel
index
;
/* Index of the channel */
/* Reload drain, freeze, fill, max_fill from hardware. */
status_t
refresh
(
Device
dev
);
status_t
refresh
();
/* Clear all counters (max_fill, valid, late) */
status_t
reset
();
/* Toggle queue states */
status_t
freeze
(
Device
dev
,
bool
freeze
);
status_t
drain
(
Device
dev
,
bool
drain
);
status_t
freeze
(
bool
freeze
);
status_t
drain
(
bool
drain
);
/*
Clear the queue max_fill counter back to fil
l */
status_t
reset
(
Device
dev
);
/*
Grab the contents from a frozen channe
l */
status_t
load
(
std
::
vector
<
ActionEntry
>&
queue
);
};
/* ======================================================================= */
...
...
@@ -144,8 +148,6 @@ struct EventStream {
/* ------------------------------------------------------------------- */
/* Constant hardware values */
/* ------------------------------------------------------------------- */
eb_address_t
address
;
uint8_t
sdb_ver_major
;
uint8_t
sdb_ver_minor
;
uint32_t
sdb_version
;
...
...
@@ -156,8 +158,11 @@ struct EventStream {
/* Access/modify the underlying hardware */
/* ------------------------------------------------------------------- */
ECA
*
eca
;
/* Device with this event stream */
eb_address_t
address
;
/* Base address of the event stream */
/* Send an event to the stream */
status_t
send
(
Device
dev
,
Event
event
,
Time
time
,
Param
param
);
status_t
send
(
EventEntry
e
);
};
/* ======================================================================= */
...
...
@@ -168,7 +173,6 @@ struct ECA {
/* Constant hardware values */
/* ------------------------------------------------------------------- */
eb_address_t
address
;
/* Wishbone base address */
std
::
string
name
;
/* ECA instance name */
uint8_t
sdb_ver_major
;
/* API version; major.minor */
...
...
@@ -195,7 +199,7 @@ struct ECA {
/* Mutable hardware registers; only modify using methods below */
/* ------------------------------------------------------------------- */
Time
time
;
/* Time as of the last refresh */
Time
time
;
/* Time as of the last refresh */
bool
disabled
;
/* When disabled, incoming events are dropped */
/* ------------------------------------------------------------------- */
...
...
@@ -222,24 +226,39 @@ struct ECA {
/* Access/modify the underlying hardware */
/* ------------------------------------------------------------------- */
status_t
refresh
(
Device
dev
);
/* refresh time+disabled */
Device
device
;
/* Device which hosts this ECA */
eb_address_t
address
;
/* Wishbone base address */
unsigned
index
;
/* Index of the ECA */
status_t
disable
(
Device
dev
,
bool
disabled
);
/* Enable/disable the ECA unit */
status_t
flipTables
(
Device
dev
);
/* Atomicly flip inactive and active tables */
status_t
refresh
();
/* refresh time+disabled */
/* Load the H/W representation of the tables */
status_t
loadQueue
(
Device
dev
,
unsigned
channel
,
std
::
vector
<
ActionEntry
>&
queue
);
status_t
loadSearch
(
Device
dev
,
bool
active
,
std
::
vector
<
SearchEntry
>&
table
);
status_t
loadWalk
(
Device
dev
,
bool
active
,
std
::
vector
<
WalkEntry
>&
table
);
status_t
disable
(
bool
disabled
);
/* Enable/disable the ECA unit */
status_t
flipTables
();
/* Atomicly flip inactive and active tables */
/*
Program the INACTIVE
table */
status_t
programSearch
(
Device
dev
,
const
std
::
vector
<
SearchEntry
>
&
table
);
status_t
programWalk
(
Device
dev
,
const
std
::
vector
<
WalkEntry
>&
table
);
/*
Load/store the condition
table */
status_t
load
(
bool
active
,
Table
&
table
);
status_t
store
(
const
Table
&
table
);
/* Locate all the ECA units on the bus */
static
status_t
load
(
Device
dev
,
std
::
vector
<
ECA
>&
ecas
);
static
status_t
probe
(
Device
dev
,
std
::
vector
<
ECA
>&
ecas
);
};
/* ======================================================================= */
/* Inline functions that are not part of the ABI */
/* ======================================================================= */
inline
void
Table
::
swap
(
Table
&
table
)
{
Impl
*
tmp
=
impl
;
impl
=
table
.
impl
;
table
.
impl
=
tmp
;
}
inline
Table
&
Table
::
operator
=
(
Table
x
)
{
swap
(
x
);
return
*
this
;
}
}
#endif
modules/wr_eca/eca.vhd
View file @
25e16479
...
...
@@ -11,7 +11,11 @@
--! 0x00 RW: ECA Control
--! 0x00 : 0x01 = disable, 0x2 = flip, 0x80=inspect_table, 0x40=inspect_queue
--! 0x01 : ASCII ECA Name
--! 0x04 RW: Table size, Q depth, channels, IDX
--! 0x04 RW: ECA params
--! 0x04 : log(table size)
--! 0x05 : log(queue depth)
--! 0x06 : number of channels
--! 0x07 : index of ECA
--! 0x08 R : Time1
--! 0x0C R : Time0
--! 0x10 RW: Search index
...
...
@@ -35,7 +39,7 @@
--! 0x48 -- reserved --
--!
--! 0x4C RW: Select
--! 0x0
1
: Channel #
--! 0x0
0-01
: Channel #
--! 0x02-03 : Buffer Index
--! 0x50 RW: Channel Control
--! 0x00 : 0x01 = disable, 0x02 = freeze, 0x40 = late, 0x80 = valid
...
...
@@ -43,7 +47,7 @@
--! 0x54 RW: Fill
--! 0x00-01 : Current Queue fill
--! 0x02-03 : Max fill (can be cleared to 0)
--! 0x58 RW:
Total
actions counter
--! 0x58 RW:
Valid
actions counter
--! 0x5C RW: Late actions counter
--!
--! 0x60 R : Event1 ... do NOT synchronize; hold index long enough
...
...
@@ -52,8 +56,8 @@
--! 0x6C R : Param0
--! 0x70 R : Tag
--! 0x74 R : Tef
--! 0x78 R : Time
0
--! 0x7C R : Time
1
--! 0x78 R : Time
1
--! 0x7C R : Time
0
--!
--------------------------------------------------------------------------------
--! This library is free software; you can redistribute it and/or
...
...
modules/wr_eca/lib/hw-channel.cpp
View file @
25e16479
...
...
@@ -28,97 +28,159 @@
#include <stdio.h>
#include <assert.h>
#include <algorithm>
#include "eca.h"
#include "hw-eca.h"
namespace
GSI_ECA
{
status_t
ActionChannel
::
refresh
(
Device
dev
)
{
status_t
ActionChannel
::
refresh
()
{
Cycle
cycle
;
eb_status_t
status
;
eb_address_t
address
;
eb_data_t
ctl
;
eb_data_t
fill
;
int
done
;
eb_data_t
d_fill
;
eb_data_t
d_valid
;
eb_data_t
d_late
;
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
if
((
status
=
cycle
.
open
(
eca
->
device
))
!=
EB_OK
)
return
status
;
cycle
.
read
(
address
+
ECAQ_CTL
,
EB_DATA32
,
&
ctl
);
cycle
.
read
(
address
+
ECAQ_FILL
,
EB_DATA32
,
&
fill
);
cycle
.
close
();
address
=
eca
->
address
;
cycle
.
write
(
address
+
ECAQ_SELECT
,
EB_DATA32
,
index
<<
16
);
cycle
.
read
(
address
+
ECAQ_CTL
,
EB_DATA32
,
&
ctl
);
cycle
.
read
(
address
+
ECAQ_FILL
,
EB_DATA32
,
&
d_fill
);
cycle
.
read
(
address
+
ECAQ_VALID
,
EB_DATA32
,
&
d_valid
);
cycle
.
read
(
address
+
ECAQ_LATE
,
EB_DATA32
,
&
d_late
);
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
if
((
status
=
cycle
.
close
())
!=
EB_OK
)
return
status
;
draining
=
((
ctl
>>
24
)
&
0x01
)
!=
0
;
frozen
=
((
ctl
>>
24
)
&
0x02
)
!=
0
;
fill
=
(
fill
>>
16
)
&
0xFFFF
;
max_fill
=
(
fill
>>
0
)
&
0xFFFF
;
fill
=
(
d_fill
>>
16
)
&
0xFFFF
;
max_fill
=
(
d_fill
>>
0
)
&
0xFFFF
;
valid
=
d_valid
&
0xFFFFFFFF
;
late
=
d_late
&
0xFFFFFFFF
;
return
EB_OK
;
}
status_t
ActionChannel
::
freeze
(
Device
dev
,
bool
freeze
)
{
status_t
ActionChannel
::
freeze
(
bool
freeze
)
{
Cycle
cycle
;
eb_status_t
status
;
eb_address_t
address
;
eb_data_t
ctl
;
int
done
;
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
if
((
status
=
cycle
.
open
(
eca
->
device
))
!=
EB_OK
)
return
status
;
address
=
eca
->
address
;
ctl
=
(
draining
?
0x1
:
0
)
|
(
freeze
?
0x2
:
0
);
cycle
.
write
(
address
+
ECAQ_SELECT
,
EB_DATA16
|
EB_BIG_ENDIAN
,
index
);
cycle
.
write
(
address
+
ECAQ_CTL
,
EB_DATA8
|
EB_BIG_ENDIAN
,
ctl
);
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
if
((
status
=
cycle
.
close
())
!=
EB_OK
)
return
status
;
frozen
=
freeze
;
return
EB_OK
;
}
status_t
ActionChannel
::
drain
(
Device
dev
,
bool
drain
)
{
status_t
ActionChannel
::
drain
(
bool
drain
)
{
Cycle
cycle
;
eb_address_t
address
;
eb_status_t
status
;
eb_data_t
ctl
;
int
done
;
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
if
((
status
=
cycle
.
open
(
eca
->
device
))
!=
EB_OK
)
return
status
;
address
=
eca
->
address
;
ctl
=
(
drain
?
0x1
:
0
)
|
(
frozen
?
0x2
:
0
);
cycle
.
write
(
address
+
ECAQ_SELECT
,
EB_DATA16
|
EB_BIG_ENDIAN
,
index
);
cycle
.
write
(
address
+
ECAQ_CTL
,
EB_DATA8
|
EB_BIG_ENDIAN
,
ctl
);
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
if
((
status
=
cycle
.
close
())
!=
EB_OK
)
return
status
;
draining
=
drain
;
return
EB_OK
;
}
status_t
ActionChannel
::
reset
(
Device
dev
)
{
status_t
ActionChannel
::
reset
()
{
Cycle
cycle
;
eb_address_t
address
;
eb_status_t
status
;
int
done
;
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
if
((
status
=
cycle
.
open
(
eca
->
device
))
!=
EB_OK
)
return
status
;
cycle
.
write
(
address
+
ECAQ_MAX_FILL
,
EB_DATA16
|
EB_BIG_ENDIAN
,
0
);
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
address
=
eca
->
address
;
cycle
.
write
(
address
+
ECAQ_SELECT
,
EB_DATA16
|
EB_BIG_ENDIAN
,
index
);
cycle
.
write
(
address
+
ECAQ_FILL
,
EB_DATA32
|
EB_BIG_ENDIAN
,
0
);
cycle
.
write
(
address
+
ECAQ_VALID
,
EB_DATA32
|
EB_BIG_ENDIAN
,
0
);
cycle
.
write
(
address
+
ECAQ_LATE
,
EB_DATA32
|
EB_BIG_ENDIAN
,
0
);
return
cycle
.
close
();
}
static
bool
sort_time
(
ActionEntry
a
,
ActionEntry
b
)
{
return
(
a
.
time
<
b
.
time
);
}
status_t
ActionChannel
::
load
(
std
::
vector
<
ActionEntry
>&
table
)
{
Cycle
cycle
;
eb_address_t
address
;
eb_status_t
status
;
eb_data_t
ctl
;
eb_data_t
event1
,
event0
;
eb_data_t
param1
,
param0
;
eb_data_t
tag
,
tef
;
eb_data_t
time1
,
time0
;
table
.
clear
();
/* Can only probe if inspect_queue is true */
if
(
!
eca
->
inspect_queue
)
return
EB_OK
;
/* If the queue is not frozen, it won't work */
if
(
!
frozen
)
return
EB_FAIL
;
address
=
eca
->
address
;
for
(
unsigned
i
=
0
;
i
<
eca
->
queue_size
;
++
i
)
{
if
((
status
=
cycle
.
open
(
eca
->
device
))
!=
EB_OK
)
return
status
;
cycle
.
write
(
address
+
ECAQ_SELECT
,
EB_DATA32
|
EB_BIG_ENDIAN
,
(
index
<<
16
)
|
i
);
cycle
.
read
(
address
+
ECAQ_CTL
,
EB_DATA32
,
&
ctl
);
cycle
.
read
(
address
+
ECAQ_EVENT1
,
EB_DATA32
,
&
event1
);
cycle
.
read
(
address
+
ECAQ_EVENT0
,
EB_DATA32
,
&
event0
);
cycle
.
read
(
address
+
ECAQ_PARAM1
,
EB_DATA32
,
&
param1
);
cycle
.
read
(
address
+
ECAQ_PARAM0
,
EB_DATA32
,
&
param0
);
cycle
.
read
(
address
+
ECAQ_TAG
,
EB_DATA32
,
&
tag
);
cycle
.
read
(
address
+
ECAQ_TEF
,
EB_DATA32
,
&
tef
);
cycle
.
read
(
address
+
ECAQ_TIME1
,
EB_DATA32
,
&
time1
);
cycle
.
read
(
address
+
ECAQ_TIME0
,
EB_DATA32
,
&
time0
);
if
((
status
=
cycle
.
close
())
!=
EB_OK
)
return
status
;
/* Is the record invalid? */
if
(((
ctl
>>
24
)
&
0x80
)
==
0
)
continue
;
ActionEntry
ae
;
ae
.
event
=
event1
;
ae
.
event
<<=
32
;
ae
.
event
+=
event0
;
ae
.
param
=
param1
;
ae
.
param
<<=
32
;
ae
.
param
+=
param0
;
ae
.
tag
=
tag
;
ae
.
tef
=
tef
;
ae
.
time
=
time1
;
ae
.
time
<<=
32
;
ae
.
time
+=
time0
;
table
.
push_back
(
ae
);
}
std
::
sort
(
table
.
begin
(),
table
.
end
(),
sort_time
);
return
EB_OK
;
}
...
...
modules/wr_eca/lib/hw-eca.cpp
View file @
25e16479
...
...
@@ -166,25 +166,20 @@ double ECA::delay(uint64_t seconds) const {
return
out
;
}
status_t
ECA
::
refresh
(
Device
dev
)
{
status_t
ECA
::
refresh
()
{
Cycle
cycle
;
eb_status_t
status
;
eb_data_t
control
;
eb_data_t
time1
,
time0
;
int
done
;
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
if
((
status
=
cycle
.
open
(
dev
ice
))
!=
EB_OK
)
return
status
;
cycle
.
read
(
address
+
ECA_CTL
,
EB_DATA32
,
&
control
);
cycle
.
read
(
address
+
ECA_TIME1
,
EB_DATA32
,
&
time1
);
cycle
.
read
(
address
+
ECA_TIME0
,
EB_DATA32
,
&
time0
);
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
if
((
status
=
cycle
.
close
())
!=
EB_OK
)
return
status
;
time
=
time1
;
time
<<=
32
;
...
...
@@ -194,47 +189,19 @@ status_t ECA::refresh(Device dev) {
return
EB_OK
;
}
status_t
ECA
::
disable
(
Device
dev
,
bool
d
)
{
Cycle
cycle
;
eb_data_t
data
;
status_t
ECA
::
disable
(
bool
d
)
{
eb_status_t
status
;
int
done
;
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
return
status
;
data
=
d
?
1
:
0
;
cycle
.
write
(
address
+
ECA_CTL
,
EB_DATA8
|
EB_BIG_ENDIAN
,
data
);
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
status
=
device
.
write
(
address
+
ECA_CTL
,
EB_DATA8
|
EB_BIG_ENDIAN
,
d
?
1
:
0
);
if
(
status
!=
EB_OK
)
return
status
;
disabled
=
d
;
return
EB_OK
;
}
status_t
ECA
::
flipTables
(
Device
dev
)
{
Cycle
cycle
;
eb_data_t
data
;
eb_status_t
status
;
int
done
;
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
return
status
;
data
=
2
;
cycle
.
write
(
address
+
ECA_CTL
,
EB_DATA8
|
EB_BIG_ENDIAN
,
data
);
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
return
EB_OK
;
status_t
ECA
::
flipTables
()
{
return
device
.
write
(
address
+
ECA_CTL
,
EB_DATA8
|
EB_BIG_ENDIAN
,
2
);
}
}
modules/wr_eca/lib/hw-eca.h
View file @
25e16479
...
...
@@ -26,6 +26,7 @@
#define ECA_HW_H
#include <etherbone.h>
#include <map>
#define GSI_VENDOR_ID 0x651
#define ECA_DEVICE_ID 0x8752bf44U
...
...
@@ -54,23 +55,74 @@
#define ECA_FREQ_5S 0x3C
#define ECA_FREQ_2S 0x3D
#define ECA_FREQ_DIV 0x3E
#define ECA_END 0x40
#define ECAQ_CTL 0x00
#define ECAQ_NAME 0x01
#define ECAQ_INDEX 0x02
#define ECAQ_FILL 0x04
#define ECAQ_MAX_FILL 0x06
#define ECAQ_TIME1 0x08
#define ECAQ_TIME0 0x0C
#define ECAQ_EVENT1 0x10
#define ECAQ_EVENT0 0x14
#define ECAQ_TAG 0x18
#define ECAQ_PARAM 0x1C
#define ECAQ_END 0x20
#define ECAQ_SELECT 0x4C
#define ECAQ_CHANNEL 0x4C
#define ECAQ_INDEX 0x4E
#define ECAQ_CTL 0x50
#define ECAQ_NAME 0x51
#define ECAQ_FILL 0x54
#define ECAQ_MAX_FILL 0x56
#define ECAQ_VALID 0x58
#define ECAQ_LATE 0x5C
#define ECAQ_EVENT1 0x60
#define ECAQ_EVENT0 0x64
#define ECAQ_PARAM1 0x68
#define ECAQ_PARAM0 0x6C
#define ECAQ_TAG 0x70
#define ECAQ_TEF 0x74
#define ECAQ_TIME1 0x78
#define ECAQ_TIME0 0x7C
namespace
GSI_ECA
{
extern
void
eca_cycle_done
(
int
*
done
,
etherbone
::
Device
dev
,
etherbone
::
Operation
op
,
eb_status_t
status
);
/* Hardware condition search table fields */
struct
SearchEntry
{
Event
event
;
Index
first
;
/* -1 if end-of-list */
};
/* Hardware condition walk table fields */
struct
WalkEntry
{
Time
offset
;
Tag
tag
;
Index
next
;
/* -1 if end-of-list */
Channel
channel
;
};
/* A useful intermediate format for the condition table */
struct
Table
::
Impl
{
public
:
/* Returns the number of conflicting records overwritten by this new record */
int
add
(
const
TableEntry
&
te
);
int
add
(
Event
begin
,
Event
end
,
Time
,
Channel
,
Tag
);
/* Returns the number of records removed/modified */
int
remove
(
const
TableEntry
&
te
);
/* ignores tag */
int
remove
(
Event
begin
,
Event
end
,
Time
,
Channel
);
/* Convert it to user-friendly form */
void
get
(
std
::
vector
<
TableEntry
>&
te
)
const
;
/* Bulk load it from user-friendly table; returns count of conflicting records */
int
set
(
const
std
::
vector
<
TableEntry
>&
t
);
/* Bulk load it from hardware tables; returns count of conflicting records */
int
decompile
(
const
std
::
vector
<
SearchEntry
>&
s
,
const
std
::
vector
<
WalkEntry
>&
w
);
/* Compile it for loading to hardware */
void
compile
(
std
::
vector
<
SearchEntry
>&
s
,
std
::
vector
<
WalkEntry
>&
w
)
const
;
protected
:
struct
EventRange
{
Event
end
;
/* [key, end] */
Tag
tag
;
};
typedef
std
::
map
<
Event
,
EventRange
>
EventFilter
;
typedef
std
::
map
<
Time
,
EventFilter
>
TableActions
;
typedef
std
::
vector
<
TableActions
>
ChannelMap
;
ChannelMap
data
;
};
}
#endif
modules/wr_eca/lib/hw-stream.cpp
View file @
25e16479
...
...
@@ -33,27 +33,23 @@
namespace
GSI_ECA
{
status_t
EventStream
::
send
(
Device
dev
,
Event
event
,
Time
time
,
Param
param
)
{
status_t
EventStream
::
send
(
EventEntry
e
)
{
Cycle
cycle
;
eb_status_t
status
;
int
done
;
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
if
((
status
=
cycle
.
open
(
eca
->
device
))
!=
EB_OK
)
return
status
;
cycle
.
write
(
address
,
EB_DATA32
,
event
>>
32
);
cycle
.
write
(
address
,
EB_DATA32
,
event
&
UINT32_C
(
0xFFFFFFFF
));
cycle
.
write
(
address
,
EB_DATA32
,
time
>>
32
);
cycle
.
write
(
address
,
EB_DATA32
,
time
&
UINT32_C
(
0xFFFFFFFF
));
cycle
.
write
(
address
,
EB_DATA32
,
param
);
cycle
.
close
();
cycle
.
write
(
address
,
EB_DATA32
,
e
.
event
>>
32
);
cycle
.
write
(
address
,
EB_DATA32
,
e
.
event
&
UINT32_C
(
0xFFFFFFFF
));
cycle
.
write
(
address
,
EB_DATA32
,
e
.
param
>>
32
);
cycle
.
write
(
address
,
EB_DATA32
,
e
.
param
&
UINT32_C
(
0xFFFFFFFF
));
cycle
.
write
(
address
,
EB_DATA32
,
0
);
// reserved
cycle
.
write
(
address
,
EB_DATA32
,
e
.
tef
&
UINT32_C
(
0xFFFFFFFF
));
cycle
.
write
(
address
,
EB_DATA32
,
e
.
time
>>
32
);
cycle
.
write
(
address
,
EB_DATA32
,
e
.
time
&
UINT32_C
(
0xFFFFFFFF
));
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
return
EB_OK
;
return
cycle
.
close
();
}
}
modules/wr_eca/lib/load-queue.cpp
deleted
100644 → 0
View file @
007b38c9
/** @file load-queue.cpp
* @brief Load the contents of a queue
* @author Wesley W. Terpstra <w.terpstra@gsi.de>
*
* Copyright (C) 2013 GSI Helmholtz Centre for Heavy Ion Research GmbH
*
* Retrieve the actions queued in a channel.
*
*******************************************************************************
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************
*/
#define __STDC_FORMAT_MACROS
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#include <stdio.h>
#include <assert.h>
#include <algorithm>
#include "eca.h"
#include "hw-eca.h"
namespace
GSI_ECA
{
static
bool
sort_time
(
ActionEntry
a
,
ActionEntry
b
)
{
return
(
a
.
time
<
b
.
time
);
}
status_t
ECA
::
loadQueue
(
Device
dev
,
unsigned
channel
,
std
::
vector
<
ActionEntry
>&
table
)
{
Cycle
cycle
;
eb_status_t
status
;
eb_address_t
base
;
eb_data_t
ctl
;
eb_data_t
time1
,
time0
;
eb_data_t
event1
,
event0
;
eb_data_t
tag
,
param
;
int
done
;
table
.
clear
();
/* Can only probe if inspect_queue is true */
if
(
!
inspect_queue
)
return
EB_OK
;
/* If the queue is not frozen, it won't work */
if
(
channel
>=
channels
.
size
()
||
!
channels
[
channel
].
frozen
)
return
EB_FAIL
;
base
=
channels
[
channel
].
address
;
for
(
unsigned
i
=
0
;
i
<
queue_size
;
++
i
)
{
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
return
status
;
cycle
.
write
(
base
+
ECAQ_INDEX
,
EB_DATA16
|
EB_BIG_ENDIAN
,
i
);
cycle
.
read
(
base
+
ECAQ_CTL
,
EB_DATA32
,
&
ctl
);
cycle
.
read
(
base
+
ECAQ_TIME1
,
EB_DATA32
,
&
time1
);
cycle
.
read
(
base
+
ECAQ_TIME0
,
EB_DATA32
,
&
time0
);
cycle
.
read
(
base
+
ECAQ_EVENT1
,
EB_DATA32
,
&
event1
);
cycle
.
read
(
base
+
ECAQ_EVENT0
,
EB_DATA32
,
&
event0
);
cycle
.
read
(
base
+
ECAQ_TAG
,
EB_DATA32
,
&
tag
);
cycle
.
read
(
base
+
ECAQ_PARAM
,
EB_DATA32
,
&
param
);
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
/* Is the record invalid? */
if
(((
ctl
>>
24
)
&
0x80
)
==
0
)
continue
;
ActionEntry
ae
;
ae
.
time
=
time1
;
ae
.
time
<<=
32
;
ae
.
time
+=
time0
;
ae
.
event
=
event1
;
ae
.
event
<<=
32
;
ae
.
event
+=
event0
;
ae
.
tag
=
tag
;
ae
.
param
=
param
;
table
.
push_back
(
ae
);
}
std
::
sort
(
table
.
begin
(),
table
.
end
(),
sort_time
);
return
EB_OK
;
}
}
modules/wr_eca/lib/load-search.cpp
deleted
100644 → 0
View file @
007b38c9
/** @file load-search.cpp
* @brief Load the search table
* @author Wesley W. Terpstra <w.terpstra@gsi.de>
*
* Copyright (C) 2013 GSI Helmholtz Centre for Heavy Ion Research GmbH
*
* Grab the contents of the search component of the condition table.
*
*******************************************************************************
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************
*/
#define __STDC_FORMAT_MACROS
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#include <stdio.h>
#include <assert.h>
#include "eca.h"
#include "hw-eca.h"
namespace
GSI_ECA
{
status_t
ECA
::
loadSearch
(
Device
dev
,
bool
active
,
std
::
vector
<
SearchEntry
>&
table
)
{
Cycle
cycle
;
eb_status_t
status
;
eb_data_t
index
,
first
;
eb_data_t
event1
,
event0
;
int
done
;
if
(
!
inspect_table
)
{
table
.
clear
();
return
EB_OK
;
}
table
.
resize
(
table_size
*
2
);
/* Two entries for every table entry */
for
(
unsigned
i
=
0
;
i
<
table
.
size
();
++
i
)
{
SearchEntry
&
se
=
table
[
i
];
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
return
status
;
index
=
(
active
?
0x80000000UL
:
0
)
+
i
;
cycle
.
write
(
address
+
ECA_SEARCH
,
EB_DATA32
,
index
);
cycle
.
read
(
address
+
ECA_FIRST
,
EB_DATA32
,
&
first
);
cycle
.
read
(
address
+
ECA_EVENT1
,
EB_DATA32
,
&
event1
);
cycle
.
read
(
address
+
ECA_EVENT0
,
EB_DATA32
,
&
event0
);
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
se
.
event
=
event1
;
se
.
event
<<=
32
;
se
.
event
|=
event0
;
if
((
first
>>
31
)
!=
0
)
{
se
.
first
=
first
&
0x7FFF
;
}
else
{
se
.
first
=
-
1
;
}
}
return
EB_OK
;
}
}
\ No newline at end of file
modules/wr_eca/lib/load-
walk
.cpp
→
modules/wr_eca/lib/load-
table
.cpp
View file @
25e16479
/** @file load-
walk
.cpp
* @brief Load the
walk
table
/** @file load-
table
.cpp
* @brief Load the
condition
table
* @author Wesley W. Terpstra <w.terpstra@gsi.de>
*
* Copyright (C) 2013 GSI Helmholtz Centre for Heavy Ion Research GmbH
*
* Grab the contents of the
walker component of the condition table
.
* Grab the contents of the
condition table from the ECA
.
*
*******************************************************************************
* This library is free software; you can redistribute it and/or
...
...
@@ -33,25 +33,69 @@
namespace
GSI_ECA
{
stat
us_t
ECA
::
loadWalk
(
Device
dev
,
bool
active
,
std
::
vector
<
Walk
Entry
>&
table
)
{
stat
ic
status_t
loadSearch
(
ECA
*
eca
,
bool
active
,
std
::
vector
<
Search
Entry
>&
table
)
{
Cycle
cycle
;
eb_address_t
address
;
eb_status_t
status
;
eb_data_t
index
,
first
;
eb_data_t
event1
,
event0
;
if
(
!
eca
->
inspect_table
)
{
table
.
clear
();
return
EB_OK
;
}
table
.
resize
(
eca
->
table_size
*
2
);
/* Two entries for every table entry */
address
=
eca
->
address
;
for
(
unsigned
i
=
0
;
i
<
table
.
size
();
++
i
)
{
SearchEntry
&
se
=
table
[
i
];
if
((
status
=
cycle
.
open
(
eca
->
device
))
!=
EB_OK
)
return
status
;
index
=
(
active
?
0x80000000UL
:
0
)
+
i
;
cycle
.
write
(
address
+
ECA_SEARCH
,
EB_DATA32
,
index
);
cycle
.
read
(
address
+
ECA_FIRST
,
EB_DATA32
,
&
first
);
cycle
.
read
(
address
+
ECA_EVENT1
,
EB_DATA32
,
&
event1
);
cycle
.
read
(
address
+
ECA_EVENT0
,
EB_DATA32
,
&
event0
);
if
((
status
=
cycle
.
close
())
!=
EB_OK
)
return
status
;
se
.
event
=
event1
;
se
.
event
<<=
32
;
se
.
event
|=
event0
;
if
((
first
>>
31
)
!=
0
)
{
se
.
first
=
first
&
0x7FFF
;
}
else
{
se
.
first
=
-
1
;
}
}
return
EB_OK
;
}
static
status_t
loadWalk
(
ECA
*
eca
,
bool
active
,
std
::
vector
<
WalkEntry
>&
table
)
{
Cycle
cycle
;
eb_address_t
address
;
eb_status_t
status
;
eb_data_t
index
,
next
;
eb_data_t
delay1
,
delay0
;
eb_data_t
tag
,
channel
;
int
done
;
if
(
!
inspect_table
)
{
if
(
!
eca
->
inspect_table
)
{
table
.
clear
();
return
EB_OK
;
}
table
.
resize
(
table_size
);
table
.
resize
(
eca
->
table_size
);
address
=
eca
->
address
;
for
(
unsigned
i
=
0
;
i
<
table
.
size
();
++
i
)
{
WalkEntry
&
we
=
table
[
i
];
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
if
((
status
=
cycle
.
open
(
eca
->
device
))
!=
EB_OK
)
return
status
;
index
=
(
active
?
0x80000000UL
:
0
)
+
i
;
...
...
@@ -61,12 +105,9 @@ status_t ECA::loadWalk(Device dev, bool active, std::vector<WalkEntry>& table) {
cycle
.
read
(
address
+
ECA_DELAY0
,
EB_DATA32
,
&
delay0
);
cycle
.
read
(
address
+
ECA_TAG
,
EB_DATA32
,
&
tag
);
cycle
.
read
(
address
+
ECA_CHANNEL
,
EB_DATA32
,
&
channel
);
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
if
((
status
=
cycle
.
close
())
!=
EB_OK
)
return
status
;
we
.
offset
=
delay1
;
we
.
offset
<<=
32
;
...
...
@@ -84,4 +125,21 @@ status_t ECA::loadWalk(Device dev, bool active, std::vector<WalkEntry>& table) {
return
EB_OK
;
}
status_t
ECA
::
load
(
bool
active
,
Table
&
table
)
{
status_t
status
;
std
::
vector
<
SearchEntry
>
se
;
std
::
vector
<
WalkEntry
>
we
;
if
((
status
=
loadSearch
(
this
,
active
,
se
))
!=
EB_OK
)
return
status
;
if
((
status
=
loadWalk
(
this
,
active
,
we
))
!=
EB_OK
)
return
status
;
if
(
table
.
impl
->
decompile
(
se
,
we
)
>
0
)
return
EB_FAIL
;
return
EB_OK
;
}
}
modules/wr_eca/lib/
load
-eca.cpp
→
modules/wr_eca/lib/
probe
-eca.cpp
View file @
25e16479
...
...
@@ -104,22 +104,6 @@ void eca_sdb_search(SearchRecord* record, Device dev, const struct sdb_table* sd
record
->
done
=
1
;
}
void
eca_cycle_done
(
int
*
done
,
Device
dev
,
Operation
op
,
eb_status_t
status
)
{
if
(
status
==
EB_OK
)
{
*
done
=
1
;
for
(;
!
op
.
is_null
();
op
=
op
.
next
())
{
if
(
op
.
had_error
())
{
*
done
=
2
;
fprintf
(
stderr
,
"Wishbone segfault %s address %"
EB_ADDR_FMT
"
\n
"
,
op
.
is_read
()
?
"reading"
:
"writing"
,
op
.
address
());
}
}
}
else
{
fprintf
(
stderr
,
"Etherbone error: %s
\n
"
,
eb_status
(
status
));
*
done
=
status
;
}
}
std
::
string
eca_extract_name
(
eb_data_t
*
data
)
{
char
name8
[
64
];
...
...
@@ -143,17 +127,17 @@ std::string eca_extract_name(eb_data_t* data) {
}
status_t
ECA
::
load
(
Device
dev
,
std
::
vector
<
ECA
>&
ecas
)
{
status_t
ECA
::
probe
(
Device
device
,
std
::
vector
<
ECA
>&
ecas
)
{
/* Phase 1 -- locate ECA units using SDB */
SearchRecord
record
;
record
.
ecas
=
&
ecas
;
dev
.
sdb_scan_root
(
&
record
,
sdb_wrap_function_callback
<
SearchRecord
,
eca_sdb_search
>
);
dev
ice
.
sdb_scan_root
(
&
record
,
sdb_wrap_function_callback
<
SearchRecord
,
eca_sdb_search
>
);
record
.
done
=
0
;
record
.
status
=
EB_OK
;
while
(
!
record
.
done
)
dev
.
socket
().
run
();
while
(
!
record
.
done
)
dev
ice
.
socket
().
run
();
if
(
record
.
status
!=
EB_OK
)
return
record
.
status
;
/* Phase 2a -- Read ECA parameters */
...
...
@@ -163,16 +147,19 @@ status_t ECA::load(Device dev, std::vector<ECA>& ecas) {
eb_data_t
time1
,
time0
;
eb_data_t
freq1
,
freq0
;
eb_data_t
fill
;
eb_data_t
valid
;
eb_data_t
late
;
eb_data_t
id
;
Cycle
cycle
;
int
done
;
for
(
unsigned
i
=
0
;
i
<
ecas
.
size
();
++
i
)
{
ECA
&
eca
=
ecas
[
i
];
unsigned
num_channels
;
eca
.
index
=
i
;
eca
.
device
=
device
;
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
if
((
status
=
cycle
.
open
(
dev
ice
))
!=
EB_OK
)
return
status
;
for
(
unsigned
j
=
0
;
j
<
64
;
++
j
)
...
...
@@ -184,12 +171,9 @@ status_t ECA::load(Device dev, std::vector<ECA>& ecas) {
cycle
.
read
(
eca
.
address
+
ECA_FREQ_MUL
,
EB_DATA32
,
&
freq1
);
cycle
.
read
(
eca
.
address
+
ECA_FREQ_5S
,
EB_DATA32
,
&
freq0
);
cycle
.
write
(
eca
.
address
+
ECA_INDEX
,
EB_BIG_ENDIAN
|
EB_DATA8
,
i
);
/* set index for matching streams */
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
if
((
status
=
cycle
.
close
())
!=
EB_OK
)
return
status
;
eca
.
name
=
eca_extract_name
(
name
);
...
...
@@ -213,26 +197,29 @@ status_t ECA::load(Device dev, std::vector<ECA>& ecas) {
/* Phase 2b -- Read Channel parameters + names */
for
(
unsigned
c
=
0
;
c
<
num_channels
;
++
c
)
{
ActionChannel
ac
;
ac
.
address
=
eca
.
address
+
ECA_END
+
c
*
ECAQ_END
;
ac
.
eca
=
&
eca
;
ac
.
index
=
c
;
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
if
((
status
=
cycle
.
open
(
dev
ice
))
!=
EB_OK
)
return
status
;
cycle
.
write
(
eca
.
address
+
ECAQ_SELECT
,
EB_DATA32
,
c
<<
16
);
for
(
unsigned
j
=
0
;
j
<
64
;
++
j
)
cycle
.
read
(
ac
.
address
+
ECAQ_CTL
,
EB_DATA32
,
&
name
[
j
]);
cycle
.
read
(
ac
.
address
+
ECAQ_FILL
,
EB_DATA32
,
&
fill
);
cycle
.
close
();
cycle
.
read
(
eca
.
address
+
ECAQ_CTL
,
EB_DATA32
,
&
name
[
j
]);
cycle
.
read
(
eca
.
address
+
ECAQ_FILL
,
EB_DATA32
,
&
fill
);
cycle
.
read
(
eca
.
address
+
ECAQ_VALID
,
EB_DATA32
,
&
valid
);
cycle
.
read
(
eca
.
address
+
ECAQ_LATE
,
EB_DATA32
,
&
late
);
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
if
((
status
=
cycle
.
close
())
!=
EB_OK
)
return
status
;
ac
.
name
=
eca_extract_name
(
name
);
ac
.
draining
=
((
name
[
0
]
>>
24
)
&
0x01
)
!=
0
;
ac
.
frozen
=
((
name
[
0
]
>>
24
)
&
0x02
)
!=
0
;
ac
.
fill
=
(
fill
>>
16
)
&
0xFFFF
;
ac
.
max_fill
=
(
fill
>>
0
)
&
0xFFFF
;
ac
.
valid
=
valid
&
0xFFFFFFFF
;
ac
.
late
=
late
&
0xFFFFFFFF
;
eca
.
channels
.
push_back
(
ac
);
}
...
...
@@ -245,17 +232,9 @@ status_t ECA::load(Device dev, std::vector<ECA>& ecas) {
for
(
unsigned
s
=
0
;
s
<
record
.
streams
.
size
();
++
s
)
{
EventStream
&
es
=
record
.
streams
[
s
];
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
return
status
;
/* These have to be separate cycles so the crossbar doesn't get stuffed up */
cycle
.
read
(
es
.
address
,
EB_DATA32
,
&
id
);
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
status
=
device
.
read
(
es
.
address
,
EB_DATA32
,
&
id
);
if
(
status
!=
EB_OK
)
return
status
;
ids
[
s
]
=
id
;
}
...
...
@@ -267,6 +246,7 @@ status_t ECA::load(Device dev, std::vector<ECA>& ecas) {
/* fprintf(stderr, "Unmatched ECA Event stream; id: %d\n", mid); */
continue
;
}
es
.
eca
=
&
ecas
[
mid
];
ecas
[
mid
].
streams
.
push_back
(
es
);
}
...
...
modules/wr_eca/lib/program-walk.cpp
deleted
100644 → 0
View file @
007b38c9
/** @file program-walk.cpp
* @brief Program the walk table
* @author Wesley W. Terpstra <w.terpstra@gsi.de>
*
* Copyright (C) 2013 GSI Helmholtz Centre for Heavy Ion Research GmbH
*
* Write the contents of the walker component of the condition table.
*
*******************************************************************************
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************
*/
#define __STDC_FORMAT_MACROS
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#include <stdio.h>
#include <assert.h>
#include "eca.h"
#include "hw-eca.h"
namespace
GSI_ECA
{
status_t
ECA
::
programWalk
(
Device
dev
,
const
std
::
vector
<
WalkEntry
>&
table
)
{
Cycle
cycle
;
eb_status_t
status
;
eb_data_t
next
;
int
done
;
/* Must fit inside this hardware */
if
(
table
.
size
()
>
table_size
)
return
EB_OOM
;
for
(
unsigned
i
=
0
;
i
<
table
.
size
();
++
i
)
{
const
WalkEntry
&
we
=
table
[
i
];
/* Ensure we don't program bullshit */
assert
(
we
.
channel
<
channels
.
size
());
assert
(
we
.
next
<
(
int
)
i
);
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
return
status
;
next
=
(
we
.
next
==-
1
)
?
0
:
(
UINT32_C
(
0x80000000
)
|
we
.
next
);
cycle
.
write
(
address
+
ECA_WALK
,
EB_DATA32
,
i
);
cycle
.
write
(
address
+
ECA_NEXT
,
EB_DATA32
,
next
);
cycle
.
write
(
address
+
ECA_DELAY1
,
EB_DATA32
,
we
.
offset
>>
32
);
cycle
.
write
(
address
+
ECA_DELAY0
,
EB_DATA32
,
we
.
offset
&
UINT32_C
(
0xFFFFFFFF
));
cycle
.
write
(
address
+
ECA_TAG
,
EB_DATA32
,
we
.
tag
);
cycle
.
write
(
address
+
ECA_CHANNEL
,
EB_DATA32
,
we
.
channel
);
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
}
return
EB_OK
;
}
}
modules/wr_eca/lib/
program-search
.cpp
→
modules/wr_eca/lib/
store-table
.cpp
View file @
25e16479
/** @file
program-search
.cpp
* @brief Program the
search
table
/** @file
store-table
.cpp
* @brief Program the
walk
table
* @author Wesley W. Terpstra <w.terpstra@gsi.de>
*
* Copyright (C) 2013 GSI Helmholtz Centre for Heavy Ion Research GmbH
*
* Write the contents of the
search component of the condition table
.
* Write the contents of the
condition table to the ECA
.
*
*******************************************************************************
* This library is free software; you can redistribute it and/or
...
...
@@ -33,13 +33,15 @@
namespace
GSI_ECA
{
stat
us_t
ECA
::
programSearch
(
Device
dev
,
const
std
::
vector
<
SearchEntry
>&
table
)
{
stat
ic
status_t
storeSearch
(
ECA
*
eca
,
const
std
::
vector
<
SearchEntry
>&
table
)
{
Cycle
cycle
;
unsigned
table_size
;
eb_address_t
address
;
eb_status_t
status
;
eb_data_t
first
;
int
done
;
/* Must fit inside this hardware */
table_size
=
eca
->
table_size
;
if
(
table
.
size
()
>
2
*
table_size
)
return
EB_OOM
;
/* Must have a 0 as first entry */
...
...
@@ -47,6 +49,7 @@ status_t ECA::programSearch(Device dev, const std::vector<SearchEntry>& table) {
Event
last_event
=
0
;
address
=
eca
->
address
;
for
(
unsigned
i
=
0
;
i
<
2
*
table_size
;
++
i
)
{
/* Duplicate the last entry to fill out the table */
const
SearchEntry
&
se
=
(
i
<
table
.
size
())
?
table
[
i
]
:
(
*--
table
.
end
());
...
...
@@ -55,7 +58,7 @@ status_t ECA::programSearch(Device dev, const std::vector<SearchEntry>& table) {
assert
(
last_event
<=
se
.
event
);
last_event
=
se
.
event
;
if
((
status
=
cycle
.
open
(
dev
,
&
done
,
wrap_function_callback
<
int
,
eca_cycle_done
>
))
!=
EB_OK
)
if
((
status
=
cycle
.
open
(
eca
->
device
))
!=
EB_OK
)
return
status
;
first
=
(
se
.
first
==-
1
)
?
0
:
(
UINT32_C
(
0x80000000
)
|
se
.
first
);
...
...
@@ -64,15 +67,65 @@ status_t ECA::programSearch(Device dev, const std::vector<SearchEntry>& table) {
cycle
.
write
(
address
+
ECA_FIRST
,
EB_DATA32
,
first
);
cycle
.
write
(
address
+
ECA_EVENT1
,
EB_DATA32
,
se
.
event
>>
32
);
cycle
.
write
(
address
+
ECA_EVENT0
,
EB_DATA32
,
se
.
event
&
UINT32_C
(
0xFFFFFFFF
));
cycle
.
close
();
done
=
0
;
while
(
!
done
)
dev
.
socket
().
run
();
if
(
done
<
0
)
return
done
;
if
(
done
==
2
)
return
EB_FAIL
;
if
((
status
=
cycle
.
close
())
!=
EB_OK
)
return
status
;
}
return
EB_OK
;
}
static
status_t
storeWalk
(
ECA
*
eca
,
const
std
::
vector
<
WalkEntry
>&
table
)
{
Cycle
cycle
;
eb_address_t
address
;
eb_status_t
status
;
eb_data_t
next
;
unsigned
channels
;
/* Must fit inside this hardware */
channels
=
eca
->
channels
.
size
();
if
(
table
.
size
()
>
eca
->
table_size
)
return
EB_OOM
;
address
=
eca
->
address
;
for
(
unsigned
i
=
0
;
i
<
table
.
size
();
++
i
)
{
const
WalkEntry
&
we
=
table
[
i
];
/* Ensure we don't program bullshit */
if
(
we
.
channel
>=
channels
)
return
EB_FAIL
;
assert
(
we
.
next
<
(
int
)
i
);
if
((
status
=
cycle
.
open
(
eca
->
device
))
!=
EB_OK
)
return
status
;
next
=
(
we
.
next
==-
1
)
?
0
:
(
UINT32_C
(
0x80000000
)
|
we
.
next
);
cycle
.
write
(
address
+
ECA_WALK
,
EB_DATA32
,
i
);
cycle
.
write
(
address
+
ECA_NEXT
,
EB_DATA32
,
next
);
cycle
.
write
(
address
+
ECA_DELAY1
,
EB_DATA32
,
we
.
offset
>>
32
);
cycle
.
write
(
address
+
ECA_DELAY0
,
EB_DATA32
,
we
.
offset
&
UINT32_C
(
0xFFFFFFFF
));
cycle
.
write
(
address
+
ECA_TAG
,
EB_DATA32
,
we
.
tag
);
cycle
.
write
(
address
+
ECA_CHANNEL
,
EB_DATA32
,
we
.
channel
);
if
((
status
=
cycle
.
close
())
!=
EB_OK
)
return
status
;
}
return
EB_OK
;
}
status_t
ECA
::
store
(
const
Table
&
table
)
{
status_t
status
;
std
::
vector
<
SearchEntry
>
se
;
std
::
vector
<
WalkEntry
>
we
;
table
.
impl
->
compile
(
se
,
we
);
if
((
status
=
storeSearch
(
this
,
se
))
!=
EB_OK
)
return
status
;
if
((
status
=
storeWalk
(
this
,
we
))
!=
EB_OK
)
return
status
;
return
EB_OK
;
}
}
modules/wr_eca/lib/
program-
table.cpp
→
modules/wr_eca/lib/table.cpp
View file @
25e16479
/** @file
program-
table.cpp
/** @file table.cpp
* @brief Convert to/from user-facing condition table
* @author Wesley W. Terpstra <w.terpstra@gsi.de>
*
...
...
@@ -39,7 +39,35 @@
namespace
GSI_ECA
{
int
ReverseTable
::
add
(
Event
begin
,
Event
end
,
Time
offset
,
Channel
channel
,
Tag
tag
)
{
Table
::
Table
()
:
impl
(
new
Impl
)
{
}
Table
::~
Table
()
{
delete
impl
;
}
Table
::
Table
(
const
Table
&
table
)
:
impl
(
new
Impl
(
*
table
.
impl
))
{
}
int
Table
::
add
(
const
TableEntry
&
te
)
{
return
impl
->
add
(
te
);
}
int
Table
::
del
(
const
TableEntry
&
te
)
{
return
impl
->
remove
(
te
);
}
int
Table
::
set
(
const
std
::
vector
<
TableEntry
>&
vect
)
{
return
impl
->
set
(
vect
);
}
void
Table
::
get
(
std
::
vector
<
TableEntry
>&
vect
)
const
{
return
impl
->
get
(
vect
);
}
int
Table
::
Impl
::
add
(
Event
begin
,
Event
end
,
Time
offset
,
Channel
channel
,
Tag
tag
)
{
int
out
=
0
;
if
(
end
<
begin
)
return
out
;
...
...
@@ -96,7 +124,7 @@ int ReverseTable::add(Event begin, Event end, Time offset, Channel channel, Tag
return
out
;
}
int
ReverseTable
::
remove
(
Event
begin
,
Event
end
,
Time
offset
,
Channel
channel
)
{
int
Table
::
Impl
::
remove
(
Event
begin
,
Event
end
,
Time
offset
,
Channel
channel
)
{
int
out
=
0
;
if
(
end
<
begin
)
return
out
;
...
...
@@ -165,7 +193,7 @@ static Event eca_encode_mask(uint8_t event_bits) {
}
int
ReverseTable
::
add
(
const
TableEntry
&
te
)
{
int
Table
::
Impl
::
add
(
const
TableEntry
&
te
)
{
Event
mask
=
eca_encode_mask
(
te
.
event_bits
);
Event
begin
=
te
.
event
&
~
mask
;
Event
end
=
begin
|
mask
;
...
...
@@ -173,7 +201,7 @@ int ReverseTable::add(const TableEntry& te) {
return
add
(
begin
,
end
,
te
.
offset
,
te
.
channel
,
te
.
tag
);
}
int
ReverseTable
::
remove
(
const
TableEntry
&
te
)
{
int
Table
::
Impl
::
remove
(
const
TableEntry
&
te
)
{
Event
mask
=
eca_encode_mask
(
te
.
event_bits
);
Event
begin
=
te
.
event
&
~
mask
;
Event
end
=
begin
|
mask
;
...
...
@@ -181,7 +209,7 @@ int ReverseTable::remove(const TableEntry& te) {
return
remove
(
begin
,
end
,
te
.
offset
,
te
.
channel
);
}
int
ReverseTable
::
load
(
const
std
::
vector
<
TableEntry
>&
t
)
{
int
Table
::
Impl
::
set
(
const
std
::
vector
<
TableEntry
>&
t
)
{
int
count
=
0
;
for
(
unsigned
ti
=
0
;
ti
<
t
.
size
();
++
ti
)
{
...
...
@@ -191,7 +219,7 @@ int ReverseTable::load(const std::vector<TableEntry>& t) {
return
count
;
}
int
ReverseTable
::
load
(
const
std
::
vector
<
SearchEntry
>&
s
,
const
std
::
vector
<
WalkEntry
>&
w
)
{
int
Table
::
Impl
::
decompile
(
const
std
::
vector
<
SearchEntry
>&
s
,
const
std
::
vector
<
WalkEntry
>&
w
)
{
int
count
=
0
;
Event
last
=
((
Event
)
-
1
);
...
...
@@ -233,8 +261,8 @@ static unsigned eca_decode_mask(Event mask) {
return
count
;
}
std
::
vector
<
TableEntry
>
ReverseTable
::
reverse
(
)
const
{
std
::
vector
<
TableEntry
>
result
;
void
Table
::
Impl
::
get
(
std
::
vector
<
TableEntry
>&
result
)
const
{
result
.
clear
()
;
for
(
unsigned
c
=
0
;
c
<
data
.
size
();
++
c
)
{
const
TableActions
&
ta
=
data
[
c
];
...
...
@@ -295,11 +323,11 @@ std::vector<TableEntry> ReverseTable::reverse() const {
}
sort
(
result
.
begin
(),
result
.
end
(),
sort_event_bits_offset_channel
);
return
result
;
}
void
ReverseTable
::
compile
(
std
::
vector
<
SearchEntry
>&
s
,
std
::
vector
<
WalkEntry
>&
w
)
const
{
std
::
vector
<
TableEntry
>
t
(
reverse
());
void
Table
::
Impl
::
compile
(
std
::
vector
<
SearchEntry
>&
s
,
std
::
vector
<
WalkEntry
>&
w
)
const
{
std
::
vector
<
TableEntry
>
t
;
get
(
t
);
s
.
clear
();
w
.
clear
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment