Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
M
Mock Turtle
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
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
Mock Turtle
Commits
ef467fd5
Commit
ef467fd5
authored
Apr 13, 2018
by
Dimitris Lampridis
Committed by
Adam Wujek
Apr 16, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sim: update testbenches to be compatible with current HDL. Tested, works.
parent
64b016b6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
621 additions
and
899 deletions
+621
-899
mock_turtle_driver.svh
hdl/testbench/include/mock_turtle_driver.svh
+140
-23
mt_config_rom_driver.svh
hdl/testbench/include/mt_config_rom_driver.svh
+20
-4
mt_cpu_csr_driver.svh
hdl/testbench/include/mt_cpu_csr_driver.svh
+56
-58
mt_hmq_driver.svh
hdl/testbench/include/mt_hmq_driver.svh
+257
-0
mt_mqueue_host_driver.svh
hdl/testbench/include/mt_mqueue_host_driver.svh
+0
-403
mt_queue_message.svh
hdl/testbench/include/mt_queue_message.svh
+44
-0
serializable.svh
hdl/testbench/include/serializable.svh
+0
-161
main.sv
hdl/testbench/mock_turtle_core/main.sv
+85
-32
run.do
hdl/testbench/mock_turtle_core/run.do
+5
-3
run_ci.do
hdl/testbench/mock_turtle_core/run_ci.do
+1
-1
wave.do
hdl/testbench/mock_turtle_core/wave.do
+0
-116
main.sv
hdl/testbench/svec_mt_demo/main.sv
+8
-96
sim-verif.c
tests/firmware/sim-verif/sim-verif.c
+5
-2
No files found.
hdl/testbench/include/mock_turtle_driver.svh
View file @
ef467fd5
...
...
@@ -27,47 +27,164 @@
`define
__MOCK_TURTLE_DRIVER_INCLUDED
`include
"simdrv_defs.svh"
`include
"if_wishbone_accessor.svh"
`include
"mt_cpu_csr_driver.svh"
`include
"mt_mqueue_host_driver.svh"
`include
"mt_queue_message.svh"
`include
"mt_hmq_driver.svh"
`include
"mt_config_rom_driver.svh"
// Simple interface to deliver the four interrupts of MT to the
// MockTurtleDriver class below
interface
IMockTurtleIRQ
(
input
logic
hmq_in
,
input
logic
hmq_out
,
input
logic
notify
,
input
logic
console
)
;
endinterface
// IMockTurtleIRQ
// Macro to simplify attaching one side of the interface to signals
// in mock_turtle_core.vhd.
// (The "other" side is monitored by the MockTurtleDriver class below)
`define
MT_ATTACH_IRQ
(
mt
)
\
.
hmq_in
(
mt
.
hmq_in_irq
),
\
.
hmq_out
(
mt
.
hmq_out_irq
),
\
.
notify
(
mt
.
notify_irq
),
\
.
console
(
mt
.
console_irq
)
// A class can only accept virtual interfaces, so we declare it here
typedef
virtual
IMockTurtleIRQ
vIMockTurtleIRQ
;
// The main class, to monitor and drive the complete MT
class
MockTurtleDriver
;
protected
CBusAccessor
m_acc
;
protected
uint64_t
m_base
;
MTCPUControl
m_csr
;
MQueueHost
m_hmq
;
MTConfigRom
m_rom
;
function
new
(
CBusAccessor
acc
,
uint64_t
base
)
;
m_acc
=
acc
;
m_base
=
base
;
protected
CWishboneAccessor
acc
;
protected
uint64_t
base
;
protected
uint32_t
core_count
;
protected
MTCPUControl
csr
;
protected
MQueueHost
hmq
[]
;
protected
MTConfigRom
rom
;
protected
vIMockTurtleIRQ
irq
;
// When set to 0, parent application will need
// to clear notification irqs manually
protected
bit
autoclear_notify
;
function
new
(
CWishboneAccessor
acc
,
uint64_t
base
,
vIMockTurtleIRQ
irq
,
bit
autoclear_notify
=
1'b1
)
;
this
.
acc
=
acc
;
this
.
base
=
base
;
this
.
irq
=
irq
;
endfunction
// new
task
init
()
;
m_csr
=
new
(
m_acc
,
m_base
+
'hc000
)
;
m_hmq
=
new
(
m_acc
,
m_base
+
'h0000
)
;
m_rom
=
new
(
m_acc
,
m_base
+
'he000
)
;
m_csr
.
init
()
;
m_hmq
.
init
()
;
m_rom
.
init
()
;
task
init
(
wb_cycle_type_t
mode
=
PIPELINED
)
;
uint32_t
slot_count
;
wb_set_mode
(
mode
)
;
// first init the config ROM, to be able to get core count etc.
rom
=
new
(
acc
,
base
+
'he000
)
;
rom
.
init
()
;
core_count
=
rom
.
getCoreCount
()
;
$
display
(
"App ID: 0x%x"
,
rom
.
getAppID
)
;
$
display
(
"Core count: %0d"
,
core_count
)
;
// Next init the MT CSR
csr
=
new
(
acc
,
base
+
'hc000
,
core_count
)
;
csr
.
init
()
;
// Host message queue objects are one per cpu core
hmq
=
new
[
core_count
]
;
for
(
int
i
=
0
;
i
<
core_count
;
i
++
)
begin
slot_count
=
rom
.
getHmqSlotCount
(
i
)
;
// CSR is passed to each queue to be able to select slot
// inside the class via csr.hmq_select()
hmq
[
i
]
=
new
(
acc
,
base
+
'h0000
,
i
,
csr
,
slot_count
)
;
hmq
[
i
]
.
init
()
;
end
endtask
// init
task
load_firmware
(
int
core
,
string
filename
,
bit
check
=
1'b1
)
;
m_
csr
.
load_firmware
(
core
,
filename
,
check
)
;
csr
.
load_firmware
(
core
,
filename
,
check
)
;
endtask
// load_firmware
task
reset_core
(
int
core
,
int
reset
)
;
m_
csr
.
reset_core
(
core
,
reset
)
;
csr
.
reset_core
(
core
,
reset
)
;
endtask
// reset_core
task
cfg_rom_display
()
;
m_
rom
.
pretty_print
()
;
rom
.
pretty_print
()
;
endtask
// cfg_rom_display
// polls HMQ and Debug UART
task
cfg_rom_dump
()
;
rom
.
dump
()
;
endtask
// cfg_rom_dump
task
wb_set_mode
(
wb_cycle_type_t
mode
)
;
acc
.
set_mode
(
mode
)
;
endtask
// wb_set_mode
task
enable_console_irq
(
int
core
,
int
enable
)
;
csr
.
debug_int_enable
(
core
,
enable
)
;
endtask
// enable_console_irq
task
enable_hmq_irq
(
int
core
,
int
queue
,
int
enable
)
;
hmq
[
core
]
.
slot_int_enable
(
queue
,
enable
)
;
endtask
// enable_hmq_irq
task
smem_read
(
input
uint32_t
offset
,
ref
uint32_t
val
)
;
uint64_t
tmp
;
acc
.
read
(
base
+
32'h1_0000
+
offset
,
tmp
)
;
val
=
tmp
;
endtask
// smem_read
task
smem_write
(
uint32_t
offset
,
uint32_t
val
)
;
acc
.
write
(
base
+
32'h1_0000
+
offset
,
val
)
;
endtask
// smem_write
task
get_cpu_notifications
(
ref
uint32_t
val
)
;
val
=
0
;
if
(
csr
.
notify_queue
.
size
()
==
0
)
return
;
while
(
csr
.
notify_queue
.
size
()
!=
0
)
val
|=
csr
.
notify_queue
.
pop_front
()
;
endtask
// get_cpu_notifications
task
clear_cpu_notifications
(
uint32_t
val
)
;
csr
.
clear_notification_irq
(
val
)
;
endtask
// clear_cpu_notifications
task
handle_hmq_in_irq
()
;
endtask
// handle_hmq_in_irq
task
hmq_receive_message
(
ref
MQueueMsg
msg
)
;
msg
=
hmq
[
msg
.
core
]
.
receive_message
(
msg
.
slot
)
;
endtask
// hmq_receive_message
task
hmq_send_message
(
input
MQueueMsg
msg
)
;
hmq
[
msg
.
core
]
.
send_message
(
msg
.
slot
,
msg
)
;
endtask
// hmq_send_message
function
bit
hmq_pending_messages
(
uint32_t
core
,
uint32_t
slot
)
;
return
hmq
[
core
]
.
pending_in
(
slot
)
;
endfunction
// hmq_pending_messages
task
update
()
;
m_csr
.
update
()
;
m_hmq
.
update
()
;
uint32_t
val
;
if
(
irq
.
console
==
1'b1
)
begin
csr
.
check_consoles
()
;
end
if
(
irq
.
notify
==
1'b1
)
begin
csr
.
handle_notification_irq
(
autoclear_notify
)
;
end
if
(
irq
.
hmq_in
==
1'b1
)
begin
for
(
int
i
=
0
;
i
<
core_count
;
i
++
)
begin
hmq
[
i
]
.
receive_pending
()
;
end
end
for
(
int
i
=
0
;
i
<
core_count
;
i
++
)
begin
hmq
[
i
]
.
send_pending
()
;
end
endtask
// update
endclass
// MockTurtleDriver
...
...
hdl/testbench/include/mt_config_rom_driver.svh
View file @
ef467fd5
...
...
@@ -60,6 +60,22 @@ class MTConfigRom;
return
m_data
[
pos
]
;
endfunction
// read
function
uint32_t
getAppID
()
;
return
read
(
5
)
;
endfunction
// getAppID
function
uint32_t
getCoreCount
()
;
return
read
(
6
)
;
endfunction
// getCoreCount
function
uint32_t
getHmqSlotCount
(
int
core
)
;
return
read
(
16
+
core
)
;
endfunction
// getHmqSlotCount
function
uint32_t
getRmqSlotCount
(
int
core
)
;
return
read
(
24
+
core
)
;
endfunction
// getRmqSlotCount
task
dump
()
;
int
i
;
...
...
@@ -71,7 +87,7 @@ class MTConfigRom;
task
pretty_print
(
)
;
int
i
,
j
;
int
cpu_count
=
read
(
6
)
;
int
cpu_count
=
getCoreCount
(
)
;
$
display
(
"Configuration ROM contents:"
)
;
$
display
(
" Magic Value : %0s"
,
read
(
0
)
)
;
...
...
@@ -79,14 +95,14 @@ class MTConfigRom;
$
display
(
" Clock Frequency : %0d"
,
read
(
3
)
)
;
$
display
(
" WR support : %0s"
,
read
(
4
)
&
1
?
"yes"
:
"no"
)
;
$
display
(
" RMQ support : %0s"
,
read
(
4
)
&
2
?
"yes"
:
"no"
)
;
$
display
(
" Application ID : %0x"
,
read
(
5
)
)
;
$
display
(
" Application ID : %0x"
,
getAppID
(
)
)
;
$
display
(
" Shared mem size : %0d"
,
read
(
7
)
)
;
$
display
(
" CPU count : %0d"
,
cpu_count
)
;
for
(
i
=
0
;
i
<
cpu_count
;
i
++
)
begin
int
hmq_slots
=
read
(
16
+
i
)
;
int
rmq_slots
=
read
(
24
+
i
)
;
int
hmq_slots
=
getHmqSlotCount
(
i
)
;
int
rmq_slots
=
getRmqSlotCount
(
i
)
;
$
display
(
" CPU #%0d"
,
i
)
;
$
display
(
" Local mem size : %0d"
,
read
(
8
+
i
)
)
;
$
display
(
" HMQ slots : %0d"
,
hmq_slots
)
;
...
...
hdl/testbench/include/mt_cpu_csr_driver.svh
View file @
ef467fd5
...
...
@@ -41,27 +41,17 @@ class MTCPUControl;
protected
CBusAccessor
bus
;
protected
uint32_t
base
;
protected
uint32_t
app_id
;
protected
uint32_t
core_count
;
protected
uint32_t
core_memsizes
[$]
;
protected
uint32_t
notify_irq_mask
;
protected
string
dbg_msg_queue
[]
;
function
new
(
CBusAccessor
bus_
,
input
uint32_t
base_
)
;
base
=
base_
;
bus
=
bus_
;
endfunction
// new
function
uint32_t
getAppID
()
;
return
app_id
;
endfunction
// getAppID
function
uint32_t
getCoreCount
()
;
return
core_count
;
endfunction
// getCoreCount
uint32_t
notify_queue
[$]
;
function
uint32_t
getCoreMemorySize
(
int
core
)
;
return
core_memsizes
[
core
]
;
endfunction
// getCoreMemorySize
function
new
(
CBusAccessor
bus
,
input
uint32_t
base
,
int
core_count
)
;
this
.
base
=
base
;
this
.
bus
=
bus
;
this
.
core_count
=
core_count
;
endfunction
// new
task
writel
(
uint32_t
r
,
uint32_t
v
)
;
bus
.
write
(
base
+
r
,
v
)
;
...
...
@@ -74,27 +64,9 @@ class MTCPUControl;
endtask
// readl
task
init
()
;
int
i
;
$
display
(
"Init CSR driver"
)
;
readl
(
`ADDR_MT_CPU_CSR_APP_ID
,
app_id
)
;
readl
(
`ADDR_MT_CPU_CSR_CORE_COUNT
,
core_count
)
;
core_count
&=
'hf
;
$
display
(
"App ID: 0x%x"
,
app_id
)
;
$
display
(
"Core count: %0d"
,
core_count
)
;
dbg_msg_queue
=
new
[
core_count
]
;
for
(
i
=
0
;
i
<
core_count
;
i
++
)
begin
uint32_t
memsize
;
writel
(
`ADDR_MT_CPU_CSR_CORE_SEL
,
i
)
;
readl
(
`ADDR_MT_CPU_CSR_CORE_MEMSIZE
,
memsize
)
;
$
display
(
"Core %1d: %3d kB private memory"
,
i
,
memsize
/
1024
)
;
core_memsizes
.
push_back
(
memsize
)
;
end
notify_irq_mask
=
0
;
notify_queue
=
{};
dbg_msg_queue
=
new
[
core_count
]
;
endtask
// init
task
reset_core
(
int
core
,
int
reset
)
;
...
...
@@ -126,7 +98,7 @@ class MTCPUControl;
// Stop in case of error.
if
(
f
==
0
)
$
exit
;
$
exit
;
reset_core
(
core
,
1
)
;
...
...
@@ -144,22 +116,22 @@ class MTCPUControl;
end
// while (!$feof(f))
if
(
check
)
begin
void
'
($
rewind
(
f
))
;
begin
void
'
($
rewind
(
f
))
;
for
(
i
=
0
;
i
<
addr
;
i
++
)
for
(
i
=
0
;
i
<
addr
;
i
++
)
begin
uint32_t
rv
,
data
;
writel
(
`ADDR_MT_CPU_CSR_UADDR
,
i
)
;
readl
(
`ADDR_MT_CPU_CSR_UDATA
,
rv
)
;
uint32_t
rv
,
data
;
writel
(
`ADDR_MT_CPU_CSR_UADDR
,
i
)
;
readl
(
`ADDR_MT_CPU_CSR_UDATA
,
rv
)
;
void
'
($
fread
(
data
,
f
))
;
assert
(
rv
==
data
)
else
$
fatal
(
"verification error at %x, got %x, expected %x
\n
"
,
i
,
rv
,
data
)
;
void
'
($
fread
(
data
,
f
))
;
assert
(
rv
==
data
)
else
$
fatal
(
"verification error at %x, got %x, expected %x
\n
"
,
i
,
rv
,
data
)
;
end
end
end
$
fclose
(
f
)
;
endtask
// load_firmware
...
...
@@ -168,6 +140,7 @@ class MTCPUControl;
uint32_t
rval
,
cpu_mask
;
readl
(
`ADDR_MT_CPU_CSR_DBG_POLL
,
cpu_mask
)
;
if
(
cpu_mask
==
0
)
return
;
...
...
@@ -182,19 +155,44 @@ class MTCPUControl;
if
(
rval
==
0
||
rval
==
13
||
rval
==
10
)
begin
$
display
(
"DBG MSG Core %0d: %s"
,
i
,
dbg_msg_queue
[
i
])
;
dbg_msg_queue
[
i
]
=
""
;
dbg_msg_queue
[
i
]
=
""
;
end
else
dbg_msg_queue
[
i
]
=
{
dbg_msg_queue
[
i
]
,
rval
[
7
:
0
]
};
else
dbg_msg_queue
[
i
]
=
{
dbg_msg_queue
[
i
]
,
rval
[
7
:
0
]
};
end
endtask
task
check_c2h_interrupts
()
;
uint32_t
val
;
task
get_notification_irq
(
ref
uint32_t
val
)
;
readl
(
`ADDR_MT_CPU_CSR_INT
,
val
)
;
if
(
val
!=
0
)
$
display
(
"C2H interrupts: %x"
,
val
)
;
endtask
endtask
// get_notification_irq
task
get_hmq_in_status
(
ref
uint64_t
val
)
;
uint32_t
tmp
;
readl
(
`ADDR_MT_CPU_CSR_HMQI_STATUS_LO
,
tmp
)
;
val
=
tmp
;
readl
(
`ADDR_MT_CPU_CSR_HMQI_STATUS_HI
,
tmp
)
;
val
|=
tmp
<<
32
;
endtask
// get_hmq_in_status
task
clear_notification_irq
(
uint32_t
val
)
;
writel
(
`ADDR_MT_CPU_CSR_INT
,
val
)
;
notify_irq_mask
&=
~
val
;
endtask
// clear_notification_irq
task
handle_notification_irq
(
input
bit
autoclear_notify
=
1'b1
)
;
uint32_t
val
;
get_notification_irq
(
val
)
;
if
(
val
&
~
notify_irq_mask
)
notify_queue
.
push_back
(
val
)
;
notify_irq_mask
|=
val
;
if
(
val
!=
0
&&
autoclear_notify
==
1'b1
)
clear_notification_irq
(
val
)
;
endtask
// handle_notification_irq
task
hmq_select
(
uint32_t
core
,
uint32_t
queue
)
;
uint32_t
val
=
(
core
&&
'b111
)
<<
3
|
(
queue
&&
'b111
)
;
writel
(
`ADDR_MT_CPU_CSR_HMQ_SEL
,
val
)
;
endtask
;
// hmq_select
task
update
()
;
check_consoles
()
;
...
...
hdl/testbench/include/mt_hmq_driver.svh
0 → 100644
View file @
ef467fd5
//------------------------------------------------------------------------------
// CERN BE-CO-HT
// Mock Turtle
// https://gitlab.cern.ch/coht/mockturtle
//------------------------------------------------------------------------------
//
// unit name: MQueueHost
//
// description: A SystemVerilog Class to provide an abstraction of the
// MockTurtle core's host message queue.
//
//------------------------------------------------------------------------------
// Copyright CERN 2018
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`ifndef
__
MT_MQUEUE_HOST_DRIVER_INCLUDED
`define
__MT_MQUEUE_HOST_DRIVER_INCLUDED
`define
MQUEUE_BASE_IN
('
h4000
)
`define
MQUEUE_BASE_OUT
('
h8000
)
`define
MQUEUE_CMD_CLAIM
(
1
<<
24
)
`define
MQUEUE_CMD_PURGE
(
1
<<
25
)
`define
MQUEUE_CMD_READY
(
1
<<
26
)
`define
MQUEUE_CMD_DISCARD
(
1
<<
27
)
`define
MQUEUE_SLOT_COMMAND 0
`define
MQUEUE_SLOT_STATUS 4
`define
MQUEUE_SLOT_HEADER 16
'
h1000
`define
MQUEUE_SLOT_DATA 16
'
h2000
`define
MQUEUE_GCR_SLOT_COUNT 0
`define
MQUEUE_GCR_SLOT_STATUS 4
`define
MQUEUE_GCR_IRQ_MASK 8
`define
MQUEUE_GCR_IRQ_COALESCE 12
`include
"mt_queue_message.svh"
class
MQueueHost
;
protected
CBusAccessor
bus
;
protected
uint32_t
base
;
protected
uint32_t
core
;
protected
uint32_t
slot_count
;
protected
MTCPUControl
csr
;
typedef
MQueueMsg
slot_queue_t
[$]
;
slot_queue_t
slots_in
[]
,
slots_out
[]
;
function
new
(
CBusAccessor
bus
,
uint32_t
base
,
uint32_t
core
,
MTCPUControl
csr
,
uint32_t
slot_count
)
;
this
.
base
=
base
;
this
.
bus
=
bus
;
this
.
core
=
core
;
this
.
csr
=
csr
;
this
.
slot_count
=
slot_count
;
endfunction
// new
task
init
()
;
this
.
slots_in
=
new
[
slot_count
]
;
this
.
slots_out
=
new
[
slot_count
]
;
for
(
int
i
=
0
;
i
<
slot_count
;
i
++
)
begin
this
.
slots_in
[
i
]
=
{};
this
.
slots_out
[
i
]
=
{};
csr
.
hmq_select
(
core
,
i
)
;
incoming_purge
()
;
outgoing_purge
()
;
end
endtask
// init
task
read
(
uint32_t
offset
,
output
uint32_t
rv
)
;
uint64_t
tmp
;
bus
.
read
(
base
+
offset
,
tmp
)
;
rv
=
tmp
;
endtask
// read
task
write
(
uint32_t
offset
,
uint32_t
rv
)
;
bus
.
write
(
base
+
offset
,
rv
)
;
endtask
// write
task
get_irq_mask
(
ref
uint32_t
val
)
;
read
(
`MQUEUE_GCR_IRQ_MASK
,
val
)
;
endtask
// get_irq_mask
task
set_irq_mask
(
input
uint32_t
val
)
;
write
(
`MQUEUE_GCR_IRQ_MASK
,
val
)
;
endtask
// set_irq_mask
task
slot_int_enable
(
int
slot
,
int
enable
)
;
uint32_t
imsk
;
csr
.
hmq_select
(
core
,
slot
)
;
get_irq_mask
(
imsk
)
;
if
(
enable
)
imsk
|=
(
1
<<
slot
)
;
else
imsk
&=
~
(
1
<<
slot
)
;
set_irq_mask
(
imsk
)
;
endtask
// slot_int_enable
task
incoming_write
(
uint32_t
r
,
uint32_t
v
)
;
write
(
`MQUEUE_BASE_IN
+
r
,
v
)
;
endtask
// incoming_write
task
outgoing_write
(
uint32_t
r
,
uint32_t
v
)
;
write
(
`MQUEUE_BASE_OUT
+
r
,
v
)
;
endtask
// outgoing_write
task
incoming_read
(
uint32_t
r
,
ref
uint32_t
v
)
;
read
(
`MQUEUE_BASE_IN
+
r
,
v
)
;
endtask
// incoming_read
task
outgoing_read
(
uint32_t
r
,
ref
uint32_t
v
)
;
read
(
`MQUEUE_BASE_OUT
+
r
,
v
)
;
endtask
// outgoing_read
task
incoming_purge
()
;
incoming_write
(
`MQUEUE_SLOT_COMMAND
,
`MQUEUE_CMD_PURGE
)
;
endtask
// incoming_purge
task
outgoing_purge
()
;
outgoing_write
(
`MQUEUE_SLOT_COMMAND
,
`MQUEUE_CMD_PURGE
)
;
endtask
// outgoing_purge
task
incoming_check_full
(
output
int
full
)
;
uint32_t
rv
;
incoming_read
(
`MQUEUE_SLOT_STATUS
,
rv
)
;
full
=
(
rv
&
1
)
?
1
:
0
;
endtask
// incoming_check_full
task
outgoing_check_full
(
output
int
full
)
;
uint32_t
rv
;
outgoing_read
(
`MQUEUE_SLOT_STATUS
,
rv
)
;
full
=
(
rv
&
1
)
?
1
:
0
;
endtask
// outgoing_check_full
task
slot_send
(
int
slot
)
;
MQueueMsg
msg
;
csr
.
hmq_select
(
core
,
slot
)
;
msg
=
slots_out
[
slot
]
.
pop_back
()
;
outgoing_write
(
`MQUEUE_SLOT_COMMAND
,
`MQUEUE_CMD_CLAIM
)
;
for
(
int
i
=
0
;
i
<
msg
.
header
.
size
()
;
i
++
)
begin
outgoing_write
(
`MQUEUE_SLOT_HEADER
+
i
*
4
,
msg
.
header
[
i
])
;
end
for
(
int
i
=
0
;
i
<
msg
.
data
.
size
()
;
i
++
)
begin
outgoing_write
(
`MQUEUE_SLOT_DATA
+
i
*
4
,
msg
.
data
[
i
])
;
end
outgoing_write
(
`MQUEUE_SLOT_COMMAND
,
`MQUEUE_CMD_READY
)
;
endtask
// slot_send
task
slot_recv
(
int
slot
)
;
MQueueMsg
msg
;
uint32_t
val
;
csr
.
hmq_select
(
core
,
slot
)
;
msg
=
new
(
core
,
slot
)
;
incoming_read
(
`MQUEUE_SLOT_HEADER
+
0
,
val
)
;
msg
.
header
[
0
]
=
val
;
incoming_read
(
`MQUEUE_SLOT_HEADER
+
4
,
val
)
;
msg
.
header
[
1
]
=
val
;
for
(
int
i
=
0
;
i
<
msg
.
header
[
0
]
;
i
++
)
begin
incoming_read
(
`MQUEUE_SLOT_DATA
+
4
*
i
,
val
)
;
msg
.
data
.
push_back
(
val
)
;
end
incoming_write
(
`MQUEUE_SLOT_COMMAND
,
`MQUEUE_CMD_DISCARD
)
;
slots_in
[
slot
]
.
push_front
(
msg
)
;
endtask
// slot_recv
function
MQueueMsg
receive_message
(
int
slot
)
;
MQueueMsg
ret
=
slots_in
[
slot
]
.
pop_back
()
;
return
ret
;
endfunction
// receive_message
function
void
send_message
(
int
slot
,
MQueueMsg
msg
)
;
slots_out
[
slot
]
.
push_front
(
msg
)
;
endfunction
// send_message
function
bit
pending_in
(
int
slot
)
;
return
slots_in
[
slot
]
.
size
()
!=
0
?
1'b1
:
1'b0
;
endfunction
// pending_in
task
receive_pending
()
;
uint64_t
stat
;
uint32_t
core_stat
;
uint32_t
imask
;
csr
.
get_hmq_in_status
(
stat
)
;
core_stat
=
(
stat
>>
(
core
*
8
))
&
'hff
;
if
(
core_stat
==
0
)
return
;
csr
.
hmq_select
(
core
,
0
)
;
get_irq_mask
(
imask
)
;
core_stat
&=
imask
;
if
(
core_stat
==
0
)
return
;
for
(
int
i
=
0
;
i
<
slot_count
;
i
++
)
begin
csr
.
hmq_select
(
core
,
i
)
;
if
(
core_stat
&
(
1
<<
i
))
slot_recv
(
i
)
;
end
endtask
// receive_pending
task
send_pending
()
;
uint32_t
full
;
for
(
int
i
=
0
;
i
<
slot_count
;
i
++
)
begin
while
(
slots_out
[
i
]
.
size
()
)
begin
csr
.
hmq_select
(
core
,
i
)
;
outgoing_check_full
(
full
)
;
if
(
full
)
break
;
slot_send
(
i
)
;
end
end
endtask
// send_pending
endclass
// MQueueHost
`endif
// `ifndef __MT_MQUEUE_HOST_DRIVER_INCLUDED
hdl/testbench/include/mt_mqueue_host_driver.svh
deleted
100644 → 0
View file @
64b016b6
This diff is collapsed.
Click to expand it.
hdl/testbench/include/mt_queue_message.svh
0 → 100644
View file @
ef467fd5
//------------------------------------------------------------------------------
// CERN BE-CO-HT
// Mock Turtle
// https://gitlab.cern.ch/coht/mockturtle
//------------------------------------------------------------------------------
//
// unit name: MQueueMsg
//
// description: A SystemVerilog Class to provide an abstraction of the
// MockTurtle core's queue message.
//
//------------------------------------------------------------------------------
// Copyright CERN 2018
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`ifndef
__
MT_MQUEUE_MSG_INCLUDED
`define
__MT_MQUEUE_MSG_INCLUDED
class
MQueueMsg
;
int
core
;
int
slot
;
uint32_t
header
[$]
;
uint32_t
data
[$]
;
function
new
(
int
core
=
0
,
int
slot
=
0
)
;
this
.
core
=
core
;
this
.
slot
=
slot
;
this
.
header
=
{};
this
.
data
=
{};
endfunction
// new
endclass
// MQueueMsg
`endif
// `ifndef __MT_MQUEUE_MSG_INCLUDED
hdl/testbench/include/serializable.svh
deleted
100644 → 0
View file @
64b016b6
//------------------------------------------------------------------------------
// CERN BE-CO-HT
// Mock Turtle
// https://gitlab.cern.ch/coht/mockturtle
//------------------------------------------------------------------------------
//
// unit name: Serializable
//
// description: A SystemVerilog Class representing a serializable object.
//
//------------------------------------------------------------------------------
// Copyright CERN 2018
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`ifndef
__
SERIALIZABLE_SVH
`define
__SERIALIZABLE_SVH
`include
"simdrv_defs.svh"
typedef
byte
int8_t
;
typedef
byte
unsigned
uint8_t
;
typedef
uint8_t
uint8_array_t
[$]
;
class
ByteBuffer
;
uint8_t
data
[$]
;
int
pos
;
function
new
()
;
pos
=
0
;
endfunction
// new
function
ByteBuffer
copy
()
;
copy
=
new
()
;
copy
.
pos
=
this
.
pos
;
copy
.
data
=
this
.
data
;
return
copy
;
endfunction
// copy
task
automatic
clear
()
;
data
=
'
{};
pos
=
0
;
endtask
// clear
task
dump
()
;
int
i
;
$
display
(
"buffer has %d bytes"
,
data
.
size
())
;
for
(
i
=
0
;
i
<
data
.
size
()
;
i
++
)
$
display
(
"%d: %x"
,
i
,
data
[
i
])
;
endtask
// dump
function
int
size
()
;
return
data
.
size
()
;
endfunction
// size
function
int
getPos
()
;
return
pos
;
endfunction
// getPos
function
automatic
void
setPos
(
int
pos_
)
;
pos
=
pos_
;
endfunction
// setPos
function
automatic
void
addByte
(
uint8_t
c
)
;
data
.
push_back
(
c
)
;
endfunction
// addByte
function
automatic
void
addShort
(
uint32_t
c
)
;
data
.
push_back
((
c
>>
8
)
&
'hff
)
;
data
.
push_back
(
c
&
'hff
)
;
endfunction
// addShort
function
automatic
void
addWord
(
uint32_t
c
)
;
data
.
push_back
((
c
>>
24
)
&
'hff
)
;
data
.
push_back
((
c
>>
16
)
&
'hff
)
;
data
.
push_back
((
c
>>
8
)
&
'hff
)
;
data
.
push_back
(
c
&
'hff
)
;
endfunction
// addWord
function
automatic
void
addBytes
(
uint8_t
d
[$]
)
;
for
(
int
i
=
0
;
i
<
d
.
size
()
;
i
++
)
data
.
push_back
(
d
[
i
])
;
endfunction
// addBytes
function
automatic
uint8_t
getByte
()
;
automatic
uint8_t
rv
=
data
[
pos
++
]
;
return
rv
;
endfunction
// getByte
function
automatic
uint8_t
at
(
int
pos_
)
;
return
data
[
pos_
]
;
endfunction
function
automatic
uint8_array_t
getBytes
(
int
count
)
;
automatic
uint8_array_t
rv
;
for
(
int
i
=
0
;
i
<
count
;
i
++
)
rv
.
push_back
(
data
[
pos
++
])
;
return
rv
;
endfunction
// getBytes
function
automatic
uint32_t
getWord
()
;
automatic
uint32_t
rv
;
rv
=
data
[
pos
++
]
;
rv
<<=
8
;
rv
|=
data
[
pos
++
]
;
rv
<<=
8
;
rv
|=
data
[
pos
++
]
;
rv
<<=
8
;
rv
|=
data
[
pos
++
]
;
return
rv
;
endfunction
// getWord
function
automatic
void
reset
()
;
pos
=
0
;
endfunction
endclass
// ByteBuffer
class
Serializable
;
protected
ByteBuffer
m_data
;
virtual
function
automatic
void
serialize
(
ByteBuffer
data
)
;
endfunction
// serialize
virtual
function
automatic
void
deserialize
(
ByteBuffer
data
)
;
m_data
=
data
;
endfunction
// deserialize
virtual
task
automatic
dump
()
;
if
(
!
m_data
)
return
;
m_data
.
dump
()
;
endtask
// dump
function
automatic
void
deserializeBytes
(
uint8_t
data
[$])
;
automatic
ByteBuffer
b
=
new
;
b
.
data
=
data
;
deserialize
(
b
)
;
endfunction
// deserializeBytes
endclass
// Serializable
`endif
// `ifndef __SERIALIZABLE_SVH
hdl/testbench/mock_turtle_core/main.sv
View file @
ef467fd5
...
...
@@ -26,6 +26,8 @@
`include
"mock_turtle_driver.svh"
`include
"vhd_wishbone_master.svh"
import
mock_turtle_pkg
::*;
`timescale
1
ns
/
1
ps
module
main
;
...
...
@@ -33,6 +35,9 @@ module main;
reg
rst_n
=
0
;
reg
clk_sys
=
0
;
t_mt_stream_source_out_array2d
rmq_src_out
;
t_mt_stream_source_in_array2d
rmq_src_in
;
always
#
8
ns
clk_sys
<=
~
clk_sys
;
initial
begin
...
...
@@ -40,55 +45,103 @@ module main;
rst_n
=
1
;
end
IVHDWishboneMaster
Host
(
clk_sys
,
rst_n
)
;
mock_turtle_core
#
()
DUT
(
.
clk_i
(
clk_sys
)
,
.
rst_n_i
(
rst_n
)
,
.
host_slave_i
(
Host
.
out
)
,
.
host_slave_o
(
Host
.
in
)
,
.
sp_master_o
()
,
.
sp_master_i
()
,
.
dp_master_o
()
,
.
dp_master_i
()
,
.
rmq_src_o
(
)
,
.
rmq_s
rc_i
(
)
,
.
rmq_snk_o
(
)
,
.
rmq_s
nk_i
(
)
,
.
clk_ref_i
()
,
.
tm_i
()
,
.
gpio_o
()
,
.
gpio_i
()
,
.
hmq_in_irq_o
()
,
.
clk_i
(
clk_sys
)
,
.
rst_n_i
(
rst_n
)
,
.
host_slave_i
(
Host
.
out
)
,
.
host_slave_o
(
Host
.
in
)
,
.
sp_master_o
()
,
.
sp_master_i
()
,
.
dp_master_o
()
,
.
dp_master_i
()
,
.
rmq_src_o
(
rmq_src_out
)
,
.
rmq_s
nk_i
(
rmq_src_out
)
,
.
rmq_snk_o
(
rmq_src_in
)
,
.
rmq_s
rc_i
(
rmq_src_in
)
,
.
clk_ref_i
()
,
.
tm_i
()
,
.
gpio_o
()
,
.
gpio_i
()
,
.
hmq_in_irq_o
()
,
.
hmq_out_irq_o
()
,
.
notify_irq_o
()
,
.
notify_irq_o
()
,
.
console_irq_o
()
)
;
initial
begin
IVHDWishboneMaster
Host
(
clk_sys
,
rst_n
)
;
static
string
fw
=
"../../../demos/hello_world/firmware/fw-01/fw-hello.bin"
;
IMockTurtleIRQ
IrqMonitor
(
`MT_ATTACH_IRQ
(
DUT
))
;
string
fw
=
"../../../tests/firmware/sim-verif/sim-verif.bin"
;
const
uint64_t
mt_base
=
'h0000
;
MockTurtleDriver
drv
;
uint64_t
count
;
task
inc_counter
()
;
uint32_t
val
;
drv
.
smem_read
(
0
,
val
)
;
if
(
val
!=
count
)
$
fatal
(
1
,
"incorrect count (%0d, expected %0d)"
,
val
,
count
)
;
count
++;
drv
.
smem_write
(
0
,
count
)
;
endtask
// inc_counter
task
check_cpu_notifications
()
;
uint32_t
val
;
drv
.
get_cpu_notifications
(
val
)
;
if
(
val
)
begin
if
(
val
&
'h1
)
inc_counter
()
;
drv
.
clear_cpu_notifications
(
val
)
;
end
endtask
// check_cpu_notifications
task
check_hmq_incoming
()
;
// check from pending messages in core 0, slot 0
while
(
drv
.
hmq_pending_messages
(
0
,
0
))
begin
// Get a message from core 0, slot 0
automatic
MQueueMsg
msg
=
new
(
0
,
0
)
;
drv
.
hmq_receive_message
(
msg
)
;
//$display(msg);
inc_counter
()
;
for
(
int
i
=
0
;
i
<
msg
.
data
.
size
()
;
i
++
)
msg
.
data
[
i
]
=
~
msg
.
data
[
i
]
;
drv
.
hmq_send_message
(
msg
)
;
end
endtask
// check_hmq_incoming
CWishboneAccessor
acc
;
MockTurtleDriver
drv
;
initial
begin
count
=
0
;
#
10u
s
;
acc
=
Host
.
get_accessor
()
;
acc
.
set_mode
(
PIPELINED
)
;
drv
=
new
(
Host
.
get_accessor
()
,
mt_base
,
IrqMonitor
,
1'b0
)
;
drv
=
new
(
acc
,
'h20000
)
;
drv
.
init
()
;
drv
.
load_firmware
(
0
,
fw
,
1'b0
)
;
drv
.
reset_core
(
0
,
0
)
;
drv
.
enable_console_irq
(
0
,
1
)
;
drv
.
enable_hmq_irq
(
0
,
0
,
1
)
;
drv
.
load_firmware
(
0
,
fw
,
1'b0
)
;
drv
.
reset_core
(
0
,
0
)
;
forever
begin
drv
.
update
()
;
#
1u
s
;
drv
.
update
()
;
check_cpu_notifications
()
;
check_hmq_incoming
()
;
#
1u
s
;
end
end
// initial begin
endmodule
endmodule
// main
hdl/testbench/mock_turtle_core/run.do
View file @
ef467fd5
vsim -L unisim work.main -novopt
vsim -
quiet -
L unisim work.main -novopt
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
do wave.do
radix -hexadecimal
run 1000us
\ No newline at end of file
log -r /*
run 300us
hdl/testbench/mock_turtle_core/run_ci.do
View file @
ef467fd5
...
...
@@ -5,7 +5,7 @@ vsim -quiet -L unisim work.main
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
run 500us
run
1
500us
exit
hdl/testbench/mock_turtle_core/wave.do
deleted
100644 → 0
View file @
64b016b6
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -group Top /main/DUT/clk_i
add wave -noupdate -group Top /main/DUT/clk_cpu_i
add wave -noupdate -group Top /main/DUT/rst_n_i
add wave -noupdate -group Top /main/DUT/sp_master_o
add wave -noupdate -group Top /main/DUT/sp_master_i
add wave -noupdate -group Top /main/DUT/dp_master_o
add wave -noupdate -group Top /main/DUT/dp_master_i
add wave -noupdate -group Top /main/DUT/host_slave_i
add wave -noupdate -group Top /main/DUT/host_slave_o
add wave -noupdate -group Top /main/DUT/clk_ref_i
add wave -noupdate -group Top /main/DUT/tm_i
add wave -noupdate -group Top /main/DUT/gpio_o
add wave -noupdate -group Top /main/DUT/gpio_i
add wave -noupdate -group Top /main/DUT/host_irq_o
add wave -noupdate -group Top /main/DUT/debug_msg_irq_o
add wave -noupdate -group Top /main/DUT/hac_master_out
add wave -noupdate -group Top /main/DUT/hac_master_in
add wave -noupdate -group Top /main/DUT/si_slave_in
add wave -noupdate -group Top /main/DUT/si_slave_out
add wave -noupdate -group Top /main/DUT/si_master_in
add wave -noupdate -group Top /main/DUT/si_master_out
add wave -noupdate -group Top /main/DUT/cpu_csr_fromwb
add wave -noupdate -group Top -expand /main/DUT/cpu_csr_towb
add wave -noupdate -group Top /main/DUT/hmq_status
add wave -noupdate -group Top /main/DUT/rmq_status
add wave -noupdate -group Top /main/DUT/cpu_index
add wave -noupdate -group Top /main/DUT/cpu_dbg_drdy
add wave -noupdate -group Top /main/DUT/cpu_dbg_dack
add wave -noupdate -group Top /main/DUT/cpu_dbg_msg_data
add wave -noupdate -group Top /main/DUT/dbg_msg_data_read_ack
add wave -noupdate -group Top /main/DUT/cpu_csr_towb_cb
add wave -noupdate -group Top /main/DUT/cpu_gpio_out
add wave -noupdate -group Top /main/DUT/rst_n_ref
add wave -noupdate -group Top /main/DUT/host_remapped_in
add wave -noupdate -group Top /main/DUT/host_remapped_out
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/clk_i
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/rst_n_i
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/stat_o
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/inb_i
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/inb_o
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/outb_i
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/outb_o
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/out_discard_i
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/mem_raddr
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/mem_waddr
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/mem_wdata
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/mem_rdata_in
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/mem_rdata_out
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/rd_ptr
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/wr_ptr
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/occupied
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/words_written
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/mem_we
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/full
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/empty
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/wr_state
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/rd_state
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/in_claim
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/in_purge
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/in_ready
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/in_enqueue
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/in_commit
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/in_cmd_wr
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/in_stat_rd
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/out_cmd_wr
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/out_stat_rd
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/status
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/out_discard
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/out_purge
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/q_read
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/q_write
add wave -noupdate -expand -group OutSlot0 /main/DUT/U_Host_MQ/gen_outgoing_slots(0)/U_Out_SlotX/n_words_last
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/clk_i
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/rst_n_i
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/si_slave_i
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/si_slave_o
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/host_slave_i
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/host_slave_o
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/host_irq_o
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/hmq_status_o
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/si_incoming_in
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/host_incoming_in
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/si_incoming_out
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/host_incoming_out
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/si_outgoing_in
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/host_outgoing_in
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/si_outgoing_out
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/host_outgoing_out
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/incoming_stat
add wave -noupdate -expand -group HMQ -expand -subitemconfig {/main/DUT/U_Host_MQ/outgoing_stat(0) -expand} /main/DUT/U_Host_MQ/outgoing_stat
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/hmq_status
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/irq_config
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/tmr_div
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/tmr_tick
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/tmr_timeout
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/irq_vec_in
add wave -noupdate -expand -group HMQ /main/DUT/U_Host_MQ/irq_vec_out
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {175218 ns} 0}
configure wave -namecolwidth 282
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ns
update
WaveRestoreZoom {173892 ns} {176452 ns}
hdl/testbench/svec_mt_demo/main.sv
View file @
ef467fd5
...
...
@@ -88,122 +88,34 @@ module main;
.
clk_i
(
DUT
.
clk_sys
)
,
.
rst_n_i
(
DUT
.
rst_n_sys
))
;
IMockTurtleIRQ
IrqMonitor
(
`MT_ATTACH_IRQ
(
DUT
.
U_Mock_Turtle
))
;
// MT base (after VME sdb and vic).
const
uint64_t
base
=
'h2_0000
;
string
fw
=
"../../../demos/hello_world/firmware/fw-01/fw-hello.bin"
;
uint64_t
count
;
const
uint64_t
mt_base
=
'h2_0000
;
task
automatic
inc_counter
(
ref
CWishboneAccessor
acc
)
;
uint64_t
val
;
acc
.
read
(
base
+
32'h1_0000
,
val
)
;
if
(
val
!=
count
)
begin
$
display
(
"incorrect count (%x, expect %x)"
,
val
,
count
)
;
$
stop
;
end
count
++;
acc
.
write
(
base
+
32'h1_0000
,
count
)
;
endtask
MockTurtleDriver
drv
;
initial
begin
static
string
fw
=
"../../../tests/firmware/sim-verif/sim-verif.bin"
;
CWishboneAccessor
acc
;
MockTurtleDriver
drv
;
@
(
posedge
DUT
.
rst_n_sys
)
;
@
(
posedge
DUT
.
clk_sys
)
;
acc
=
Host
.
get_accessor
()
;
acc
.
set_mode
(
PIPELINED
)
;
// MT is mapped at 128kB on the VME wishbone port
drv
=
new
(
acc
,
base
)
;
drv
=
new
(
Host
.
get_accessor
()
,
mt_base
,
IrqMonitor
)
;
drv
.
init
()
;
$
display
(
"Display config rom"
)
;
drv
.
cfg_rom_display
()
;
drv
.
enable_console_irq
(
0
,
1
)
;
$
display
(
"Loading binary for cpu #0"
)
;
drv
.
load_firmware
(
0
,
fw
,
1'b0
)
;
$
display
(
"Start cpu #0 at %t"
,
$
time
)
;
drv
.
reset_core
(
0
,
0
)
;
// Enable all console interrupts
drv
.
m_csr
.
writel
(
`ADDR_MT_CPU_CSR_DBG_IMSK
,
8'hff
)
;
// Enable HMQ IN irqs.
drv
.
m_hmq
.
gcr_write
(
`MQUEUE_GCR_IRQ_MASK
,
8'hff
)
;
// Enable VIC interrupts (unmask)
acc
.
write
(
32'h2008
,
8'hff
)
;
count
=
0
;
forever
begin
uint32_t
val
;
uint64_t
risr
;
// Read VIC RISR
acc
.
read
(
32'h2004
,
risr
)
;
if
(
risr
[
2
])
drv
.
m_csr
.
check_consoles
()
;
// Check notify interrupt
if
(
risr
[
3
])
begin
drv
.
m_csr
.
readl
(
`ADDR_MT_CPU_CSR_INT
,
val
)
;
if
(
val
!=
0
)
begin
// Read counter for cpu #0 (in smem)
inc_counter
(
acc
)
;
$
display
(
"Notify interrupts: %x, count: %d"
,
val
,
count
)
;
drv
.
m_csr
.
writel
(
`ADDR_MT_CPU_CSR_INT
,
val
)
;
end
end
// Check HMQ IN
if
(
risr
[
0
])
begin
drv
.
m_hmq
.
gcr_read
(
`MQUEUE_GCR_SLOT_STATUS
,
val
)
;
$
display
(
"HMQ IN irq: %x"
,
val
)
;
if
((
val
&
16'hff
)
!=
0
)
begin
uint32_t
stat
;
uint32_t
len
;
uint32_t
dat
;
$
display
(
"HMQ GCR status: %x"
,
val
)
;
drv
.
m_hmq
.
incoming_read
(
`MQUEUE_SLOT_STATUS
,
stat
)
;
$
display
(
" SLOT status: %x"
,
stat
)
;
drv
.
m_hmq
.
incoming_read
(
`MQUEUE_SLOT_HEADER
+
0
,
len
)
;
$
display
(
" SLOT header: %x"
,
len
)
;
len
=
2
;
drv
.
m_hmq
.
outgoing_write
(
`MQUEUE_SLOT_COMMAND
,
`MQUEUE_CMD_CLAIM
)
;
drv
.
m_hmq
.
outgoing_write
(
`MQUEUE_SLOT_HEADER
,
len
)
;
for
(
int
i
=
0
;
i
<
len
;
i
++
)
begin
drv
.
m_hmq
.
incoming_read
(
`MQUEUE_SLOT_DATA
+
4
*
i
,
dat
)
;
$
display
(
" SLOT data[%d]: %x"
,
i
,
dat
)
;
drv
.
m_hmq
.
outgoing_write
(
`MQUEUE_SLOT_DATA
+
4
*
i
,
~
dat
)
;
end
inc_counter
(
acc
)
;
drv
.
m_hmq
.
incoming_write
(
`MQUEUE_SLOT_COMMAND
,
`MQUEUE_CMD_DISCARD
)
;
drv
.
m_hmq
.
outgoing_write
(
`MQUEUE_SLOT_COMMAND
,
`MQUEUE_CMD_READY
)
;
end
end
drv
.
update
()
;
#
1u
s
;
end
end
end
// initial begin
endmodule
// main
tests/firmware/sim-verif/sim-verif.c
View file @
ef467fd5
...
...
@@ -34,7 +34,6 @@ test_notify (void)
{
unsigned
int
v
;
puts
(
"#2 notify irq
\n
"
);
v
=
counts
[
cpu
];
lr_writel
(
1
,
MT_CPU_LR_REG_HOST_INT
);
while
((
lr_readl
(
MT_CPU_LR_REG_HOST_INT
)
&
(
1
<<
cpu
))
!=
0
)
...
...
@@ -130,7 +129,11 @@ main(void)
puts
(
"#1 console
\n
"
);
test_notify
();
lr_writel
(
1
,
MT_CPU_LR_REG_HOST_INT
);
puts
(
"#2 notify irq
\n
"
);
for
(
int
i
=
0
;
i
<
10
;
i
++
)
test_notify
();
test_rmq
();
...
...
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