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
2a23d551
Commit
2a23d551
authored
Jul 03, 2020
by
Dimitris Lampridis
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
hdl: wip, do not use this commit
parent
73cb5a89
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
80 additions
and
126 deletions
+80
-126
l2p_dma_master.vhd
hdl/rtl/l2p_dma_master.vhd
+72
-86
main.sv
hdl/sim/example_tb/main.sv
+8
-40
No files found.
hdl/rtl/l2p_dma_master.vhd
View file @
2a23d551
...
...
@@ -76,13 +76,24 @@ end l2p_dma_master;
architecture
arch
of
l2p_dma_master
is
-- Used to tweak the almost full flag threshold of the SYNC FIFO
-- in
-- in order to help with timing by giving an advanced warning
-- that we can then pipeline through an equal number of registers.
constant
c_SYNC_FIFO_FULL_DELAY
:
natural
:
=
3
;
type
l2p_dma_state_type
is
(
L2P_IDLE
,
L2P_SETUP
,
L2P_WAIT
,
L2P_HEADER
,
L2P_HOLD
,
L2P_ADDR_H
,
L2P_ADDR_L
,
L2P_DATA
,
L2P_NEXT
,
L2P_ERROR
);
-- Even though the actual limit is 4KiB, the GN4124 really hates it
-- if we try to send more than 256 Bytes (64 Words) within a single packet.
-- During tests, we've seen that the GN4124 chip might freeze when such
-- a request arrives, with the probability of a freeze increasing with
-- the size of the packet.
-- The overhead of the extra transaction is minimal so we keep here the
-- limit that was there in previous versions of this code (128 Bytes,
-- or 32 Words).
constant
c_L2P_MAX_PAYLOAD
:
integer
:
=
32
;
type
l2p_dma_state_type
is
(
L2P_IDLE
,
L2P_WB_SETUP
,
L2P_SETUP
,
L2P_WAIT
,
L2P_HEADER
,
L2P_HOLD
,
L2P_ADDR_H
,
L2P_ADDR_L
,
L2P_DATA
,
L2P_NEXT
,
L2P_ERROR
);
signal
l2p_dma_current_state
:
l2p_dma_state_type
:
=
L2P_IDLE
;
type
wb_dma_state_type
is
(
WB_IDLE
,
WB_SETUP
,
WB_DATA
,
WB_HOLD
);
...
...
@@ -90,7 +101,7 @@ architecture arch of l2p_dma_master is
signal
dma_target_addr
:
unsigned
(
29
downto
0
)
:
=
(
others
=>
'0'
);
signal
dma_total_len
:
unsigned
(
29
downto
0
)
:
=
(
others
=>
'0'
);
signal
dma_packet_len
:
unsigned
(
10
downto
0
)
:
=
(
others
=>
'0'
);
signal
dma_packet_len
:
unsigned
(
5
downto
0
)
:
=
(
others
=>
'0'
);
signal
dma_host_addr
:
unsigned
(
63
downto
0
)
:
=
(
others
=>
'0'
);
signal
dma_byte_swap
:
std_logic_vector
(
1
downto
0
)
:
=
(
others
=>
'0'
);
...
...
@@ -106,7 +117,7 @@ architecture arch of l2p_dma_master is
signal
l2p_fsm_dma_param_wr
:
std_logic
:
=
'0'
;
signal
l2p_fsm_dma_param_busy
:
std_logic
:
=
'0'
;
signal
dma_param_sync
:
std_logic_vector
(
40
downto
0
)
:
=
(
others
=>
'0'
);
signal
dma_param_sync
:
std_logic_vector
(
59
downto
0
)
:
=
(
others
=>
'0'
);
signal
dma_param_wr
:
std_logic
:
=
'0'
;
signal
l2p_timeout_cnt
:
unsigned
(
12
downto
0
)
:
=
(
others
=>
'0'
);
...
...
@@ -116,8 +127,8 @@ architecture arch of l2p_dma_master is
signal
wb_dma_stb
:
std_logic
:
=
'0'
;
signal
wb_dma_addr
:
unsigned
(
29
downto
0
)
:
=
(
others
=>
'0'
);
signal
wb_dma_addr_d
:
unsigned
(
29
downto
0
)
:
=
(
others
=>
'0'
);
signal
wb_dma_cnt_stb
:
unsigned
(
10
downto
0
)
:
=
(
others
=>
'0'
);
signal
wb_dma_cnt_ack
:
unsigned
(
10
downto
0
)
:
=
(
others
=>
'0'
);
signal
wb_dma_cnt_stb
:
unsigned
(
29
downto
0
)
:
=
(
others
=>
'0'
);
signal
wb_dma_cnt_ack
:
unsigned
(
29
downto
0
)
:
=
(
others
=>
'0'
);
signal
wb_dma_fsm_en
:
std_logic
:
=
'0'
;
signal
wb_dma_fsm_en_sync
:
std_logic
:
=
'0'
;
...
...
@@ -185,26 +196,31 @@ begin
dma_host_addr_l
<=
unsigned
(
dma_ctrl_host_addr_l_i
);
dma_total_len
<=
unsigned
(
dma_ctrl_len_i
(
31
downto
2
));
dma_byte_swap
<=
dma_ctrl_byte_swap_i
;
l2p_dma_current_state
<=
L2P_WB_SETUP
;
end
if
;
when
L2P_WB_SETUP
=>
l2p_fsm_dma_param_wr
<=
'1'
;
if
l2p_fsm_dma_param_busy
=
'1'
then
l2p_dma_current_state
<=
L2P_SETUP
;
end
if
;
when
L2P_SETUP
=>
-- Calculate DMA packet length for next tranfer. A transfer can be
-- up to 1024 words, limited by the "length" field in the L2P header.
if
dma_total_len
>
1024
then
dma_packet_len
<=
to_unsigned
(
1024
,
dma_packet_len
'length
);
-- We limit it artificially to c_L2P_MAX_PAYLOAD (see note in
-- constant declaration).
if
dma_total_len
>
c_L2P_MAX_PAYLOAD
then
dma_packet_len
<=
to_unsigned
(
c_L2P_MAX_PAYLOAD
,
dma_packet_len
'length
);
dma_last_packet
<=
'0'
;
elsif
dma_total_len
=
1024
then
dma_packet_len
<=
to_unsigned
(
1024
,
dma_packet_len
'length
);
elsif
dma_total_len
=
c_L2P_MAX_PAYLOAD
then
dma_packet_len
<=
to_unsigned
(
c_L2P_MAX_PAYLOAD
,
dma_packet_len
'length
);
dma_last_packet
<=
'1'
;
else
dma_packet_len
<=
dma_total_len
(
10
downto
0
);
dma_packet_len
<=
dma_total_len
(
5
downto
0
);
dma_last_packet
<=
'1'
;
end
if
;
l2p_fsm_dma_param_wr
<=
'1'
;
if
l2p_fsm_dma_param_busy
=
'1'
then
l2p_dma_current_state
<=
L2P_WAIT
;
end
if
;
when
L2P_WAIT
=>
-- Send request to DMA arbiter
...
...
@@ -237,7 +253,7 @@ begin
-- FBE (First Byte Enable)
l2p_fsm_data
(
19
downto
16
)
<=
"1111"
;
-- Length field (in 32 bit words). When zero it means 1024 words.
l2p_fsm_data
(
9
downto
0
)
<=
std_logic_vector
(
dma_packet_len
(
9
downto
0
)
);
l2p_fsm_data
(
9
downto
0
)
<=
"0000"
&
std_logic_vector
(
dma_packet_len
);
if
(
l2p_64b_address
=
'1'
)
then
l2p_dma_current_state
<=
L2P_ADDR_H
;
else
...
...
@@ -302,9 +318,9 @@ begin
when
L2P_NEXT
=>
if
data_fifo_empty
=
'1'
then
dma_total_len
<=
dma_total_len
-
1024
;
dma_target_addr
<=
dma_target_addr
+
1024
;
dma_host_addr
<=
dma_host_addr
+
4096
;
dma_total_len
<=
dma_total_len
-
c_L2P_MAX_PAYLOAD
;
dma_target_addr
<=
dma_target_addr
+
c_L2P_MAX_PAYLOAD
;
dma_host_addr
<=
dma_host_addr
+
4
*
c_L2P_MAX_PAYLOAD
;
l2p_dma_current_state
<=
L2P_SETUP
;
end
if
;
...
...
@@ -332,15 +348,15 @@ begin
-------------------------------------------------
gen_sync_word_dma_param
:
if
g_DMA_USE_PCI_CLK
=
FALSE
generate
signal
dma_param_to_sync
:
std_logic_vector
(
40
downto
0
);
signal
dma_param_to_sync
:
std_logic_vector
(
59
downto
0
);
begin
dma_param_to_sync
(
40
downto
11
)
<=
std_logic_vector
(
dma_target_addr
);
dma_param_to_sync
(
10
downto
0
)
<=
std_logic_vector
(
dma_packet
_len
);
dma_param_to_sync
(
59
downto
30
)
<=
std_logic_vector
(
dma_target_addr
);
dma_param_to_sync
(
29
downto
0
)
<=
std_logic_vector
(
dma_total
_len
);
cmp_sync_dma_param
:
entity
work
.
gc_sync_word_wr
generic
map
(
g_AUTO_WR
=>
false
,
g_WIDTH
=>
41
)
g_AUTO_WR
=>
FALSE
,
g_WIDTH
=>
60
)
port
map
(
clk_in_i
=>
clk_i
,
rst_in_n_i
=>
'1'
,
...
...
@@ -362,44 +378,14 @@ begin
end
generate
gen_sync_word_dma_param
;
gen_no_sync_word_dma_param
:
if
g_DMA_USE_PCI_CLK
=
TRUE
generate
dma_param_sync
(
40
downto
11
)
<=
std_logic_vector
(
dma_target_addr
);
dma_param_sync
(
10
downto
0
)
<=
std_logic_vector
(
dma_packet
_len
);
gen_no_sync_word_dma_param
:
if
g_DMA_USE_PCI_CLK
=
TRUE
generate
dma_param_sync
(
59
downto
30
)
<=
std_logic_vector
(
dma_target_addr
);
dma_param_sync
(
29
downto
0
)
<=
std_logic_vector
(
dma_total
_len
);
l2p_fsm_dma_param_busy
<=
l2p_fsm_dma_param_wr
;
dma_param_wr
<=
l2p_fsm_dma_param_wr
;
wb_dma_fsm_en_sync
<=
wb_dma_fsm_en
;
end
generate
gen_no_sync_word_dma_param
;
-- p_wb_master : process (wb_dma_clk_i) is
-- begin
-- if rising_edge(wb_dma_clk_i) then
-- if wb_dma_rst_n_i = '0' then
-- wb_dma_stb <= '0';
-- else
-- -- Handle strobe and address generation.
-- wb_dma_stb <= '0';
-- if wb_xfer_en_sync = '1' then
-- if wb_dma_cnt > 1 and data_fifo_full = '0' or
-- wb_dma_stb <= '1';
-- if wb_dma_i.stall = '0' and wb_dma_stb = '1' then
-- wb_dma_addr <= wb_dma_addr + 1;
-- wb_dma_cnt <= wb_dma_cnt - 1;
-- end if;
-- end if;
-- elsif dma_param_wr = '1' then
-- wb_dma_addr <= unsigned(dma_param_sync(40 downto 11));
-- wb_dma_cnt <= unsigned(dma_param_sync(10 downto 0));
-- end if;
-- -- Write received data to FIFO.
-- -- No need to check FIFO full, it was done earlier
-- -- when we decided to strobe.
-- data_fifo_din <= wb_dma_i.dat;
-- data_fifo_wr <= wb_dma_i.ack;
-- end if;
-- end if;
-- end process p_wb_master;
-- P2P communication, no need to drop WB cycle.
wb_dma_o
.
cyc
<=
'1'
;
wb_dma_o
.
stb
<=
wb_dma_stb
;
...
...
@@ -436,9 +422,9 @@ begin
end
if
;
when
WB_SETUP
=>
wb_dma_addr
<=
unsigned
(
dma_param_sync
(
40
downto
11
));
wb_dma_cnt_stb
<=
unsigned
(
dma_param_sync
(
10
downto
0
));
wb_dma_cnt_ack
<=
unsigned
(
dma_param_sync
(
10
downto
0
));
wb_dma_addr
<=
unsigned
(
dma_param_sync
(
59
downto
30
));
wb_dma_cnt_stb
<=
unsigned
(
dma_param_sync
(
29
downto
0
));
wb_dma_cnt_ack
<=
unsigned
(
dma_param_sync
(
29
downto
0
));
if
data_fifo_full
=
'0'
then
wb_dma_current_state
<=
WB_DATA
;
end
if
;
...
...
hdl/sim/example_tb/main.sv
View file @
2a23d551
...
...
@@ -179,7 +179,7 @@ module main;
initial
begin
automatic
int
ntest
=
1
;
const
int
tests
=
9
;
const
int
tests
=
8
;
uint32_t
addr
,
val
,
expected
;
...
...
@@ -211,38 +211,6 @@ module main;
$
write
(
"PASS
\n
"
)
;
/* -----\/----- EXCLUDED -----\/-----
$write("Test %0d/%0d: 128B read over DMA, abort after first read: ",
ntest++, tests);
if (dma_irq != 1'b0)
$fatal(1, "dma irq should be 0");
acc.write('h14, 'h80); // count
acc.write('h00, 'h01); // start
// Check values read from memory
@(posedge i_gn4124.l2p_valid); // skip header
repeat(2) @(posedge i_gn4124.l2p_clk_p);
expected = 32'h8000001f;
val = i_gn4124.l2p_data;
@(posedge i_gn4124.l2p_clk_n);
val |= i_gn4124.l2p_data << 16;
val_check("DMA read-back", 'h20, val, expected);
repeat(2) @(posedge clk_125m);
// Test abort feature
acc.write('h00, 'h02);
reg_check('h04, 'h03);
acc.write('h00, 'h00);
repeat(2) @(posedge clk_125m);
$write("PASS\n");
-----/\----- EXCLUDED -----/\----- */
$
write
(
"Test %0d/%0d: 2x128B chained reads over DMA: "
,
ntest
++,
tests
)
;
...
...
@@ -347,26 +315,26 @@ module main;
#
1u
s
;
end
$
write
(
"Test %0d/%0d:
8K
B read over DMA with 32bit host address overflow: "
,
$
write
(
"Test %0d/%0d:
256
B read over DMA with 32bit host address overflow: "
,
ntest
++,
tests
)
;
acc
.
write
(
'h14
,
'h
20
00
)
;
// count
acc
.
write
(
'h14
,
'h
1
00
)
;
// count
acc
.
write
(
'h20
,
'h00
)
;
// attrib
acc
.
write
(
'h0c
,
'hfffff
00
0
)
;
// hstartL
acc
.
write
(
'h0c
,
'hfffff
f8
0
)
;
// 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_f
00
0 and the next one with a 64-bit
// one with a 32-bit adress starting at ffff_f
f8
0 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
,
'h02ff00
0
0
)
;
val_check
(
"Host address overflow header"
,
1
,
DUT
.
cmp_wrapped_gn4124
.
ldm_arb_data
,
'h02ff00
2
0
)
;
@
(
posedge
DUT
.
cmp_wrapped_gn4124
.
sys_clk
)
;
val_check
(
"Host address overflow address"
,
1
,
DUT
.
cmp_wrapped_gn4124
.
ldm_arb_data
,
'hfffff
00
0
)
;
val_check
(
"Host address overflow address"
,
1
,
DUT
.
cmp_wrapped_gn4124
.
ldm_arb_data
,
'hfffff
f8
0
)
;
@
(
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
,
'h03ff00
0
0
)
;
val_check
(
"Host address overflow header"
,
2
,
DUT
.
cmp_wrapped_gn4124
.
ldm_arb_data
,
'h03ff00
2
0
)
;
@
(
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
)
;
...
...
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