Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
x393
Commits
6a2bdfd7
Commit
6a2bdfd7
authored
Jul 07, 2016
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
testing cocotb simulation, converting more simulation features
parent
98b0786f
Changes
19
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
892 additions
and
314 deletions
+892
-314
socket_command.py
cocotb/socket_command.py
+5
-4
x393_cocotb_02.sav
cocotb/x393_cocotb_02.sav
+91
-9
x393_cocotb_server.py
cocotb/x393_cocotb_server.py
+77
-26
x393_dut.v
cocotb/x393_dut.v
+139
-176
x393interfaces.py
cocotb/x393interfaces.py
+289
-14
x393_simulation_parameters.vh
includes/x393_simulation_parameters.vh
+4
-0
cocoargs
py393/cocoargs
+7
-0
test_mcntrl.py
py393/test_mcntrl.py
+11
-12
vrlg.py
py393/vrlg.py
+122
-32
x393_axi_control_status.py
py393/x393_axi_control_status.py
+4
-1
x393_mem.py
py393/x393_mem.py
+75
-9
x393_sens_cmprs.py
py393/x393_sens_cmprs.py
+28
-5
x393_sensor.py
py393/x393_sensor.py
+1
-1
sim_soc_interrupts.v
simulation_modules/sim_soc_interrupts.v
+1
-1
simul_axi_fifo_out.v
simulation_modules/simul_axi_fifo_out.v
+11
-8
simul_axi_hp_rd.v
simulation_modules/simul_axi_hp_rd.v
+6
-2
simul_axi_hp_wr.v
simulation_modules/simul_axi_hp_wr.v
+6
-1
simul_axi_master_wdata.v
simulation_modules/simul_axi_master_wdata.v
+8
-9
x393_testbench03.tf
x393_testbench03.tf
+7
-4
No files found.
cocotb/socket_command.py
View file @
6a2bdfd7
...
@@ -68,7 +68,7 @@ class SocketCommand():
...
@@ -68,7 +68,7 @@ class SocketCommand():
self
.
arguments
=
None
self
.
arguments
=
None
class
x393Client
():
class
x393Client
():
def
__init__
(
self
,
port
=
7777
,
host
=
'localhost'
):
def
__init__
(
self
,
host
=
'localhost'
,
port
=
7777
):
self
.
PORT
=
port
self
.
PORT
=
port
self
.
HOST
=
host
# Symbolic name meaning all available interfaces
self
.
HOST
=
host
# Symbolic name meaning all available interfaces
self
.
cmd
=
SocketCommand
()
self
.
cmd
=
SocketCommand
()
...
@@ -87,11 +87,12 @@ class x393Client():
...
@@ -87,11 +87,12 @@ class x393Client():
print
(
"stop->"
,
self
.
communicate
(
self
.
cmd
.
toJSON
()))
print
(
"stop->"
,
self
.
communicate
(
self
.
cmd
.
toJSON
()))
def
write
(
self
,
address
,
data
):
def
write
(
self
,
address
,
data
):
self
.
cmd
.
setWrite
([
address
,
data
])
self
.
cmd
.
setWrite
([
address
,
data
])
print
(
"write->"
,
self
.
communicate
(
self
.
cmd
.
toJSON
()))
rslt
=
self
.
communicate
(
self
.
cmd
.
toJSON
())
print
(
"write->"
,
rslt
)
def
read
(
self
,
address
):
def
read
(
self
,
address
):
self
.
cmd
.
setRead
(
address
)
self
.
cmd
.
setRead
(
address
)
print
(
"read->args"
,
self
.
cmd
.
getArgs
())
#
print("read->args",self.cmd.getArgs())
rslt
=
self
.
communicate
(
self
.
cmd
.
toJSON
())
rslt
=
self
.
communicate
(
self
.
cmd
.
toJSON
())
print
(
"read->"
,
rslt
)
#
print("read->",rslt)
return
json
.
loads
(
rslt
)
return
json
.
loads
(
rslt
)
cocotb/x393_cocotb_02.sav
View file @
6a2bdfd7
[*]
[*]
[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
[*] GTKWave Analyzer v3.3.66 (w)1999-2015 BSI
[*]
Mon Jul 4 03:19:05
2016
[*]
Wed Jul 6 17:53:54
2016
[*]
[*]
[dumpfile] "/home/eyesis/git/x393-neon/simulation/x393_dut-2016070
3211758949
.fst"
[dumpfile] "/home/eyesis/git/x393-neon/simulation/x393_dut-2016070
6092756207
.fst"
[dumpfile_mtime] "
Mon Jul 4 03:18:33
2016"
[dumpfile_mtime] "
Wed Jul 6 16:46:27
2016"
[dumpfile_size]
639043
[dumpfile_size]
26909872
[savefile] "/home/eyesis/git/x393-neon/cocotb/x393_cocotb_02.sav"
[savefile] "/home/eyesis/git/x393-neon/cocotb/x393_cocotb_02.sav"
[timestart]
1092470
0
[timestart] 0
[size] 1836 1171
[size] 1836 1171
[pos] 1920 0
[pos] 1920 0
*-16.699684 11530000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*-24.853212 32750000 32750000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 204
[treeopen] x393_dut.
[treeopen] x393_dut.simul_axi_master_wdata_i.
[sst_width] 357
[signals_width] 238
[signals_width] 238
[sst_expanded] 1
[sst_expanded] 1
[sst_vpaned_height]
34
4
[sst_vpaned_height]
48
4
@82
1
@82
0
x393_dut.TEST_TITLE[639:0]
x393_dut.TEST_TITLE[639:0]
@c00200
-maxi0
@28
@28
x393_dut.dutm0_aclk
x393_dut.dutm0_aclk
@22
@22
...
@@ -86,6 +90,8 @@ x393_dut.dutm0_wid_w[11:0]
...
@@ -86,6 +90,8 @@ x393_dut.dutm0_wid_w[11:0]
x393_dut.dutm0_wlast
x393_dut.dutm0_wlast
x393_dut.dutm0_wlast_w
x393_dut.dutm0_wlast_w
x393_dut.dutm0_wready
x393_dut.dutm0_wready
@200
-
@22
@22
x393_dut.dutm0_wstb[3:0]
x393_dut.dutm0_wstb[3:0]
x393_dut.dutm0_wstb_w[3:0]
x393_dut.dutm0_wstb_w[3:0]
...
@@ -95,5 +101,81 @@ x393_dut.dutm0_wvalid_w
...
@@ -95,5 +101,81 @@ x393_dut.dutm0_wvalid_w
@22
@22
x393_dut.dutm0_xtra_blag[3:0]
x393_dut.dutm0_xtra_blag[3:0]
x393_dut.dutm0_xtra_rdlag[3:0]
x393_dut.dutm0_xtra_rdlag[3:0]
@1401200
-maxi0
@800200
-SENSOR1
@28
x393_dut.simul_sensor12bits_i.MCLK
@22
x393_dut.simul_sensor12bits_i.D[11:0]
@28
x393_dut.simul_sensor12bits_i.HACT
x393_dut.simul_sensor12bits_i.MRST
@29
x393_dut.simul_sensor12bits_i.ARST
@28
x393_dut.simul_sensor12bits_i.NMRST
x393_dut.simul_sensor12bits_i.stopped
x393_dut.simul_sensor12bits_i.DCLK
@200
-
@1000200
-SENSOR1
@800200
-axi_master_wdata
@28
x393_dut.simul_axi_master_wdata_i.clk
x393_dut.simul_axi_master_wdata_i.ready
x393_dut.simul_axi_master_wdata_i.reset
x393_dut.simul_axi_master_wdata_i.set_cmd
@22
x393_dut.simul_axi_master_wdata_i.wdata[31:0]
x393_dut.simul_axi_master_wdata_i.wdata_in[31:0]
x393_dut.simul_axi_master_wdata_i.wdata_out[31:0]
x393_dut.simul_axi_master_wdata_i.wid[11:0]
x393_dut.simul_axi_master_wdata_i.wid_in[11:0]
x393_dut.simul_axi_master_wdata_i.wid_out[11:0]
@28
x393_dut.simul_axi_master_wdata_i.wlast
x393_dut.simul_axi_master_wdata_i.wlast_in
x393_dut.simul_axi_master_wdata_i.wlast_out
x393_dut.simul_axi_master_wdata_i.wready
@22
x393_dut.simul_axi_master_wdata_i.wstrb[3:0]
x393_dut.simul_axi_master_wdata_i.wstrb_in[3:0]
x393_dut.simul_axi_master_wdata_i.wstrb_out[3:0]
@28
x393_dut.simul_axi_master_wdata_i.wvalid
x393_dut.simul_axi_master_wdata_i.wvalid_out
@200
-
@800200
-simul_axi_fifo
@8028
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.clk
@8022
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.data_in[48:0]
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.data_out[48:0]
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.in_address
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.in_count
@8028
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.input_ready
@8022
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.latency_delay[3:0]
@8028
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.latency_delay_r[2:0]
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.load
@8022
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.out_address
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.out_count
@8028
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.out_inc
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.ready
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.reset
x393_dut.simul_axi_master_wdata_i.simul_axi_fifo_i.valid
@1000200
-simul_axi_fifo
-axi_master_wdata
[pattern_trace] 1
[pattern_trace] 1
[pattern_trace] 0
[pattern_trace] 0
cocotb/x393_cocotb_server.py
View file @
6a2bdfd7
...
@@ -38,15 +38,30 @@ import logging
...
@@ -38,15 +38,30 @@ import logging
class
X393_cocotb_server
(
object
):
class
X393_cocotb_server
(
object
):
writeIDMask
=
(
1
<<
12
)
-
1
writeIDMask
=
(
1
<<
12
)
-
1
readIDMask
=
(
1
<<
12
)
-
1
readIDMask
=
(
1
<<
12
)
-
1
def
__init__
(
self
,
dut
,
port
,
host
):
# , debug=False):
started
=
False
def
__init__
(
self
,
dut
,
port
,
host
,
mempath
=
"memfile"
,
autoflush
=
True
):
# , debug=False):
debug
=
os
.
getenv
(
'COCOTB_DEBUG'
)
# None/1
debug
=
os
.
getenv
(
'COCOTB_DEBUG'
)
# None/1
self
.
cmd
=
SocketCommand
()
self
.
cmd
=
SocketCommand
()
self
.
dut
=
dut
self
.
dut
=
dut
#initialize MAXIGP0 interface (main control/status registers, TODO: add MAXIGP1 for SATA)
self
.
maxigp0
=
MAXIGPMaster
(
entity
=
dut
,
name
=
"dutm0"
,
clock
=
dut
.
dutm0_aclk
,
rdlag
=
0
,
blag
=
0
)
self
.
maxigp0
=
MAXIGPMaster
(
entity
=
dut
,
name
=
"dutm0"
,
clock
=
dut
.
dutm0_aclk
,
rdlag
=
0
,
blag
=
0
)
self
.
writeID
=
0
self
.
writeID
=
0
self
.
readID
=
0
self
.
readID
=
0
#initialize Zynq register access, has methods write_reg(a,d) and read_reg(a)
self
.
ps_sbus
=
PSBus
(
entity
=
dut
,
name
=
"ps_sbus"
,
clock
=
dut
.
ps_sbus_clk
)
#Bus masters (communicated over mempath file
#Membridge to FPGA
self
.
saxihp0r
=
SAXIRdSim
(
entity
=
dut
,
name
=
"saxihp0"
,
clock
=
dut
.
axi_hclk
,
mempath
=
mempath
,
memhigh
=
0x40000000
,
data_bytes
=
8
)
#Membridge from FPGA
self
.
saxihp0w
=
SAXIWrSim
(
entity
=
dut
,
name
=
"saxihp0"
,
clock
=
dut
.
axi_hclk
,
mempath
=
mempath
,
memhigh
=
0x40000000
,
data_bytes
=
8
,
autoflush
=
autoflush
,
blatency
=
5
)
#Compressors from FPGA
self
.
saxihp1w
=
SAXIWrSim
(
entity
=
dut
,
name
=
"saxihp1"
,
clock
=
dut
.
axi_hclk
,
mempath
=
mempath
,
memhigh
=
0x40000000
,
data_bytes
=
8
,
autoflush
=
autoflush
,
blatency
=
5
)
#histograms from FPGA
self
.
saxigp0
=
SAXIWrSim
(
entity
=
dut
,
name
=
"saxigp0"
,
clock
=
dut
.
saxigp0
,
mempath
=
mempath
,
memhigh
=
0x40000000
,
data_bytes
=
4
,
autoflush
=
autoflush
,
blatency
=
5
)
level
=
logging
.
DEBUG
if
debug
else
logging
.
WARNING
level
=
logging
.
DEBUG
if
debug
else
logging
.
WARNING
self
.
maxigp0
.
log
.
setLevel
(
level
)
self
.
maxigp0
.
log
.
setLevel
(
level
)
...
@@ -54,6 +69,7 @@ class X393_cocotb_server(object):
...
@@ -54,6 +69,7 @@ class X393_cocotb_server(object):
self
.
PORT
=
port
self
.
PORT
=
port
self
.
HOST
=
host
# Symbolic name meaning all available interfaces
self
.
HOST
=
host
# Symbolic name meaning all available interfaces
self
.
socket_conn
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
socket_conn
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
socket_conn
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
1
)
# Otherwise restarting program will need 2 minutes
try
:
try
:
self
.
socket_conn
.
bind
((
self
.
HOST
,
self
.
PORT
))
self
.
socket_conn
.
bind
((
self
.
HOST
,
self
.
PORT
))
self
.
dut
.
_log
.
debug
(
'Socket bind complete, HOST=
%
s, PORT=
%
d'
%
(
self
.
HOST
,
self
.
PORT
))
self
.
dut
.
_log
.
debug
(
'Socket bind complete, HOST=
%
s, PORT=
%
d'
%
(
self
.
HOST
,
self
.
PORT
))
...
@@ -61,6 +77,9 @@ class X393_cocotb_server(object):
...
@@ -61,6 +77,9 @@ class X393_cocotb_server(object):
self
.
dut
.
_log
.
info
(
'Socket now listening to a single request on port
%
d: send command, receive response, close'
%
(
self
.
PORT
))
self
.
dut
.
_log
.
info
(
'Socket now listening to a single request on port
%
d: send command, receive response, close'
%
(
self
.
PORT
))
except
socket
.
error
as
msg
:
except
socket
.
error
as
msg
:
self
.
logErrorTerminate
(
'Bind failed. Error Code :
%
s Message
%
s'
%
(
str
(
msg
[
0
]),
msg
[
1
]))
self
.
logErrorTerminate
(
'Bind failed. Error Code :
%
s Message
%
s'
%
(
str
(
msg
[
0
]),
msg
[
1
]))
def
logErrorTerminate
(
self
,
msg
):
def
logErrorTerminate
(
self
,
msg
):
self
.
dut
.
_log
.
error
(
msg
)
self
.
dut
.
_log
.
error
(
msg
)
...
@@ -75,20 +94,22 @@ class X393_cocotb_server(object):
...
@@ -75,20 +94,22 @@ class X393_cocotb_server(object):
self
.
dut
.
_log
.
debug
(
"Connected with
%
s"
%
(
soc_addr
[
0
]
+
':'
+
str
(
soc_addr
[
1
])))
self
.
dut
.
_log
.
debug
(
"Connected with
%
s"
%
(
soc_addr
[
0
]
+
':'
+
str
(
soc_addr
[
1
])))
#Sending message to connected client
#Sending message to connected client
line
=
self
.
soc_conn
.
recv
(
4096
)
# or make it unlimited?
line
=
self
.
soc_conn
.
recv
(
4096
)
# or make it unlimited?
self
.
dut
.
_log
.
info
(
"Received from socket:
%
s"
%
(
line
))
self
.
dut
.
_log
.
debug
(
"Received from socket:
%
s"
%
(
line
))
except
:
except
:
self
.
logErrorTerminate
(
"Socket seems to have died :-("
)
self
.
logErrorTerminate
(
"Socket seems to have died :-("
)
self
.
dut
.
_log
.
info
(
"1.Received from socket:
%
s"
%
(
line
))
self
.
dut
.
_log
.
debug
(
"1.Received from socket:
%
s"
%
(
line
))
yield
self
.
executeCommand
(
line
)
yield
self
.
executeCommand
(
line
)
self
.
dut
.
_log
.
debug
(
"3.Received from socket:
%
s"
%
(
line
))
self
.
dut
.
_log
.
debug
(
"3.Received from socket:
%
s"
%
(
line
))
@
cocotb
.
coroutine
@
cocotb
.
coroutine
def
executeCommand
(
self
,
line
):
def
executeCommand
(
self
,
line
):
self
.
dut
.
_log
.
info
(
"1.executeCommand:
%
s"
%
(
line
))
self
.
dut
.
_log
.
debug
(
"1.executeCommand:
%
s"
%
(
line
))
if
not
line
:
if
not
line
:
raise
ReturnValue
(
None
)
raise
ReturnValue
(
None
)
self
.
dut
.
_log
.
info
(
"2.executeCommand:
%
s"
%
(
line
))
self
.
dut
.
_log
.
debug
(
"2.executeCommand:
%
s"
%
(
line
))
self
.
cmd
.
fromJSON
(
line
)
self
.
cmd
.
fromJSON
(
line
)
#TODO: add interrupt related commands (including wait IRQ with timeout
if
self
.
cmd
.
getStart
():
if
self
.
cmd
.
getStart
():
self
.
dut
.
_log
.
info
(
'Received START, waiting reset to be over'
)
self
.
dut
.
_log
.
info
(
'Received START, waiting reset to be over'
)
yield
Timer
(
10000
)
yield
Timer
(
10000
)
...
@@ -98,12 +119,18 @@ class X393_cocotb_server(object):
...
@@ -98,12 +119,18 @@ class X393_cocotb_server(object):
while
self
.
dut
.
reset_out
.
value
:
while
self
.
dut
.
reset_out
.
value
:
yield
Timer
(
10000
)
yield
Timer
(
10000
)
# Launch all bus masters (no need to join ever, preserving just in case
self
.
self
.
saxihp0r_thread
=
cocotb
.
fork
(
saxihp0r
.
saxi_rd_run
)
self
.
self
.
saxihp0w_thread
=
cocotb
.
fork
(
saxihp0w
.
saxi_wr_run
)
self
.
self
.
saxihp1w_thread
=
cocotb
.
fork
(
saxihp1w
.
saxi_wr_run
)
self
.
self
.
saxihp2w_thread
=
cocotb
.
fork
(
saxihp2w
.
saxi_wr_run
)
self
.
soc_conn
.
send
(
self
.
cmd
.
toJSON
(
0
)
+
"
\n
"
)
self
.
soc_conn
.
send
(
self
.
cmd
.
toJSON
(
0
)
+
"
\n
"
)
self
.
dut
.
_log
.
debug
(
'Sent 0 to the socket'
)
self
.
dut
.
_log
.
debug
(
'Sent 0 to the socket'
)
started
=
True
elif
self
.
cmd
.
getStop
():
elif
self
.
cmd
.
getStop
():
self
.
dut
.
_log
.
debug
(
'Received STOP, closing...'
)
self
.
dut
.
_log
.
info
(
'Received STOP, closing...'
)
self
.
soc_conn
.
send
(
self
.
cmd
.
toJSON
(
0
)
+
"
\n
"
)
self
.
soc_conn
.
send
(
self
.
cmd
.
toJSON
(
0
)
+
"
\n
"
)
self
.
soc_conn
.
close
()
self
.
soc_conn
.
close
()
yield
Timer
(
10000
)
# small pause for the wave output
yield
Timer
(
10000
)
# small pause for the wave output
...
@@ -111,36 +138,60 @@ class X393_cocotb_server(object):
...
@@ -111,36 +138,60 @@ class X393_cocotb_server(object):
self
.
socket_conn
.
shutdown
(
socket
.
SHUT_RDWR
)
self
.
socket_conn
.
shutdown
(
socket
.
SHUT_RDWR
)
self
.
socket_conn
.
close
()
self
.
socket_conn
.
close
()
cocotb
.
regression
.
tear_down
()
cocotb
.
regression
.
tear_down
()
started
=
False
raise
TestSuccess
(
'Terminating as received STOP command'
)
raise
TestSuccess
(
'Terminating as received STOP command'
)
#For now write - one at a time, TODO: a) consolidate, b) decode address (some will be just a disk file)
#For now write - one at a time, TODO: a) consolidate, b) decode address (some will be just a disk file)
elif
self
.
cmd
.
getWrite
():
elif
self
.
cmd
.
getWrite
():
ad
=
self
.
cmd
.
getWrite
()
ad
=
self
.
cmd
.
getWrite
()
self
.
dut
.
_log
.
info
(
'Received WRITE, 0x
%0
x:
%
s'
%
(
ad
[
0
],
str
(
ad
[
1
])))
self
.
dut
.
_log
.
info
(
'Received WRITE, 0x
%0
x:
%
s'
%
(
ad
[
0
],
str
(
ad
[
1
])))
rslt
=
yield
self
.
maxigp0
.
axi_write
(
address
=
ad
[
0
],
if
ad
[
0
]
<
0x40000000
:
value
=
ad
[
1
],
pass
byte_enable
=
None
,
elif
(
ad
[
0
]
>=
0x40000000
)
and
(
ad
[
0
]
<
0x80000000
):
id
=
self
.
writeID
,
rslt
=
yield
self
.
maxigp0
.
axi_write
(
address
=
ad
[
0
],
dsize
=
2
,
value
=
ad
[
1
],
burst
=
1
,
byte_enable
=
None
,
address_latency
=
0
,
id
=
self
.
writeID
,
data_latency
=
0
)
dsize
=
2
,
self
.
dut
.
_log
.
info
(
'maxigp0.axi_write yielded
%
s'
%
(
str
(
rslt
)))
burst
=
1
,
self
.
writeID
=
(
self
.
writeID
+
1
)
&
self
.
writeIDMask
address_latency
=
0
,
data_latency
=
0
)
self
.
dut
.
_log
.
info
(
'maxigp0.axi_write yielded
%
s'
%
(
str
(
rslt
)))
self
.
writeID
=
(
self
.
writeID
+
1
)
&
self
.
writeIDMask
elif
ad
[
0
]
>=
0xc0000000
:
self
.
ps_sbus
.
write_reg
(
ad
[
0
],
ad
[
1
][
0
])
rslt
=
0
else
:
self
.
dut
.
_log
.
info
(
'Write address 0x
%08
x is outside of maxgp0, not yet supported'
%
(
ad
[
0
]))
rslt
=
0
self
.
soc_conn
.
send
(
self
.
cmd
.
toJSON
(
rslt
)
+
"
\n
"
)
self
.
soc_conn
.
send
(
self
.
cmd
.
toJSON
(
rslt
)
+
"
\n
"
)
self
.
dut
.
_log
.
debug
(
'Sent rslt to the socket'
)
self
.
dut
.
_log
.
debug
(
'Sent rslt to the socket'
)
elif
self
.
cmd
.
getRead
():
elif
self
.
cmd
.
getRead
():
a
=
self
.
cmd
.
getRead
()
a
=
self
.
cmd
.
getRead
()
dval
=
yield
self
.
maxigp0
.
axi_read
(
address
=
a
,
if
a
<
0x40000000
:
id
=
self
.
readID
,
pass
dlen
=
1
,
if
(
a
>=
0x40000000
)
and
(
a
<
0x80000000
):
dsize
=
2
,
dval
=
yield
self
.
maxigp0
.
axi_read
(
address
=
a
,
address_latency
=
0
,
id
=
self
.
readID
,
data_latency
=
0
)
dlen
=
1
,
self
.
dut
.
_log
.
info
(
"axi_read returned => "
+
str
(
dval
))
dsize
=
2
,
self
.
readID
=
(
self
.
readID
+
1
)
&
self
.
readIDMask
address_latency
=
0
,
data_latency
=
0
)
self
.
dut
.
_log
.
info
(
"axi_read returned => "
+
str
(
dval
))
self
.
readID
=
(
self
.
readID
+
1
)
&
self
.
readIDMask
elif
ad
[
0
]
>=
0xc0000000
:
dval
=
yield
self
.
ps_sbus
.
read_reg
(
ad
[
0
])
else
:
self
.
dut
.
_log
.
info
(
'Read address 0x
%08
x is outside of maxgp0, not yet supported'
%
(
a
))
dval
=
[
0
]
self
.
soc_conn
.
send
(
self
.
cmd
.
toJSON
(
dval
)
+
"
\n
"
)
self
.
soc_conn
.
send
(
self
.
cmd
.
toJSON
(
dval
)
+
"
\n
"
)
self
.
dut
.
_log
.
debug
(
'Sent dval to the socket'
)
self
.
dut
.
_log
.
debug
(
'Sent dval to the socket'
)
def
flush_all
(
self
):
self
.
self
.
saxihp0w
.
flush
()
self
.
self
.
saxihp1w
.
flush
()
self
.
self
.
saxihp2w
.
flush
()
def
convert_string
(
txt
):
def
convert_string
(
txt
):
number
=
0
number
=
0
for
c
in
txt
:
for
c
in
txt
:
...
@@ -154,7 +205,7 @@ def run_test(dut, port=7777):
...
@@ -154,7 +205,7 @@ def run_test(dut, port=7777):
while
True
:
while
True
:
try
:
try
:
rslt
=
yield
tb
.
receiveCommandFromSocket
()
rslt
=
yield
tb
.
receiveCommandFromSocket
()
dut
.
_log
.
info
(
"rslt =
%
s"
%
(
str
(
rslt
)))
dut
.
_log
.
debug
(
"rslt =
%
s"
%
(
str
(
rslt
)))
except
ReturnValue
as
rv
:
except
ReturnValue
as
rv
:
line
=
rv
.
retval
;
line
=
rv
.
retval
;
dut
.
_log
.
info
(
"rv =
%
s"
%
(
str
(
rv
)))
dut
.
_log
.
info
(
"rv =
%
s"
%
(
str
(
rv
)))
...
...
cocotb/x393_dut.v
View file @
6a2bdfd7
This diff is collapsed.
Click to expand it.
cocotb/x393interfaces.py
View file @
6a2bdfd7
This diff is collapsed.
Click to expand it.
includes/x393_simulation_parameters.vh
View file @
6a2bdfd7
...
@@ -36,6 +36,8 @@
...
@@ -36,6 +36,8 @@
* with at least one of the Free Software programs.
* with at least one of the Free Software programs.
*/
*/
, // to continue previous parameter list
, // to continue previous parameter list
parameter NUM_INTERRUPTS = 9,
parameter integer AXI_RDADDR_LATENCY= 2, // 2, //2, //2,
parameter integer AXI_RDADDR_LATENCY= 2, // 2, //2, //2,
parameter integer AXI_WRADDR_LATENCY= 1, // 1, //2, //4,
parameter integer AXI_WRADDR_LATENCY= 1, // 1, //2, //4,
parameter integer AXI_WRDATA_LATENCY= 2, // 1, //1, //1
parameter integer AXI_WRDATA_LATENCY= 2, // 1, //1, //1
...
@@ -113,6 +115,8 @@
...
@@ -113,6 +115,8 @@
parameter FRAME_WIDTH_ROUND_BITS = 9, // multiple of 512 pixels (32 16-byte bursts) (11 - ful SDRAM page)
parameter FRAME_WIDTH_ROUND_BITS = 9, // multiple of 512 pixels (32 16-byte bursts) (11 - ful SDRAM page)
parameter WOI_WIDTH= 64,
parameter WOI_WIDTH= 64,
parameter WOI_HEIGHT= 32,
parameter QUADRANTS_PXD_HACT_VACT = 6'h01, // 2 bits each: data-0, hact - 1, vact - 2
parameter QUADRANTS_PXD_HACT_VACT = 6'h01, // 2 bits each: data-0, hact - 1, vact - 2
// 90-degree shifts for data [1:0], hact [3:2] and vact [5:4]
// 90-degree shifts for data [1:0], hact [3:2] and vact [5:4]
parameter SENSOR_PRIORITY = 1000
parameter SENSOR_PRIORITY = 1000
py393/cocoargs
0 → 100644
View file @
6a2bdfd7
-d TARGET_MODE=1
-f system_defines.vh
-f includes/x393_parameters.vh includes/x393_cur_params_target.vh includes/x393_localparams.vh includes/x393_simulation_parameters.vh
-l includes/x393_cur_params_target_gen.vh
-l includes/x393_cur_params_target_gen.vh
-p PICKLE="includes/x393_mcntrl.pickle"
-i
py393/test_mcntrl.py
View file @
6a2bdfd7
...
@@ -31,10 +31,13 @@ __version__ = "3.0+"
...
@@ -31,10 +31,13 @@ __version__ = "3.0+"
__maintainer__
=
"Andrey Filippov"
__maintainer__
=
"Andrey Filippov"
__email__
=
"andrey@elphel.com"
__email__
=
"andrey@elphel.com"
__status__
=
"Development"
__status__
=
"Development"
'''
'''
./test_mcntrl.py -v -f../system_defines.vh -f ../includes/x393_parameters.vh ../includes/x393_localparams.vh -pNEWPAR=
\'
h3ff -c write_mem 0x377 25 -c read_mem 0x3ff -i -d aaa=bbb -d ccc=ddd
./test_mcntrl.py -v -f../system_defines.vh -f ../includes/x393_parameters.vh ../includes/x393_localparams.vh -pNEWPAR=
\'
h3ff -c write_mem 0x377 25 -c read_mem 0x3ff -i -d aaa=bbb -d ccc=ddd
'''
'''
import
readline
import
sys
import
sys
import
os
import
os
import
inspect
import
inspect
...
@@ -94,15 +97,7 @@ class CLIError(Exception):
...
@@ -94,15 +97,7 @@ class CLIError(Exception):
return
self
.
msg
return
self
.
msg
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
self
.
msg
return
self
.
msg
'''
for name in x393_mem.X393Mem.__dict__:
if hasattr((x393_mem.X393Mem.__dict__[name]), '__call__') and not (name[0]=='_'):
func_args=x393_mem.X393Mem.__dict__[name].func_code.co_varnames[1:x393_mem.X393Mem.__dict__[name].func_code.co_argcount]
# print (name+": "+str(x393_mem.X393Mem.__dict__[name]))
# print ("args="+str(func_args))
print (name+": "+str(func_args))
'''
def
extractTasks
(
obj
,
inst
):
def
extractTasks
(
obj
,
inst
):
for
name
in
obj
.
__dict__
:
for
name
in
obj
.
__dict__
:
if
hasattr
((
obj
.
__dict__
[
name
]),
'__call__'
)
and
not
(
name
[
0
]
==
'_'
):
if
hasattr
((
obj
.
__dict__
[
name
]),
'__call__'
)
and
not
(
name
[
0
]
==
'_'
):
...
@@ -221,7 +216,7 @@ USAGE
...
@@ -221,7 +216,7 @@ USAGE
parser
.
add_argument
(
"-p"
,
"--parameter"
,
dest
=
"parameters"
,
action
=
"append"
,
default
=
[],
help
=
"Define parameter(s) as name=value"
,
nargs
=
'*'
)
parser
.
add_argument
(
"-p"
,
"--parameter"
,
dest
=
"parameters"
,
action
=
"append"
,
default
=
[],
help
=
"Define parameter(s) as name=value"
,
nargs
=
'*'
)
parser
.
add_argument
(
"-c"
,
"--command"
,
dest
=
"commands"
,
action
=
"append"
,
default
=
[],
help
=
"execute command"
,
nargs
=
'*'
)
parser
.
add_argument
(
"-c"
,
"--command"
,
dest
=
"commands"
,
action
=
"append"
,
default
=
[],
help
=
"execute command"
,
nargs
=
'*'
)
parser
.
add_argument
(
"-i"
,
"--interactive"
,
dest
=
"interactive"
,
action
=
"store_true"
,
help
=
"enter interactive mode [default:
%(default)
s]"
)
parser
.
add_argument
(
"-i"
,
"--interactive"
,
dest
=
"interactive"
,
action
=
"store_true"
,
help
=
"enter interactive mode [default:
%(default)
s]"
)
parser
.
add_argument
(
"-s"
,
"--simulated"
,
dest
=
"simulated"
,
action
=
"store
_true
"
,
help
=
"Simulated mode (no real hardware I/O) [default:
%(default)
s]"
)
parser
.
add_argument
(
"-s"
,
"--simulated"
,
dest
=
"simulated"
,
action
=
"store"
,
help
=
"Simulated mode (no real hardware I/O) [default:
%(default)
s]"
)
parser
.
add_argument
(
"-x"
,
"--exceptions"
,
dest
=
"exceptions"
,
action
=
"count"
,
help
=
"Exit on more exceptions [default:
%(default)
s]"
)
parser
.
add_argument
(
"-x"
,
"--exceptions"
,
dest
=
"exceptions"
,
action
=
"count"
,
help
=
"Exit on more exceptions [default:
%(default)
s]"
)
parser
.
add_argument
(
"-l"
,
"--localparams"
,
dest
=
"localparams"
,
action
=
"store"
,
default
=
""
,
parser
.
add_argument
(
"-l"
,
"--localparams"
,
dest
=
"localparams"
,
action
=
"store"
,
default
=
""
,
help
=
"path were modified parameters are saved [default:
%(default)
s]"
,
metavar
=
"path"
)
help
=
"path were modified parameters are saved [default:
%(default)
s]"
,
metavar
=
"path"
)
...
@@ -236,9 +231,11 @@ USAGE
...
@@ -236,9 +231,11 @@ USAGE
QUIET
=
(
1
,
0
)[
args
.
exceptions
]
QUIET
=
(
1
,
0
)[
args
.
exceptions
]
# print ("args.exception=%d, QUIET=%d"%(args.exceptions,QUIET))
# print ("args.exception=%d, QUIET=%d"%(args.exceptions,QUIET))
print
(
"args.simulated = "
,
args
.
simulated
)
print
(
"args = "
,
args
)
if
not
args
.
simulated
:
if
not
args
.
simulated
:
if
not
os
.
path
.
exists
(
"/dev/xdevcfg"
):
if
not
os
.
path
.
exists
(
"/dev/xdevcfg"
):
args
.
simulated
=
True
args
.
simulated
=
"simulated"
print
(
"Program is forced to run in SIMULATED mode as '/dev/xdevcfg' does not exist (not a camera)"
)
print
(
"Program is forced to run in SIMULATED mode as '/dev/xdevcfg' does not exist (not a camera)"
)
#print("--- defines=%s"% str(args.defines))
#print("--- defines=%s"% str(args.defines))
#print("--- paths=%s"% str(args.paths))
#print("--- paths=%s"% str(args.paths))
...
@@ -401,7 +398,7 @@ USAGE
...
@@ -401,7 +398,7 @@ USAGE
rslt
=
execTask
(
cmdLine
)
rslt
=
execTask
(
cmdLine
)
print
(
' Result: '
+
str
(
rslt
))
print
(
' Result: '
+
str
(
rslt
))
'''
'''
#TODO: use readline
#TODO: use readline
'''
'''
if
args
.
socket_port
:
if
args
.
socket_port
:
PORT
=
int
(
args
.
socket_port
)
# 8888
PORT
=
int
(
args
.
socket_port
)
# 8888
...
@@ -424,8 +421,10 @@ USAGE
...
@@ -424,8 +421,10 @@ USAGE
line
=
""
line
=
""
while
True
:
while
True
:
soc_conn
=
None
soc_conn
=
None
prompt
=
'x393
%
s +
%3.3
fs--> '
%
((
''
,
'(simulated)'
)[
args
.
simulated
],(
time
.
time
()
-
tim
))
prompt
=
'x393 (
%
s) +
%3.3
fs--> '
%
(
args
.
simulated
,(
time
.
time
()
-
tim
))
if
args
.
simulated
else
'x393 +
%3.3
fs--> '
%
(
time
.
time
()
-
tim
)
#prompt = 'x393%s +%3.3fs--> '%(args.simulated,(time.time()-tim))
if
socket_conn
:
if
socket_conn
:
print
(
"***socket_conn***"
)
print
(
prompt
,
end
=
""
)
print
(
prompt
,
end
=
""
)
sys
.
stdout
.
flush
()
sys
.
stdout
.
flush
()
if
(
args
.
socket_port
):
if
(
args
.
socket_port
):
...
...
py393/vrlg.py
View file @
6a2bdfd7
This diff is collapsed.
Click to expand it.
py393/x393_axi_control_status.py
View file @
6a2bdfd7
...
@@ -364,7 +364,10 @@ class X393AxiControlStatus(object):
...
@@ -364,7 +364,10 @@ class X393AxiControlStatus(object):
print
(
"MCNTRL_TEST01_STATUS_REG_CHN4_ADDR:
%
s"
%
(
hx
(
self
.
read_status
(
vrlg
.
MCNTRL_TEST01_STATUS_REG_CHN4_ADDR
),
8
)))
print
(
"MCNTRL_TEST01_STATUS_REG_CHN4_ADDR:
%
s"
%
(
hx
(
self
.
read_status
(
vrlg
.
MCNTRL_TEST01_STATUS_REG_CHN4_ADDR
),
8
)))
print
(
"MEMBRIDGE_STATUS_REG:
%
s"
%
(
hx
(
self
.
read_status
(
vrlg
.
MEMBRIDGE_STATUS_REG
),
8
)))
print
(
"MEMBRIDGE_STATUS_REG:
%
s"
%
(
hx
(
self
.
read_status
(
vrlg
.
MEMBRIDGE_STATUS_REG
),
8
)))
items_per_line
=
8
items_per_line
=
8
for
i
in
range
(
256
):
r
=
range
(
256
)
if
self
.
DRY_MODE
:
r
=
(
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
0x38
,
0x39
,
0x3a
,
0x3b
,
0x3c
,
0x3d
,
0x3e
,
0x3f
,
0xf8
,
0xf9
,
0xfa
,
0xfb
,
0xfc
,
0xfd
,
0xfe
,
0xff
)
for
i
in
r
:
if
not
i
%
items_per_line
:
if
not
i
%
items_per_line
:
print
(
"
\n
0x
%02
x: "
%
(
i
),
end
=
""
)
print
(
"
\n
0x
%02
x: "
%
(
i
),
end
=
""
)
d
=
hx
(
self
.
read_status
(
i
),
8
)
d
=
hx
(
self
.
read_status
(
i
),
8
)
...
...
py393/x393_mem.py
View file @
6a2bdfd7
...
@@ -32,6 +32,15 @@ import mmap
...
@@ -32,6 +32,15 @@ import mmap
#import sys
#import sys
import
struct
import
struct
import
os
import
os
import
sys
import
traceback
sys
.
path
.
append
(
os
.
path
.
abspath
(
os
.
path
.
dirname
(
sys
.
argv
[
0
])
+
'/../cocotb'
))
from
socket_command
import
x393Client
DBG_CNTR
=
0
X393_CLIENT
=
None
class
X393Mem
(
object
):
class
X393Mem
(
object
):
'''
'''
classdocs
classdocs
...
@@ -47,16 +56,40 @@ class X393Mem(object):
...
@@ -47,16 +56,40 @@ class X393Mem(object):
# 2.7.11 does not need subtraction(and reports error if negative)
# 2.7.11 does not need subtraction(and reports error if negative)
def
__init__
(
self
,
debug_mode
=
1
,
dry_mode
=
False
,
maxi_port
=
0
):
def
__init__
(
self
,
debug_mode
=
1
,
dry_mode
=
False
,
maxi_port
=
0
):
if
maxi_port
:
global
DBG_CNTR
self
.
MAXI_BASE
=
self
.
MAXI1_BASE
global
X393_CLIENT
else
:
"""
self
.
MAXI_BASE
=
self
.
MAXI0_BASE
;
print('dry_mode = ',dry_mode,', DBG_CNTR=',DBG_CNTR)
self
.
DEBUG_MODE
=
debug_mode
traceback.print_stack()
"""
if
not
dry_mode
:
if
not
dry_mode
:
if
not
os
.
path
.
exists
(
"/dev/xdevcfg"
):
if
not
os
.
path
.
exists
(
"/dev/xdevcfg"
):
dry_mode
=
True
dry_mode
=
True
print
(
"Program is forced to run in SIMULATED mode as '/dev/xdevcfg' does not exist (not a camera)"
)
print
(
"Program is forced to run in SIMULATED mode as '/dev/xdevcfg' does not exist (not a camera)"
)
self
.
DRY_MODE
=
dry_mode
self
.
DRY_MODE
=
dry_mode
if
(
dry_mode
)
and
(
X393_CLIENT
is
None
):
print
(
"Creating X393_CLIENT"
)
try
:
X393_CLIENT
=
x393Client
(
host
=
dry_mode
.
split
(
":"
)[
0
],
port
=
int
(
dry_mode
.
split
(
":"
)[
1
]))
print
(
"Created X393_CLIENT"
)
except
:
X393_CLIENT
=
True
print
(
"Failed to create X393_CLIENT"
)
if
not
X393_CLIENT
is
True
:
print
(
"Starting X393_CLIENT"
)
try
:
X393_CLIENT
.
start
()
except
:
print
(
"Failed to communicate to the server. Is it started? Swithching to dry tun mode"
)
X393_CLIENT
=
True
DBG_CNTR
+=
1
if
maxi_port
:
self
.
MAXI_BASE
=
self
.
MAXI1_BASE
else
:
self
.
MAXI_BASE
=
self
.
MAXI0_BASE
;
self
.
DEBUG_MODE
=
debug_mode
def
maxi_base
(
self
,
maxi_port
=
None
):
def
maxi_base
(
self
,
maxi_port
=
None
):
if
not
maxi_port
is
None
:
if
not
maxi_port
is
None
:
if
maxi_port
:
if
maxi_port
:
...
@@ -86,7 +119,20 @@ class X393Mem(object):
...
@@ -86,7 +119,20 @@ class X393Mem(object):
return
mmap
.
mmap
(
f
.
fileno
(),
self
.
PAGE_SIZE
,
offset
=
page_addr
-
(
1
<<
32
))
return
mmap
.
mmap
(
f
.
fileno
(),
self
.
PAGE_SIZE
,
offset
=
page_addr
-
(
1
<<
32
))
else
:
else
:
return
mmap
.
mmap
(
f
.
fileno
(),
self
.
PAGE_SIZE
,
offset
=
page_addr
)
return
mmap
.
mmap
(
f
.
fileno
(),
self
.
PAGE_SIZE
,
offset
=
page_addr
)
def
finish
(
self
):
"""
Finish simulation, if server is opened
"""
global
X393_CLIENT
if
X393_CLIENT
is
None
:
print
(
"Not running in simulated mode"
)
return
elif
X393_CLIENT
is
True
:
print
(
"Not running as a client to x393 simulation server"
)
return
else
:
X393_CLIENT
.
stop
()
X393_CLIENT
=
True
# just simulated mode
def
write_mem
(
self
,
addr
,
data
,
quiet
=
1
):
def
write_mem
(
self
,
addr
,
data
,
quiet
=
1
):
"""
"""
...
@@ -95,9 +141,17 @@ class X393Mem(object):
...
@@ -95,9 +141,17 @@ class X393Mem(object):
@param data - 32-bit data to write
@param data - 32-bit data to write
@param quiet - reduce output
@param quiet - reduce output
"""
"""
if
self
.
DRY_MODE
:
if
X393_CLIENT
is
True
:
# if self.DRY_MODE:
print
(
"simulated: write_mem(0x
%
x,0x
%
x)"
%
(
addr
,
data
))
print
(
"simulated: write_mem(0x
%
x,0x
%
x)"
%
(
addr
,
data
))
return
return
elif
not
X393_CLIENT
is
None
:
if
quiet
<
1
:
print
(
"remote: write_mem(0x
%
x,0x
%
x)"
%
(
addr
,
data
))
X393_CLIENT
.
write
(
addr
,
[
data
])
if
quiet
<
2
:
print
(
"remote: write_mem done"
)
return
with
open
(
"/dev/mem"
,
"r+b"
)
as
f
:
with
open
(
"/dev/mem"
,
"r+b"
)
as
f
:
page_addr
=
addr
&
(
~
(
self
.
PAGE_SIZE
-
1
))
page_addr
=
addr
&
(
~
(
self
.
PAGE_SIZE
-
1
))
page_offs
=
addr
-
page_addr
page_offs
=
addr
-
page_addr
...
@@ -108,7 +162,7 @@ class X393Mem(object):
...
@@ -108,7 +162,7 @@ class X393Mem(object):
packedData
=
struct
.
pack
(
self
.
ENDIAN
+
"L"
,
data
)
packedData
=
struct
.
pack
(
self
.
ENDIAN
+
"L"
,
data
)
d
=
struct
.
unpack
(
self
.
ENDIAN
+
"L"
,
packedData
)[
0
]
d
=
struct
.
unpack
(
self
.
ENDIAN
+
"L"
,
packedData
)[
0
]
mm
[
page_offs
:
page_offs
+
4
]
=
packedData
mm
[
page_offs
:
page_offs
+
4
]
=
packedData
if
quiet
<
1
:
if
quiet
<
2
:
print
(
"0x
%08
x <== 0x
%08
x (
%
d)"
%
(
addr
,
d
,
d
))
print
(
"0x
%08
x <== 0x
%08
x (
%
d)"
%
(
addr
,
d
,
d
))
'''
'''
if MONITOR_EMIO and VEBOSE:
if MONITOR_EMIO and VEBOSE:
...
@@ -125,7 +179,19 @@ class X393Mem(object):
...
@@ -125,7 +179,19 @@ class X393Mem(object):
Read 32-bit word from physical memory
Read 32-bit word from physical memory
@param addr physical byte address
@param addr physical byte address
@param quiet - reduce output
@param quiet - reduce output
'''
'''
if
X393_CLIENT
is
True
:
# if self.DRY_MODE:
print
(
"simulated: read_mem(0x
%
x)"
%
(
addr
))
return
addr
# just some data
elif
not
X393_CLIENT
is
None
:
if
quiet
<
1
:
print
(
"remote: read_mem(0x
%
x)"
%
(
addr
))
data
=
X393_CLIENT
.
read
(
addr
)
if
quiet
<
1
:
print
(
"remote: read_mem done: 0x
%08
x"
%
(
data
[
0
]))
return
data
[
0
]
if
self
.
DRY_MODE
:
if
self
.
DRY_MODE
:
print
(
"simulated: read_mem(0x
%
x)"
%
(
addr
))
print
(
"simulated: read_mem(0x
%
x)"
%
(
addr
))
return
addr
# just some data
return
addr
# just some data
...
...
py393/x393_sens_cmprs.py
View file @
6a2bdfd7
...
@@ -124,9 +124,10 @@ SENSOR_INTERFACES={x393_sensor.SENSOR_INTERFACE_PARALLEL: {"mv":2800, "freq":24.
...
@@ -124,9 +124,10 @@ SENSOR_INTERFACES={x393_sensor.SENSOR_INTERFACE_PARALLEL: {"mv":2800, "freq":24.
# x393_sensor.SENSOR_INTERFACE_HISPI: {"mv":2500, "freq":24.444, "iface":"1V8_LVDS"}}
# x393_sensor.SENSOR_INTERFACE_HISPI: {"mv":2500, "freq":24.444, "iface":"1V8_LVDS"}}
SENSOR_DEFAULTS
=
{
x393_sensor
.
SENSOR_INTERFACE_PARALLEL
:
{
"width"
:
2592
,
"height"
:
1944
,
"top"
:
0
,
"left"
:
0
,
"slave"
:
0x48
,
"i2c_delay"
:
100
,
"bayer"
:
3
},
SENSOR_DEFAULTS
=
{
x393_sensor
.
SENSOR_INTERFACE_PARALLEL
:
{
"width"
:
2592
,
"height"
:
1944
,
"top"
:
0
,
"left"
:
0
,
"slave"
:
0x48
,
"i2c_delay"
:
100
,
"bayer"
:
3
},
# SENSOR_INTERFACE_HISPI: {"width":4608, "height":3288, "top":0, "left":0, "slave":0x10, "i2c_delay":100}}
x393_sensor
.
SENSOR_INTERFACE_HISPI
:
{
"width"
:
4384
,
"height"
:
3288
,
"top"
:
0
,
"left"
:
0
,
"slave"
:
0x10
,
"i2c_delay"
:
100
,
"bayer"
:
2
}}
x393_sensor
.
SENSOR_INTERFACE_HISPI
:
{
"width"
:
4384
,
"height"
:
3288
,
"top"
:
0
,
"left"
:
0
,
"slave"
:
0x10
,
"i2c_delay"
:
100
,
"bayer"
:
2
}}
#SENSOR_DEFAULTS_SIMULATION= {x393_sensor.SENSOR_INTERFACE_PARALLEL: {"width":2592, "height":1944, "top":0, "left":0, "slave":0x48, "i2c_delay":100, "bayer":3},
# x393_sensor.SENSOR_INTERFACE_HISPI: {"width":4384, "height":3288, "top":0, "left":0, "slave":0x10, "i2c_delay":100, "bayer":2}}
class
X393SensCmprs
(
object
):
class
X393SensCmprs
(
object
):
DRY_MODE
=
True
# True
DRY_MODE
=
True
# True
DEBUG_MODE
=
1
DEBUG_MODE
=
1
...
@@ -147,8 +148,25 @@ class X393SensCmprs(object):
...
@@ -147,8 +148,25 @@ class X393SensCmprs(object):
def
__init__
(
self
,
debug_mode
=
1
,
dry_mode
=
True
,
saveFileName
=
None
):
def
__init__
(
self
,
debug_mode
=
1
,
dry_mode
=
True
,
saveFileName
=
None
):
# global BUFFER_ADDRESS, BUFFER_LEN
# global BUFFER_ADDRESS, BUFFER_LEN
global
BUFFER_ADDRESS
,
BUFFER_LEN
,
COMMAND_ADDRESS
,
DATAIN_ADDRESS
,
DATAOUT_ADDRESS
global
BUFFER_ADDRESS
,
BUFFER_LEN
,
COMMAND_ADDRESS
,
DATAIN_ADDRESS
,
DATAOUT_ADDRESS
global
BUFFER_ADDRESS_H2D
,
BUFFER_LEN_H2D
,
BUFFER_ADDRESS_D2H
,
BUFFER_LEN_D2H
,
BUFFER_ADDRESS_BIDIR
,
BUFFER_LEN_BIDIR
global
BUFFER_ADDRESS_H2D
,
BUFFER_LEN_H2D
,
BUFFER_ADDRESS_D2H
,
BUFFER_LEN_D2H
,
BUFFER_ADDRESS_BIDIR
,
BUFFER_LEN_BIDIR
# global SENSOR_DEFAULTS_SIMULATION
print
(
"X393SensCmprs.__init__: dry_mode="
,
dry_mode
)
try
:
if
":"
in
dry_mode
:
print
(
"X393SensCmprs.__init__: setting SENSOR_DEFAULTS"
)
SENSOR_DEFAULTS
[
x393_sensor
.
SENSOR_INTERFACE_PARALLEL
][
"width"
]
=
vrlg
.
WOI_WIDTH
+
4
SENSOR_DEFAULTS
[
x393_sensor
.
SENSOR_INTERFACE_PARALLEL
][
"height"
]
=
vrlg
.
WOI_HEIGHT
+
4
SENSOR_DEFAULTS
[
x393_sensor
.
SENSOR_INTERFACE_PARALLEL
][
"top"
]
=
0
SENSOR_DEFAULTS
[
x393_sensor
.
SENSOR_INTERFACE_PARALLEL
][
"left"
]
=
0
SENSOR_DEFAULTS
[
x393_sensor
.
SENSOR_INTERFACE_HISPI
][
"width"
]
=
vrlg
.
WOI_WIDTH
+
4
SENSOR_DEFAULTS
[
x393_sensor
.
SENSOR_INTERFACE_HISPI
][
"height"
]
=
vrlg
.
WOI_HEIGHT
+
4
SENSOR_DEFAULTS
[
x393_sensor
.
SENSOR_INTERFACE_HISPI
][
"top"
]
=
0
SENSOR_DEFAULTS
[
x393_sensor
.
SENSOR_INTERFACE_HISPI
][
"left"
]
=
0
print
(
"Using simulation size sensor defaults "
,
SENSOR_DEFAULTS
)
except
:
print
(
"No simulation server is used, just running in dry mode"
)
self
.
DEBUG_MODE
=
debug_mode
self
.
DEBUG_MODE
=
debug_mode
self
.
DRY_MODE
=
dry_mode
self
.
DRY_MODE
=
dry_mode
self
.
x393_mem
=
X393Mem
(
debug_mode
,
dry_mode
)
self
.
x393_mem
=
X393Mem
(
debug_mode
,
dry_mode
)
...
@@ -2112,11 +2130,16 @@ class X393SensCmprs(object):
...
@@ -2112,11 +2130,16 @@ class X393SensCmprs(object):
elif
direction
.
upper
()[
0
]
in
"B"
:
elif
direction
.
upper
()[
0
]
in
"B"
:
return
"_bidir"
return
"_bidir"
def
sync_for_cpu
(
self
,
direction
,
saddr
=
None
,
leng
=
None
):
def
sync_for_cpu
(
self
,
direction
,
saddr
=
None
,
leng
=
None
):
if
self
.
DRY_MODE
:
print
(
"Simulating sync_for_cpu(),"
,
self
.
get_mem_buf_args
(
saddr
,
leng
),
" -> "
,
MEM_PATH
+
BUFFER_FOR_CPU
+
self
.
_get_dma_dir_suffix
(
direction
))
return
with
open
(
MEM_PATH
+
BUFFER_FOR_CPU
+
self
.
_get_dma_dir_suffix
(
direction
),
"w"
)
as
f
:
with
open
(
MEM_PATH
+
BUFFER_FOR_CPU
+
self
.
_get_dma_dir_suffix
(
direction
),
"w"
)
as
f
:
print
(
self
.
get_mem_buf_args
(
saddr
,
leng
),
file
=
f
)
print
(
self
.
get_mem_buf_args
(
saddr
,
leng
),
file
=
f
)
def
sync_for_device
(
self
,
direction
,
saddr
=
None
,
leng
=
None
):
def
sync_for_device
(
self
,
direction
,
saddr
=
None
,
leng
=
None
):
if
self
.
DRY_MODE
:
print
(
"Simulating sync_for_device(),"
,
self
.
get_mem_buf_args
(
saddr
,
leng
),
" -> "
,
MEM_PATH
+
BUFFER_FOR_DEVICE
+
self
.
_get_dma_dir_suffix
(
direction
))
return
with
open
(
MEM_PATH
+
BUFFER_FOR_DEVICE
+
self
.
_get_dma_dir_suffix
(
direction
),
"w"
)
as
f
:
with
open
(
MEM_PATH
+
BUFFER_FOR_DEVICE
+
self
.
_get_dma_dir_suffix
(
direction
),
"w"
)
as
f
:
print
(
self
.
get_mem_buf_args
(
saddr
,
leng
),
file
=
f
)
print
(
self
.
get_mem_buf_args
(
saddr
,
leng
),
file
=
f
)
"""
"""
...
@@ -2175,7 +2198,7 @@ jpeg_write "img.jpeg" 0 100 None False 0 "/www/pages/" 3
...
@@ -2175,7 +2198,7 @@ jpeg_write "img.jpeg" 0 100 None False 0 "/www/pages/" 3
"""
"""
# Setup for compression of t
eh
simulated data
# Setup for compression of t
he
simulated data
def
setup_simulated_mode
(
self
,
def
setup_simulated_mode
(
self
,
data_file
=
None
,
data_file
=
None
,
chn
=
0
,
chn
=
0
,
...
...
py393/x393_sensor.py
View file @
6a2bdfd7
...
@@ -70,7 +70,7 @@ class X393Sensor(object):
...
@@ -70,7 +70,7 @@ class X393Sensor(object):
Get sensor interface type by reading status register 0xfe that is set to 0 for parallel and 1 for HiSPi
Get sensor interface type by reading status register 0xfe that is set to 0 for parallel and 1 for HiSPi
@return "PAR12" or "HISPI"
@return "PAR12" or "HISPI"
"""
"""
if
self
.
DRY_MODE
:
if
self
.
DRY_MODE
is
True
:
return
SENSOR_INTERFACE_PARALLEL
return
SENSOR_INTERFACE_PARALLEL
return
(
SENSOR_INTERFACE_PARALLEL
,
SENSOR_INTERFACE_HISPI
)[
self
.
x393_axi_tasks
.
read_status
(
address
=
0xfe
)]
# "PAR12" , "HISPI"
return
(
SENSOR_INTERFACE_PARALLEL
,
SENSOR_INTERFACE_HISPI
)[
self
.
x393_axi_tasks
.
read_status
(
address
=
0xfe
)]
# "PAR12" , "HISPI"
...
...
simulation_modules/sim_soc_interrupts.v
View file @
6a2bdfd7
...
@@ -36,7 +36,7 @@ module sim_soc_interrupts #(
...
@@ -36,7 +36,7 @@ module sim_soc_interrupts #(
input
[
NUM_INTERRUPTS
-
1
:
0
]
irq_done
,
// end of ISR, turn off inta bit, re-enable arbitration
input
[
NUM_INTERRUPTS
-
1
:
0
]
irq_done
,
// end of ISR, turn off inta bit, re-enable arbitration
output
[
NUM_INTERRUPTS
-
1
:
0
]
irqs
,
// synchronized by clock masked interrupts
output
[
NUM_INTERRUPTS
-
1
:
0
]
irqs
,
// synchronized by clock masked interrupts
output
[
NUM_INTERRUPTS
-
1
:
0
]
inta
,
// interrupt acknowledge
output
[
NUM_INTERRUPTS
-
1
:
0
]
inta
,
// interrupt acknowledge
output
main_go
// enable main th
er
ad to proceed
output
main_go
// enable main th
re
ad to proceed
)
;
)
;
reg
[
NUM_INTERRUPTS
-
1
:
0
]
inta_r
;
reg
[
NUM_INTERRUPTS
-
1
:
0
]
inta_r
;
...
...
simulation_modules/simul_axi_fifo_out.v
View file @
6a2bdfd7
...
@@ -64,34 +64,37 @@ module simul_axi_fifo
...
@@ -64,34 +64,37 @@ module simul_axi_fifo
integer
out_count
;
integer
out_count
;
reg
[
LATENCY
:
0
]
latency_delay_r
;
reg
[
LATENCY
:
0
]
latency_delay_r
;
wire
[
LATENCY
+
1
:
0
]
latency_delay
={
latency_delay_r
,
load
};
wire
out_inc
=
latency_delay
[
LATENCY
]
;
wire
out_inc
=
latency_delay
[
LATENCY
]
;
wire
input_ready_w
=
in_count
<
DEPTH
;
wire
load_and_ready
=
load
&
input_ready_w
;
// Masked load with input_ready 07/06/2016
wire
[
LATENCY
+
1
:
0
]
latency_delay
={
latency_delay_r
,
load_and_ready
};
assign
data_out
=
fifo
[
out_address
]
;
assign
data_out
=
fifo
[
out_address
]
;
assign
valid
=
out_count
!=
0
;
assign
valid
=
out_count
!=
0
;
assign
input_ready
=
in_count
<
DEPTH
;
assign
input_ready
=
input_ready_w
;
// assign out_inc={
// assign out_inc={
always
@
(
posedge
clk
or
posedge
reset
)
begin
always
@
(
posedge
clk
or
posedge
reset
)
begin
if
(
reset
)
latency_delay_r
<=
0
;
if
(
reset
)
latency_delay_r
<=
0
;
else
latency_delay_r
<=
latency_delay
[
LATENCY
:
0
]
;
else
latency_delay_r
<=
latency_delay
[
LATENCY
:
0
]
;
if
(
reset
)
in_address
<=
0
;
if
(
reset
)
in_address
<=
0
;
else
if
(
load
)
in_address
<=
(
in_address
==
(
FIFO_DEPTH
-
1
))
?
0
:
in_address
+
1
;
else
if
(
load
_and_ready
)
in_address
<=
(
in_address
==
(
FIFO_DEPTH
-
1
))
?
0
:
in_address
+
1
;
if
(
reset
)
out_address
<=
0
;
if
(
reset
)
out_address
<=
0
;
else
if
(
valid
&&
ready
)
out_address
<=
(
out_address
==
(
FIFO_DEPTH
-
1
))
?
0
:
out_address
+
1
;
else
if
(
valid
&&
ready
)
out_address
<=
(
out_address
==
(
FIFO_DEPTH
-
1
))
?
0
:
out_address
+
1
;
if
(
reset
)
in_count
<=
0
;
if
(
reset
)
in_count
<=
0
;
else
if
(
!
(
valid
&&
ready
)
&&
load
)
in_count
<=
in_count
+
1
;
else
if
(
!
(
valid
&&
ready
)
&&
load
_and_ready
)
in_count
<=
in_count
+
1
;
else
if
(
valid
&&
ready
&&
!
load
)
in_count
<=
in_count
-
1
;
else
if
(
valid
&&
ready
&&
!
load
_and_ready
)
in_count
<=
in_count
-
1
;
if
(
reset
)
out_count
<=
0
;
if
(
reset
)
out_count
<=
0
;
else
if
(
!
(
valid
&&
ready
)
&&
out_inc
)
out_count
<=
out_count
+
1
;
else
if
(
!
(
valid
&&
ready
)
&&
out_inc
)
out_count
<=
out_count
+
1
;
else
if
(
valid
&&
ready
&&
!
out_inc
)
out_count
<=
out_count
-
1
;
else
if
(
valid
&&
ready
&&
!
out_inc
)
out_count
<=
out_count
-
1
;
end
end
always
@
(
posedge
clk
)
begin
always
@
(
posedge
clk
)
begin
if
(
load
)
fifo
[
in_address
]
<=
data_in
;
if
(
load
_and_ready
)
fifo
[
in_address
]
<=
data_in
;
end
end
endmodule
endmodule
\ No newline at end of file
simulation_modules/simul_axi_hp_rd.v
View file @
6a2bdfd7
...
@@ -81,7 +81,8 @@ module simul_axi_hp_rd #(
...
@@ -81,7 +81,8 @@ module simul_axi_hp_rd #(
input
reg_wr
,
input
reg_wr
,
input
reg_rd
,
input
reg_rd
,
input
[
31
:
0
]
reg_din
,
input
[
31
:
0
]
reg_din
,
output
[
31
:
0
]
reg_dout
output
[
31
:
0
]
reg_dout
,
output
reg_dvalid
// register output data valid
)
;
)
;
localparam
AFI_BASECTRL
=
32'hf8008000
+
(
HP_PORT
<<
12
)
;
localparam
AFI_BASECTRL
=
32'hf8008000
+
(
HP_PORT
<<
12
)
;
localparam
AFI_RDCHAN_CTRL
=
AFI_BASECTRL
+
'h00
;
localparam
AFI_RDCHAN_CTRL
=
AFI_BASECTRL
+
'h00
;
...
@@ -162,7 +163,10 @@ module simul_axi_hp_rd #(
...
@@ -162,7 +163,10 @@ module simul_axi_hp_rd #(
{
25'b0
,
rdIssueCap1
,
1'b0
,
rdIssueCap0
}:
{
25'b0
,
rdIssueCap1
,
1'b0
,
rdIssueCap0
}:
(
(
reg_rd
&&
(
reg_addr
==
AFI_RDQOS
))
?
(
(
reg_rd
&&
(
reg_addr
==
AFI_RDQOS
))
?
{
28'b0
,
rdStaticQos
}:
32'bz
)))
;
{
28'b0
,
rdStaticQos
}:
32'bz
)))
;
assign
reg_dvalid
=
(
reg_rd
&&
((
reg_addr
==
AFI_RDDATAFIFO_LEVEL
)
||
(
reg_addr
==
AFI_RDCHAN_CTRL
)
||
(
reg_addr
==
AFI_RDCHAN_ISSUINGCAP
)
||
(
reg_addr
==
AFI_RDQOS
)))
?
1
:
0
;
always
@
(
posedge
aclk
or
posedge
rst
)
begin
always
@
(
posedge
aclk
or
posedge
rst
)
begin
if
(
rst
)
begin
if
(
rst
)
begin
rdQosHeadOfCmdQEn
<=
0
;
rdQosHeadOfCmdQEn
<=
0
;
...
...
simulation_modules/simul_axi_hp_wr.v
View file @
6a2bdfd7
...
@@ -87,7 +87,8 @@ module simul_axi_hp_wr#(
...
@@ -87,7 +87,8 @@ module simul_axi_hp_wr#(
input
reg_wr
,
input
reg_wr
,
input
reg_rd
,
input
reg_rd
,
input
[
31
:
0
]
reg_din
,
input
[
31
:
0
]
reg_din
,
output
[
31
:
0
]
reg_dout
output
[
31
:
0
]
reg_dout
,
output
reg_dvalid
)
;
)
;
// localparam ADDRESS_BITS=32;
// localparam ADDRESS_BITS=32;
localparam
AFI_BASECTRL
=
32'hf8008000
+
(
HP_PORT
<<
12
)
;
localparam
AFI_BASECTRL
=
32'hf8008000
+
(
HP_PORT
<<
12
)
;
...
@@ -179,6 +180,10 @@ UPDATE: Xilinx docs say that (AR/AW)CACHE is ignored
...
@@ -179,6 +180,10 @@ UPDATE: Xilinx docs say that (AR/AW)CACHE is ignored
{
25'b0
,
wrIssueCap1
,
1'b0
,
wrIssueCap0
}:
{
25'b0
,
wrIssueCap1
,
1'b0
,
wrIssueCap0
}:
(
(
reg_rd
&&
(
reg_addr
==
AFI_WRQOS
))
?
(
(
reg_rd
&&
(
reg_addr
==
AFI_WRQOS
))
?
{
28'b0
,
staticQos
}:
32'bz
)))
;
{
28'b0
,
staticQos
}:
32'bz
)))
;
assign
reg_dvalid
=
(
reg_rd
&&
((
reg_addr
==
AFI_WRDATAFIFO_LEVEL
)
||
(
reg_addr
==
AFI_WRCHAN_CTRL
)
||
(
reg_addr
==
AFI_WRCHAN_ISSUINGCAP
)
||
(
reg_addr
==
AFI_WRQOS
)))
?
1
:
0
;
always
@
(
posedge
aclk
or
posedge
rst
)
begin
always
@
(
posedge
aclk
or
posedge
rst
)
begin
if
(
rst
)
begin
if
(
rst
)
begin
...
...
simulation_modules/simul_axi_master_wdata.v
View file @
6a2bdfd7
...
@@ -82,14 +82,13 @@ simul_axi_fifo
...
@@ -82,14 +82,13 @@ simul_axi_fifo
.
LATENCY
(
LATENCY
)
,
// minimal delay between inout and output ( 0 - next cycle)
.
LATENCY
(
LATENCY
)
,
// minimal delay between inout and output ( 0 - next cycle)
.
DEPTH
(
DEPTH
)
// maximal number of commands in FIFO
.
DEPTH
(
DEPTH
)
// maximal number of commands in FIFO
)
simul_axi_fifo_i
(
)
simul_axi_fifo_i
(
.
clk
(
clk
)
,
// input clk,
.
clk
(
clk
)
,
// input clk,
.
reset
(
reset
)
,
// input reset,
.
reset
(
reset
)
,
// input reset,
.
data_in
(
{
wid_in
,
wdata_in
,
wstrb_in
,
wlast_in
}
)
,
// input [WIDTH-1:0] data_in,
.
data_in
(
{
wid_in
,
wdata_in
,
wstrb_in
,
wlast_in
}
)
,
// input [WIDTH-1:0] data_in,
.
load
(
set_cmd
)
,
// input load,
.
load
(
set_cmd
)
,
// input load,
.
input_ready
(
ready
)
,
// output input_ready,
.
input_ready
(
ready
)
,
// output input_ready,
.
data_out
(
{
wid_out
,
wdata_out
,
wstrb_out
,
wlast_out
}
)
,
// output [WIDTH-1:0] data_out,
.
data_out
(
{
wid_out
,
wdata_out
,
wstrb_out
,
wlast_out
}
)
,
// output [WIDTH-1:0] data_out,
.
valid
(
wvalid_out
)
,
// output valid,
.
valid
(
wvalid_out
)
,
// output valid,
.
ready
(
wready
))
;
// input ready);
.
ready
(
wready
))
;
// input ready);
endmodule
endmodule
x393_testbench03.tf
View file @
6a2bdfd7
...
@@ -155,7 +155,7 @@ parameter NUM_INTERRUPTS = 9;
...
@@ -155,7 +155,7 @@ parameter NUM_INTERRUPTS = 9;
parameter
BLANK_ROWS_BEFORE
=
8
;
// 1; //8; ///2+2 - a little faster than compressor
parameter
BLANK_ROWS_BEFORE
=
8
;
// 1; //8; ///2+2 - a little faster than compressor
parameter
BLANK_ROWS_AFTER
=
8
;
// 1; //8;
parameter
BLANK_ROWS_AFTER
=
8
;
// 1; //8;
`
endif
`
endif
parameter
WOI_HEIGHT
=
32
;
//
parameter WOI_HEIGHT= 32;
parameter
TRIG_LINES
=
8
;
parameter
TRIG_LINES
=
8
;
parameter
VBLANK
=
2
;
/// 2 lines //SuppressThisWarning Veditor UNUSED
parameter
VBLANK
=
2
;
/// 2 lines //SuppressThisWarning Veditor UNUSED
parameter
CYCLES_PER_PIXEL
=
3
;
/// 2 for JP4, 3 for JPEG // SuppressThisWarning VEditor - not used
parameter
CYCLES_PER_PIXEL
=
3
;
/// 2 for JP4, 3 for JPEG // SuppressThisWarning VEditor - not used
...
@@ -2303,7 +2303,8 @@ simul_axi_hp_rd #(
...
@@ -2303,7 +2303,8 @@ simul_axi_hp_rd #(
.reg_wr (PS_REG_WR), // input
.reg_wr (PS_REG_WR), // input
.reg_rd (PS_REG_RD), // input
.reg_rd (PS_REG_RD), // input
.reg_din (PS_REG_DIN), // input[31:0]
.reg_din (PS_REG_DIN), // input[31:0]
.reg_dout (PS_REG_DOUT) // output[31:0]
.reg_dout (PS_REG_DOUT), // output[31:0]
.reg_dvalid ()
);
);
simul_axi_hp_wr #(
simul_axi_hp_wr #(
...
@@ -2349,7 +2350,8 @@ simul_axi_hp_wr #(
...
@@ -2349,7 +2350,8 @@ simul_axi_hp_wr #(
.reg_wr (PS_REG_WR), // input
.reg_wr (PS_REG_WR), // input
.reg_rd (PS_REG_RD), // input
.reg_rd (PS_REG_RD), // input
.reg_din (PS_REG_DIN), // input[31:0]
.reg_din (PS_REG_DIN), // input[31:0]
.reg_dout (PS_REG_DOUT) // output[31:0]
.reg_dout (PS_REG_DOUT), // output[31:0]
.reg_dvalid ()
);
);
// afi1 - from compressor
// afi1 - from compressor
simul_axi_hp_wr #(
simul_axi_hp_wr #(
...
@@ -2395,7 +2397,8 @@ simul_axi_hp_wr #(
...
@@ -2395,7 +2397,8 @@ simul_axi_hp_wr #(
.reg_wr (PS_REG_WR1), // input
.reg_wr (PS_REG_WR1), // input
.reg_rd (PS_REG_RD1), // input
.reg_rd (PS_REG_RD1), // input
.reg_din (PS_REG_DIN), // input[31:0]
.reg_din (PS_REG_DIN), // input[31:0]
.reg_dout (PS_REG_DOUT1) // output[31:0]
.reg_dout (PS_REG_DOUT1), // output[31:0]
.reg_dvalid ()
);
);
// SAXI_GP0 - histograms to system memory
// SAXI_GP0 - histograms to system memory
...
...
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