Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
Gennum GN4124 core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
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
Gennum GN4124 core
Commits
5f010f90
Commit
5f010f90
authored
Sep 02, 2019
by
Dimitris Lampridis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[hdl] handle host 32-bit address overflow in L2P DMA master
parent
f2863fc1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
66 additions
and
12 deletions
+66
-12
l2p_dma_master.vhd
hdl/rtl/l2p_dma_master.vhd
+23
-11
main.sv
hdl/sim/example_tb/main.sv
+43
-1
No files found.
hdl/rtl/l2p_dma_master.vhd
View file @
5f010f90
...
...
@@ -86,7 +86,14 @@ architecture behavioral of l2p_dma_master is
---------------------
-- Constants
---------------------
constant
c_L2P_MAX_PAYLOAD
:
integer
:
=
32
;
-- L2P_MAX_PAYLOAD must be a power of 2 for easier 32-bit address overflow check.
constant
c_L2P_MAX_PAYLOAD_NBITS
:
integer
:
=
7
;
constant
c_L2P_MAX_PAYLOAD_BYTES
:
integer
:
=
2
**
c_L2P_MAX_PAYLOAD_NBITS
;
constant
c_L2P_MAX_PAYLOAD_WORDS
:
integer
:
=
c_L2P_MAX_PAYLOAD_BYTES
/
4
;
constant
c_L2P_A32_OVERFLOW_MASK
:
std_logic_vector
(
31
downto
0
)
:
=
not
std_logic_vector
(
to_unsigned
(
c_L2P_MAX_PAYLOAD_BYTES
-
1
,
32
));
constant
c_TIMEOUT
:
integer
:
=
2000
;
-- how many pending WB requests to allow without ACK
...
...
@@ -330,13 +337,13 @@ begin
l2p_byte_swap
<=
dma_ctrl_byte_swap_i
;
l2p_last_packet
<=
'0'
;
elsif
(
l2p_dma_current_state
=
L2P_SETUP
)
then
if
(
l2p_len_cnt
>
c_L2P_MAX_PAYLOAD
)
then
l2p_data_cnt
<=
TO_UNSIGNED
(
c_L2P_MAX_PAYLOAD
,
13
);
l2p_len_header
<=
TO_UNSIGNED
(
c_L2P_MAX_PAYLOAD
,
13
);
if
(
l2p_len_cnt
>
c_L2P_MAX_PAYLOAD
_WORDS
)
then
l2p_data_cnt
<=
TO_UNSIGNED
(
c_L2P_MAX_PAYLOAD
_WORDS
,
13
);
l2p_len_header
<=
TO_UNSIGNED
(
c_L2P_MAX_PAYLOAD
_WORDS
,
13
);
l2p_last_packet
<=
'0'
;
elsif
(
l2p_len_cnt
=
c_L2P_MAX_PAYLOAD
)
then
l2p_data_cnt
<=
TO_UNSIGNED
(
c_L2P_MAX_PAYLOAD
,
13
);
l2p_len_header
<=
TO_UNSIGNED
(
c_L2P_MAX_PAYLOAD
,
13
);
elsif
(
l2p_len_cnt
=
c_L2P_MAX_PAYLOAD
_WORDS
)
then
l2p_data_cnt
<=
TO_UNSIGNED
(
c_L2P_MAX_PAYLOAD
_WORDS
,
13
);
l2p_len_header
<=
TO_UNSIGNED
(
c_L2P_MAX_PAYLOAD
_WORDS
,
13
);
l2p_last_packet
<=
'1'
;
else
l2p_data_cnt
<=
l2p_len_cnt
(
12
downto
0
);
...
...
@@ -349,10 +356,15 @@ begin
end
if
;
elsif
(
l2p_dma_current_state
=
L2P_LAST_DATA
)
then
if
(
l2p_last_packet
=
'0'
)
then
-- Increase Address
-- TODO Not overflow safe !
l2p_address_l
<=
std_logic_vector
(
unsigned
(
l2p_address_l
)
+
(
c_L2P_MAX_PAYLOAD
*
4
));
l2p_len_cnt
<=
l2p_len_cnt
-
c_L2P_MAX_PAYLOAD
;
-- Increase Address, check for overflow
if
(
l2p_address_l
and
(
c_L2P_A32_OVERFLOW_MASK
))
=
c_L2P_A32_OVERFLOW_MASK
then
l2p_address_h
<=
std_logic_vector
(
unsigned
(
l2p_address_h
)
+
1
);
l2p_address_l
(
31
downto
c_L2P_MAX_PAYLOAD_NBITS
)
<=
(
others
=>
'0'
);
else
l2p_address_l
<=
std_logic_vector
(
unsigned
(
l2p_address_l
)
+
(
c_L2P_MAX_PAYLOAD_BYTES
));
end
if
;
l2p_len_cnt
<=
l2p_len_cnt
-
c_L2P_MAX_PAYLOAD_WORDS
;
else
l2p_len_cnt
<=
(
others
=>
'0'
);
end
if
;
...
...
hdl/sim/example_tb/main.sv
View file @
5f010f90
...
...
@@ -153,7 +153,7 @@ module main;
initial
begin
automatic
int
ntest
=
1
;
const
int
tests
=
7
;
const
int
tests
=
8
;
uint32_t
addr
,
val
,
expected
;
...
...
@@ -321,6 +321,48 @@ module main;
#
1u
s
;
end
$
write
(
"Test %0d/%0d: 256B read over DMA with 32bit host address overflow: "
,
ntest
++,
tests
)
;
acc
.
write
(
'h14
,
'h100
)
;
// count
acc
.
write
(
'h20
,
'h00
)
;
// attrib
acc
.
write
(
'h0c
,
'hffffff80
)
;
// hstartL
acc
.
write
(
'h10
,
'h00000000
)
;
// hstartH
acc
.
write
(
'h00
,
'h01
)
;
// start
// Transfer will be split internally by L2P DMA master in two requests, the first
// one with a 32-bit adress starting at ffff_ff80 and the next one with a 64-bit
// address starting at 1_0000_0000
@
(
posedge
DUT
.
cmp_wrapped_gn4124
.
ldm_arb_dframe
)
;
@
(
posedge
DUT
.
cmp_wrapped_gn4124
.
sys_clk
)
;
val_check
(
"Host address overflow header"
,
1
,
DUT
.
cmp_wrapped_gn4124
.
ldm_arb_data
,
'h02ff0020
)
;
@
(
posedge
DUT
.
cmp_wrapped_gn4124
.
sys_clk
)
;
val_check
(
"Host address overflow address"
,
1
,
DUT
.
cmp_wrapped_gn4124
.
ldm_arb_data
,
'hffffff80
)
;
@
(
posedge
DUT
.
cmp_wrapped_gn4124
.
ldm_arb_dframe
)
;
@
(
posedge
DUT
.
cmp_wrapped_gn4124
.
sys_clk
)
;
val_check
(
"Host address overflow header"
,
2
,
DUT
.
cmp_wrapped_gn4124
.
ldm_arb_data
,
'h03ff0020
)
;
@
(
posedge
DUT
.
cmp_wrapped_gn4124
.
sys_clk
)
;
val_check
(
"Host address overflow address high"
,
2
,
DUT
.
cmp_wrapped_gn4124
.
ldm_arb_data
,
1
)
;
@
(
posedge
DUT
.
cmp_wrapped_gn4124
.
sys_clk
)
;
val_check
(
"Host address overflow address low"
,
2
,
DUT
.
cmp_wrapped_gn4124
.
ldm_arb_data
,
0
)
;
@
(
posedge
dma_irq
)
;
// Check irq status
reg_check
(
'h04
,
'h04
)
;
if
(
dma_irq
!=
1'b1
)
$
fatal
(
1
,
"dma irq should be 1"
)
;
// clear irq
acc
.
write
(
'h04
,
'h04
)
;
reg_check
(
'h04
,
'h00
)
;
if
(
dma_irq
!=
1'b0
)
$
fatal
(
1
,
"dma irq should be 0"
)
;
repeat
(
4
)
@
(
posedge
clk_125m
)
;
$
write
(
"PASS
\n
"
)
;
$
display
()
;
$
display
(
"Simulation PASSED"
)
;
...
...
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