Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
ALPACA
CASPER
casperfpga
Commits
0d2eb8ac
Commit
0d2eb8ac
authored
Jan 20, 2016
by
Jason Manley
Browse files
Merge pull request #43 from ska-sa/devel
Merge devel with master
parents
588e0728
01419c7c
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
279 additions
and
164 deletions
+279
-164
src/attribute_container.py
src/attribute_container.py
+3
-22
src/casperfpga.py
src/casperfpga.py
+75
-61
src/katcp_fpga.py
src/katcp_fpga.py
+157
-78
src/memory.py
src/memory.py
+8
-3
src/utils.py
src/utils.py
+36
-0
No files found.
src/attribute_container.py
View file @
0d2eb8ac
__author__
=
'paulp'
class
AttributeContainer
(
object
):
"""An iterable class to make registers, snapshots, etc more accessible.
"""
def
__init__
(
self
):
self
.
_items
=
[]
self
.
clear
()
def
__getitem__
(
self
,
item_to_get
):
...
...
@@ -18,27 +15,13 @@ class AttributeContainer(object):
def
__setattr__
(
self
,
name
,
value
):
try
:
if
name
!=
'_next_item'
:
self
.
_items
.
append
(
name
)
self
.
_items
.
append
(
name
)
except
AttributeError
:
pass
object
.
__setattr__
(
self
,
name
,
value
)
def
__iter__
(
self
):
return
self
def
__next__
(
self
):
try
:
item_name
=
self
.
_items
[
self
.
_next_item
]
except
:
self
.
_next_item
=
0
raise
StopIteration
else
:
self
.
_next_item
+=
1
return
getattr
(
self
,
item_name
)
def
next
(
self
):
# Python 2 compat
return
self
.
__next__
()
return
(
getattr
(
self
,
n
)
for
n
in
self
.
_items
)
def
remove_attribute
(
self
,
attribute
):
"""
...
...
@@ -51,7 +34,6 @@ class AttributeContainer(object):
def
clear
(
self
):
self
.
__dict__
.
clear
()
self
.
_next_item
=
0
self
.
_items
=
[]
def
names
(
self
):
...
...
@@ -65,6 +47,5 @@ class AttributeContainer(object):
def
__repr__
(
self
):
keys
=
self
.
__dict__
.
keys
()
keys
.
pop
(
keys
.
index
(
'_next_item'
))
keys
.
pop
(
keys
.
index
(
'_items'
))
return
str
(
keys
)
src/casperfpga.py
View file @
0d2eb8ac
...
...
@@ -17,18 +17,19 @@ from utils import parse_fpg
LOGGER
=
logging
.
getLogger
(
__name__
)
# known CASPER memory-accessible devices and their associated classes and containers
# known CASPER memory-accessible devices and their associated
# classes and containers
CASPER_MEMORY_DEVICES
=
{
'xps:bram'
:
{
'class'
:
sbram
.
Sbram
,
'container'
:
'sbrams'
},
'xps:qdr'
:
{
'class'
:
qdr
.
Qdr
,
'container'
:
'qdrs'
},
'xps:sw_reg'
:
{
'class'
:
register
.
Register
,
'container'
:
'registers'
},
'xps:tengbe_v2'
:
{
'class'
:
tengbe
.
TenGbe
,
'container'
:
'tengbes'
},
'casper:snapshot'
:
{
'class'
:
snap
.
Snap
,
'container'
:
'snapshots'
},
'xps:bram'
:
{
'class'
:
sbram
.
Sbram
,
'container'
:
'sbrams'
},
'xps:qdr'
:
{
'class'
:
qdr
.
Qdr
,
'container'
:
'qdrs'
},
'xps:sw_reg'
:
{
'class'
:
register
.
Register
,
'container'
:
'registers'
},
'xps:tengbe_v2'
:
{
'class'
:
tengbe
.
TenGbe
,
'container'
:
'tengbes'
},
'casper:snapshot'
:
{
'class'
:
snap
.
Snap
,
'container'
:
'snapshots'
},
}
# other devices - blocks that aren't memory devices, but about which we'd
like to know
# tagged in the simulink diagram
# other devices - blocks that aren't memory devices, but about which we'd
#
like to know
tagged in the simulink diagram
CASPER_OTHER_DEVICES
=
{
'casper:bitsnap'
:
'bitsnap'
,
'casper:dec_fir'
:
'dec_fir'
,
...
...
@@ -79,7 +80,8 @@ class CasperFpga(object):
def
deprogram
(
self
):
"""
The child class will deprogram the FPGA, we just reset out device information
The child class will deprogram the FPGA, we just reset out
device information
:return:
"""
self
.
__reset_device_info
()
...
...
@@ -106,13 +108,14 @@ class CasperFpga(object):
def
test_connection
(
self
):
"""
Write to and read from the scratchpad to test the connection to the FPGA
.
Write to and read from the scratchpad to test the connection to the FPGA
"""
for
val
in
[
0xa5a5a5
,
0x000000
]:
self
.
write_int
(
'sys_scratchpad'
,
val
)
rval
=
self
.
read_int
(
'sys_scratchpad'
)
if
rval
!=
val
:
raise
RuntimeError
(
'%s: cannot write scratchpad? %i != %i'
%
(
self
.
host
,
rval
,
val
))
raise
RuntimeError
(
'%s: cannot write scratchpad? %i != %i'
%
(
self
.
host
,
rval
,
val
))
return
True
# def __getattribute__(self, name):
...
...
@@ -136,13 +139,13 @@ class CasperFpga(object):
last_dram_page
=
-
1
dram_indirect_page_size
=
(
64
*
1024
*
1024
)
#read_chunk_size = (1024*1024)
#
read_chunk_size = (1024*1024)
LOGGER
.
debug
(
'%s: reading a total of %8i bytes from offset %8i...'
%
(
self
.
host
,
size
,
offset
))
while
n_reads
<
size
:
dram_page
=
(
offset
+
n_reads
)
/
dram_indirect_page_size
local_offset
=
(
offset
+
n_reads
)
%
dram_indirect_page_size
#local_reads = min(read_chunk_size, size-n_reads, dram_indirect_page_size-(offset%dram_indirect_page_size))
#
local_reads = min(read_chunk_size, size-n_reads, dram_indirect_page_size-(offset%dram_indirect_page_size))
local_reads
=
min
(
size
-
n_reads
,
dram_indirect_page_size
-
(
offset
%
dram_indirect_page_size
))
if
last_dram_page
!=
dram_page
:
self
.
write_int
(
'dram_controller'
,
dram_page
)
...
...
@@ -201,12 +204,14 @@ class CasperFpga(object):
if
new_data
!=
data
:
unpacked_wrdata
=
struct
.
unpack
(
'>L'
,
data
[
0
:
4
])[
0
]
unpacked_rddata
=
struct
.
unpack
(
'>L'
,
new_data
[
0
:
4
])[
0
]
LOGGER
.
error
(
'%s: verification of write to %s at offset %d failed. Wrote 0x%08x... '
'but got back 0x%08x...'
%
(
self
.
host
,
device_name
,
offset
,
unpacked_wrdata
,
unpacked_rddata
))
raise
ValueError
(
'%s: verification of write to %s at offset %d failed. Wrote 0x%08x... '
'but got back 0x%08x...'
%
(
self
.
host
,
device_name
,
offset
,
unpacked_wrdata
,
unpacked_rddata
))
LOGGER
.
error
(
'%s: verification of write to %s at offset %d failed. '
'Wrote 0x%08x... but got back 0x%08x...'
%
(
self
.
host
,
device_name
,
offset
,
unpacked_wrdata
,
unpacked_rddata
))
raise
ValueError
(
'%s: verification of write to %s at offset %d '
'failed. Wrote 0x%08x... but got back 0x%08x...'
%
(
self
.
host
,
device_name
,
offset
,
unpacked_wrdata
,
unpacked_rddata
))
def
read_int
(
self
,
device_name
,
word_offset
=
0
):
"""
...
...
@@ -242,52 +247,61 @@ class CasperFpga(object):
# careful of packing input data into 32 bit - check range: if
# negative, must be signed int; if positive over 2^16, must be unsigned
# int.
data
=
struct
.
pack
(
'>i'
if
integer
<
0
else
'>I'
,
integer
)
try
:
data
=
struct
.
pack
(
'>i'
if
integer
<
0
else
'>I'
,
integer
)
except
Exception
as
ve
:
LOGGER
.
error
(
'Writing integer %i failed with error %s'
%
(
integer
,
ve
.
message
))
raise
ValueError
(
'Writing integer %i failed with error %s'
%
(
integer
,
ve
.
message
))
if
blindwrite
:
self
.
blindwrite
(
device_name
,
data
,
word_offset
*
4
)
else
:
self
.
write
(
device_name
,
data
,
word_offset
*
4
)
LOGGER
.
debug
(
'%s: write_int %8x to register %s at word offset %d okay%s.'
%
(
self
.
host
,
integer
,
device_name
,
word_offset
,
' (blind)'
if
blindwrite
else
''
))
def
get_rcs
(
self
,
rcs_block_name
=
'rcs'
):
"""Retrieves and decodes a revision control block."""
raise
NotImplementedError
rv
=
{
'user'
:
self
.
read_uint
(
rcs_block_name
+
'_user'
)}
app
=
self
.
read_uint
(
rcs_block_name
+
'_app'
)
lib
=
self
.
read_uint
(
rcs_block_name
+
'_lib'
)
if
lib
&
(
1
<<
31
):
rv
[
'compile_timestamp'
]
=
lib
&
((
2
**
31
)
-
1
)
else
:
if
lib
&
(
1
<<
30
):
# type is svn
rv
[
'lib_rcs_type'
]
=
'svn'
else
:
# type is git
rv
[
'lib_rcs_type'
]
=
'git'
if
lib
&
(
1
<<
28
):
# dirty bit
rv
[
'lib_dirty'
]
=
True
else
:
rv
[
'lib_dirty'
]
=
False
rv
[
'lib_rev'
]
=
lib
&
((
2
**
28
)
-
1
)
if
app
&
(
1
<<
31
):
rv
[
'app_last_modified'
]
=
app
&
((
2
**
31
)
-
1
)
else
:
if
app
&
(
1
<<
30
):
# type is svn
rv
[
'app_rcs_type'
]
=
'svn'
else
:
# type is git
rv
[
'app_rcs_type'
]
=
'git'
if
app
&
(
1
<<
28
):
# dirty bit
rv
[
'app_dirty'
]
=
True
else
:
rv
[
'lib_dirty'
]
=
False
rv
[
'app_rev'
]
=
app
&
((
2
**
28
)
-
1
)
return
rv
LOGGER
.
debug
(
'%s: write_int %8x to register %s at word offset %d '
'okay%s.'
%
(
self
.
host
,
integer
,
device_name
,
word_offset
,
' (blind)'
if
blindwrite
else
''
))
# def get_rcs(self, rcs_block_name='rcs'):
# """
# Retrieves and decodes a revision control block.
# """
# raise NotImplementedError
# rv = {'user': self.read_uint(rcs_block_name + '_user')}
# app = self.read_uint(rcs_block_name+'_app')
# lib = self.read_uint(rcs_block_name+'_lib')
# if lib & (1 << 31):
# rv['compile_timestamp'] = lib & ((2 ** 31)-1)
# else:
# if lib & (1 << 30):
# # type is svn
# rv['lib_rcs_type'] = 'svn'
# else:
# # type is git
# rv['lib_rcs_type'] = 'git'
# if lib & (1 << 28):
# # dirty bit
# rv['lib_dirty'] = True
# else:
# rv['lib_dirty'] = False
# rv['lib_rev'] = lib & ((2 ** 28)-1)
# if app & (1 << 31):
# rv['app_last_modified'] = app & ((2 ** 31)-1)
# else:
# if app & (1 << 30):
# # type is svn
# rv['app_rcs_type'] = 'svn'
# else:
# # type is git
# rv['app_rcs_type'] = 'git'
# if app & (1 << 28):
# # dirty bit
# rv['app_dirty'] = True
# else:
# rv['lib_dirty'] = False
# rv['app_rev'] = app & ((2 ** 28)-1)
# return rv
def
__create_memory_devices
(
self
,
device_dict
,
memorymap_dict
):
"""
...
...
src/katcp_fpga.py
View file @
0d2eb8ac
This diff is collapsed.
Click to expand it.
src/memory.py
View file @
0d2eb8ac
...
...
@@ -7,6 +7,7 @@ busses. Normally via KATCP.
import
logging
import
bitfield
import
struct
import
numpy
as
np
LOGGER
=
logging
.
getLogger
(
__name__
)
...
...
@@ -39,7 +40,8 @@ def fp2fixed_int(num, bitwidth, bin_pt, signed):
"""
Convert a given float to an integer representation of the fixed-point number
described by the params.
Provides the same output as a Xilinx block in Simulink would if you cast it to an unsigned int.
Provides the same output as a Xilinx block in Simulink would if you cast
it to an unsigned int.
"""
_format
=
'%s%i.%i'
%
(
'fix'
if
signed
else
'ufix'
,
bitwidth
,
bin_pt
)
LOGGER
.
debug
(
'Converting %f to %s'
%
(
num
,
_format
))
...
...
@@ -59,10 +61,13 @@ def fp2fixed_int(num, bitwidth, bin_pt, signed):
negnum
=
num
<
0
_original_num
=
num
num
=
abs
(
num
)
left
=
int
(
num
)
right
,
left
=
np
.
modf
(
num
)
left
=
int
(
left
)
right
=
int
(
right
*
(
2
**
bin_pt
))
# left = int(num)
if
left
>
left_limits
[
1
]:
raise
ValueError
(
'Cannot represent %f in %s'
%
(
_original_num
,
_format
))
right
=
int
(
round
((
abs
(
num
)
%
1
)
*
(
2
**
bin_pt
)))
#
right = int(round((abs(num) % 1) * (2**bin_pt)))
assert
left
>=
0
and
right
>=
0
_lsbin
=
bin
(
left
)[
2
:]
_lsbin
=
'0'
*
(
left_bits
-
len
(
_lsbin
))
+
_lsbin
...
...
src/utils.py
View file @
0d2eb8ac
...
...
@@ -67,6 +67,42 @@ def parse_fpg(filename):
return
create_meta_dictionary
(
metalist
),
memorydict
def
pull_info_from_fpg
(
fpg_file
,
parameter
):
"""
Pull available parameters about x-engine or f-engine from .fpg file.
Available options for x-engine: 'x_fpga_clock', 'xeng_outbits', 'xeng_accumulation_len'
Available options for f-engine: 'n_chans', 'quant_format', 'spead_flavour'
:param fpg_file: bit file path
:param parameter: parameter string
:return: pattern value (string)
"""
match
=
[]
fpg_dict
=
parse_fpg
(
fpg_file
)
if
parameter
==
'x_fpga_clock'
:
match
=
str
(
int
(
fpg_dict
[
0
][
'XSG_core_config'
][
'clk_rate'
])
*
10
**
6
)
if
parameter
==
'xeng_outbits'
:
match
=
fpg_dict
[
0
][
'sys0_vacc'
][
'n_bits'
]
if
parameter
==
'xeng_accumulation_len'
:
match
=
fpg_dict
[
0
][
'sys0_xeng'
][
'acc_len'
]
if
parameter
==
'spead_flavour'
:
match1
=
fpg_dict
[
0
][
'pack_spead_pack0'
][
'spead_msw'
]
match2
=
fpg_dict
[
0
][
'pack_spead_pack0'
][
'spead_lsw'
]
s
=
','
match
=
s
.
join
([
match1
,
match2
])
if
parameter
==
'quant_format'
:
match1
=
fpg_dict
[
0
][
'snap_quant0'
][
'io_widths'
]
match2
=
fpg_dict
[
0
][
'snap_quant0'
][
'io_bps'
]
s
=
'.'
match
=
s
.
join
([
match1
[
1
],
match2
[
1
]])
if
parameter
==
'n_chans'
:
match1
=
int
(
fpg_dict
[
0
][
'pfb_fft_wideband_real_fft_biplex_real_4x'
][
'fftsize'
])
match2
=
int
(
fpg_dict
[
0
][
'pfb_fft_wideband_real_fft_biplex_real_4x'
][
'n_inputs'
])
match
=
match2
*
2
**
match1
if
match
is
[]:
raise
RuntimeError
(
'Parameter %s does not match any field in fpg file.'
%
parameter
)
return
match
def
program_fpgas
(
fpga_list
,
progfile
,
timeout
=
10
):
"""
Program more than one FPGA at the same time.
...
...
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