Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
G
Gennum GN4124 core
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Projects
Gennum GN4124 core
Commits
4221b112
Commit
4221b112
authored
4 years ago
by
Tristan Gingold
Browse files
Options
Downloads
Patches
Plain Diff
p2l_dma_master: allow transfer longer than 4096 bytes.
parent
f6d26f73
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
hdl/rtl/p2l_dma_master.vhd
+42
-52
42 additions, 52 deletions
hdl/rtl/p2l_dma_master.vhd
hdl/rtl/spartan6/gn4124_core.vhd
+2
-2
2 additions, 2 deletions
hdl/rtl/spartan6/gn4124_core.vhd
with
44 additions
and
54 deletions
hdl/rtl/p2l_dma_master.vhd
+
42
−
52
View file @
4221b112
...
...
@@ -145,9 +145,8 @@ architecture arch of p2l_dma_master is
signal
l2p_address_h
:
std_logic_vector
(
31
downto
0
)
:
=
(
others
=>
'0'
);
signal
l2p_address_l
:
std_logic_vector
(
31
downto
0
)
:
=
(
others
=>
'0'
);
signal
l2p_len_cnt
:
unsigned
(
29
downto
0
)
:
=
(
others
=>
'0'
);
signal
l2p_len_header
:
unsigned
(
9
downto
0
)
:
=
(
others
=>
'0'
)
;
signal
l2p_len_header
:
unsigned
(
10
downto
0
);
signal
l2p_64b_address
:
std_logic
;
signal
l2p_last_packet
:
std_logic
;
signal
pdm_arb_data
:
std_logic_vector
(
31
downto
0
)
:
=
(
others
=>
'0'
);
...
...
@@ -174,7 +173,7 @@ architecture arch of p2l_dma_master is
signal
wb_dma_tfr
:
boolean
;
-- P2L DMA read request FSM
type
p2l_dma_state_type
is
(
P2L_IDLE
,
P2L_HEADER
,
P2L_ADDR_H
,
P2L_ADDR_L
,
P2L_WAIT_READ_COMPLETION
);
type
p2l_dma_state_type
is
(
P2L_IDLE
,
P2L_SETUP
,
P2L_HEADER
,
P2L_ADDR_H
,
P2L_ADDR_L
,
P2L_WAIT_READ_COMPLETION
);
signal
p2l_dma_current_state
:
p2l_dma_state_type
;
signal
p2l_data_cnt
:
unsigned
(
10
downto
0
)
:
=
(
others
=>
'0'
);
...
...
@@ -212,7 +211,6 @@ begin
rx_error_t
<=
'0'
;
l2p_64b_address
<=
'0'
;
is_next_item
<=
'0'
;
l2p_last_packet
<=
'0'
;
else
case
p2l_dma_current_state
is
...
...
@@ -229,36 +227,31 @@ begin
l2p_address_h
<=
dma_ctrl_host_addr_h_i
;
l2p_address_l
<=
dma_ctrl_host_addr_l_i
;
l2p_len_cnt
<=
unsigned
(
dma_ctrl_len_i
(
31
downto
2
));
-- dma_ctrl_len_i is in byte
if
dma_ctrl_start_next_i
=
'1'
then
-- Catching next DMA item
is_next_item
<=
'1'
;
-- flag for data retrieve block
else
-- P2L DMA transfer
is_next_item
<=
'0'
;
end
if
;
-- Catching whether this is a P2L DMA transfer or just a fetch of the next DMA item
is_next_item
<=
dma_ctrl_start_next_i
;
if
dma_ctrl_host_addr_h_i
=
X"00000000"
then
l2p_64b_address
<=
'0'
;
else
l2p_64b_address
<=
'1'
;
end
if
;
-- request access to PCIe bus
pdm_arb_req_o
<=
'1'
;
-- prepare a packet, first the header
p2l_dma_current_state
<=
P2L_
HEADER
;
p2l_dma_current_state
<=
P2L_
SETUP
;
end
if
;
when
P2L_
HEADER
=>
when
P2L_
SETUP
=>
-- if DMA length is bigger than the max PCIe payload size,
-- we have to generate several read request
if
l2p_len_cnt
>
c_MAX_READ_REQ_SIZE
then
-- when max payload length is 1024, the header length field = 0
l2p_len_header
<=
c_MAX_READ_REQ_SIZE
(
9
downto
0
);
l2p_last_packet
<=
'0'
;
l2p_len_header
<=
c_MAX_READ_REQ_SIZE
;
else
l2p_len_header
<=
l2p_len_cnt
(
9
downto
0
);
l2p_last_packet
<=
'1'
;
l2p_len_header
<=
l2p_len_cnt
(
10
downto
0
);
end
if
;
-- request access to PCIe bus
pdm_arb_req_o
<=
'1'
;
p2l_dma_current_state
<=
P2L_HEADER
;
when
P2L_HEADER
=>
if
arb_pdm_gnt_i
=
'1'
then
-- clear access request to the arbiter
-- access is granted until dframe is cleared
...
...
@@ -277,7 +270,7 @@ begin
pdm_arb_data
(
15
downto
13
)
<=
"111"
;
--> Reserved
pdm_arb_data
(
12
)
<=
'0'
;
--> VC (Virtual Channel)
pdm_arb_data
(
11
downto
10
)
<=
"01"
;
--> CID
pdm_arb_data
(
9
downto
0
)
<=
std_logic_vector
(
l2p_len_header
);
--> Length (in
32-bit
words)
pdm_arb_data
(
9
downto
0
)
<=
std_logic_vector
(
l2p_len_header
(
9
downto
0
)
);
--> Length (in words)
pdm_arb_valid_o
<=
'1'
;
pdm_arb_dframe_o
<=
'1'
;
if
l2p_64b_address
=
'1'
then
...
...
@@ -296,35 +289,35 @@ begin
p2l_dma_current_state
<=
P2L_ADDR_L
;
when
P2L_ADDR_L
=>
-- Subtract the number of word requested to generate a new read request if needed
if
l2p_last_packet
=
'0'
then
l2p_len_cnt
<=
l2p_len_cnt
-
c_MAX_READ_REQ_SIZE
;
else
l2p_len_cnt
<=
(
others
=>
'0'
);
end
if
;
-- send host address 32 lowest bits
pdm_arb_data
<=
l2p_address_l
;
-- clear dframe signal to indicate the end of packet
pdm_arb_dframe_o
<=
'0'
;
-- Subtract the number of word requested to generate a new read request if needed
l2p_len_cnt
<=
l2p_len_cnt
-
l2p_len_header
;
l2p_address_l
<=
std_logic_vector
(
unsigned
(
l2p_address_l
)
+
4
*
l2p_len_header
);
p2l_dma_current_state
<=
P2L_WAIT_READ_COMPLETION
;
when
P2L_WAIT_READ_COMPLETION
=>
-- End of the read request packet
pdm_arb_valid_o
<=
'0'
;
if
pd_pdm_data_valid_i
=
'1'
and
pd_pdm_master_cpld_i
=
'1'
then
-- Received a word.
l2p_len_header
<=
l2p_len_header
-
1
;
end
if
;
if
dma_ctrl_abort_i
=
'1'
then
rx_error_t
<=
'1'
;
p2l_dma_current_state
<=
P2L_IDLE
;
elsif
(
pd_pdm_master_cpld_i
=
'1'
and
pd_pdm_data_last_i
=
'1'
and
p2l_data_cnt
<
=
1
)
elsif
pd_pdm_master_cpld_i
=
'1'
and
pd_pdm_data_last_i
=
'1'
and
l2p_len_header
=
1
then
-- Note: a read request may result in multiple read completion.
-- last word of read completion has been received
if
l2p_l
ast_packe
t
=
'0'
then
if
l2p_l
en_cn
t
/
=
0
then
-- A new read request is needed, DMA size > max payload
p2l_dma_current_state
<=
P2L_HEADER
;
-- As the end of packet is used to delimit arbitration phases
-- we have to ask again for permission
pdm_arb_req_o
<=
'1'
;
p2l_dma_current_state
<=
P2L_SETUP
;
else
-- indicate end of DMA transfer
if
is_next_item
=
'1'
then
...
...
@@ -378,14 +371,11 @@ begin
if
rising_edge
(
clk_i
)
then
if
p2l_dma_current_state
=
P2L_ADDR_L
then
-- Store number of 32-bit data words to be received for the current read request
if
l2p_len_header
=
0
then
p2l_data_cnt
<=
to_unsigned
(
1024
,
p2l_data_cnt
'length
);
else
p2l_data_cnt
<=
'0'
&
l2p_len_header
;
end
if
;
elsif
(
p2l_dma_current_state
=
P2L_WAIT_READ_COMPLETION
and
pd_pdm_data_valid_i
=
'1'
and
pd_pdm_master_cpld_i
=
'1'
)
then
p2l_data_cnt
<=
l2p_len_header
;
elsif
p2l_dma_current_state
=
P2L_WAIT_READ_COMPLETION
and
pd_pdm_data_valid_i
=
'1'
and
pd_pdm_master_cpld_i
=
'1'
then
-- decrement number of data to be received
p2l_data_cnt
<=
p2l_data_cnt
-
1
;
end
if
;
...
...
@@ -398,8 +388,8 @@ begin
p_next_item
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
p2l_dma_current_state
=
P2L_WAIT_READ_COMPLETION
and
is_next_item
=
'1'
and
pd_pdm_data_valid_i
=
'1'
)
if
p2l_dma_current_state
=
P2L_WAIT_READ_COMPLETION
and
is_next_item
=
'1'
and
pd_pdm_data_valid_i
=
'1'
then
-- next item data are supposed to be received in the right order !!
case
p2l_data_cnt
(
2
downto
0
)
is
...
...
@@ -438,7 +428,7 @@ begin
p_addr_cnt
:
process
(
clk_i
)
begin
if
rising_edge
(
clk_i
)
then
if
(
rst_n_i
=
'0'
)
then
if
rst_n_i
=
'0'
then
dma_busy_error
<=
'0'
;
to_wb_fifo_wr
<=
'0'
;
to_wb_fifo_wr_d
<=
'0'
;
...
...
@@ -446,8 +436,8 @@ begin
to_wb_fifo_din_d
<=
to_wb_fifo_din
;
to_wb_fifo_wr_d
<=
to_wb_fifo_wr
;
if
(
dma_ctrl_start_p2l_i
=
'1'
)
then
if
(
p2l_dma_current_state
=
P2L_IDLE
)
then
if
dma_ctrl_start_p2l_i
=
'1'
then
if
p2l_dma_current_state
=
P2L_IDLE
then
-- dma_ctrl_target_addr_i is a byte address and target_addr_cnt is a
-- 32-bit word address
target_addr_cnt
<=
unsigned
(
dma_ctrl_carrier_addr_i
(
31
downto
2
));
...
...
@@ -456,15 +446,15 @@ begin
else
dma_busy_error
<=
'1'
;
end
if
;
elsif
(
p2l_dma_current_state
=
P2L_WAIT_READ_COMPLETION
and
is_next_item
=
'0'
and
pd_pdm_data_valid_i
=
'1'
)
elsif
p2l_dma_current_state
=
P2L_WAIT_READ_COMPLETION
and
is_next_item
=
'0'
and
pd_pdm_data_valid_i
=
'1'
then
-- increment target address counter
target_addr_cnt
<=
target_addr_cnt
+
1
;
-- write target address and data to the sync fifo
to_wb_fifo_wr
<=
'1'
;
to_wb_fifo_din
(
31
downto
0
)
<=
f_byte_swap
(
g_BYTE_SWAP
,
pd_pdm_data_i
,
to_wb_fifo_byte_swap
);
to_wb_fifo_din
(
61
downto
32
)
<=
std_logic_vector
(
target_addr_cnt
);
-- increment target address counter
target_addr_cnt
<=
target_addr_cnt
+
1
;
else
dma_busy_error
<=
'0'
;
to_wb_fifo_wr
<=
'0'
;
...
...
This diff is collapsed.
Click to expand it.
hdl/rtl/spartan6/gn4124_core.vhd
+
2
−
2
View file @
4221b112
...
...
@@ -566,7 +566,7 @@ begin
);
-----------------------------------------------------------------------------
-- L2P DMA master
-- L2P DMA master
(for board to host transfers)
-----------------------------------------------------------------------------
cmp_l2p_dma_master
:
entity
work
.
l2p_dma_master
generic
map
(
...
...
@@ -608,7 +608,7 @@ begin
l2p_dma_in
.
rty
<=
dma_rty_i
;
-----------------------------------------------------------------------------
-- P2L DMA
master
-- P2L DMA master
(for host to board transfers)
-----------------------------------------------------------------------------
cmp_p2l_dma_master
:
entity
work
.
p2l_dma_master
generic
map
(
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment