Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393_sata
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_sata
Commits
3b5ef7db
Commit
3b5ef7db
authored
Jul 23, 2015
by
Alexey Grebenkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
+ dma_control
parent
f8d03ec9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
268 additions
and
4 deletions
+268
-4
dma_adapter.v
dma_adapter.v
+1
-4
dma_control.v
dma_control.v
+267
-0
No files found.
dma_adapter.v
View file @
3b5ef7db
...
...
@@ -29,10 +29,7 @@
* a big dma data storage and axi interface. So it shall recieve data and control
* for 1 burst and pass it to axi.
*/
module
send_dma
#(
parameter
REGISTERS_CNT
=
20
)
(
module
dma_adapter
(
input
wire
clk
,
input
wire
rst
,
...
...
dma_control.v
0 → 100644
View file @
3b5ef7db
/*******************************************************************************
* Module: dma_control
* Date: 2015-07-11
* Author: Alexey
* Description: temporary dma request control logic
*
* Copyright (c) 2015 Elphel, Inc.
* dma_control.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* dma_control.v file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
/*
* Later on most of address evaluation logic could divided into 2 parts, which
* could be presented as 2 instances of 1 parameterized module
*/
module
dma_control
(
input
wire
sclk
,
// sata clock
input
wire
hclk
,
// axi-hp clock
input
wire
rst
,
// registers iface
input
wire
[
31
:
7
]
mem_address
,
input
wire
[
31
:
0
]
lba
,
input
wire
[
31
:
0
]
sector_cnt
,
input
wire
dma_type
,
input
wire
dma_start
,
output
wire
dma_done
,
// adapter data iface
// to main memory
output
wire
[
63
:
0
]
to_data
,
output
wire
to_val
,
input
wire
to_ack
,
// from main memory
input
wire
[
63
:
0
]
from_data
,
input
wire
from_val
,
input
wire
from_ack
// sata host iface
// data from sata host
input
wire
[
31
:
0
]
in_data
,
output
wire
in_val
,
input
wire
in_busy
,
// data to sata host
output
wire
[
31
:
0
]
out_data
,
output
wire
out_val
,
input
wire
out_busy
)
;
/*
* from main memory resyncronisation circuit
*/
reg
[
9
:
0
]
from_rd_addr
;
reg
[
8
:
0
]
from_wr_addr
;
// incremened addresses
wire
[
8
:
0
]
from_wr_next_addr
;
wire
[
9
:
0
]
from_rd_next_addr
;
// gray coded addresses
reg
[
9
:
0
]
from_rd_addr
;
reg
[
8
:
0
]
from_wr_addr
;
// anti-metastability shift registers for gray-coded addresses
reg
[
9
:
0
]
from_rd_addr_gr_r
;
reg
[
8
:
0
]
from_wr_addr_gr_r
;
reg
[
9
:
0
]
from_rd_addr_gr_rr
;
reg
[
8
:
0
]
from_wr_addr_gr_rr
;
// resynced to opposite clks addresses
wire
[
9
:
0
]
from_rd_addr_r
;
wire
[
8
:
0
]
from_wr_addr_r
;
// fifo states
wire
from_full
;
// MAY BE full. ~full -> MUST NOT be full
wire
from_empty
;
// MAY BE empty. ~empty -> MUST NOT be empty
wire
from_re
;
wire
from_we
;
assign
from_wr_next_addr
=
from_wr_addr
+
1'b1
;
assign
from_rd_next_addr
=
from_rd_addr
+
1'b1
;
// hclk domain counters
always
@
(
posedge
hclk
)
begin
from_wr_addr
<=
rst
?
9'h0
:
from_we
?
from_wr_next_addr
:
from_wr_addr
;
from_wr_addr_gr
<=
rst
?
9'h0
:
from_we
?
from_wr_next_addr
^
{
1'b0
,
from_wr_next_addr
[
8
:
1
]
}
:
from_wr_addr_gr
;
end
// sclk domain counters
always
@
(
posedge
sclk
)
begin
from_rd_addr
<=
rst
?
10'h0
:
from_re
?
from_rd_next_addr
:
from_rd_addr
;
from_rd_addr_gr
<=
rst
?
10'h0
:
from_re
?
from_rd_next_addr
^
{
1'b0
,
from_rd_next_addr
[
9
:
1
]
}
:
from_rd_addr_gr
;
end
// write address -> sclk (rd) domain to compare
always
@
(
posedge
sclk
)
begin
from_wr_addr_gr_r
<=
rst
?
9'h0
:
from_wr_addr
;
from_wr_addr_gr_rr
<=
rst
?
9'h0
:
from_wr_addr_rr
;
end
// read address -> hclk (wr) domain to compare
always
@
(
posedge
hclk
)
begin
from_rd_addr_gr_r
<=
rst
?
10'h0
:
from_rd_addr
;
from_rd_addr_gr_rr
<=
rst
?
10'h0
:
from_rd_addr_rr
;
end
// translate resynced write address into ordinary (non-gray) address
genvar
ii
;
generate
for
(
ii
=
0
;
ii
<
9
;
ii
=
ii
+
1
)
begin:
from_wr_antigray
assign
from_wr_addr_r
[
ii
]
=
^
from_wr_addr_gr_rr
[
8
:
ii
]
;
end
endgenerate
// translate resynced read address into ordinary (non-gray) address
generate
for
(
ii
=
0
;
ii
<
10
;
ii
=
ii
+
1
)
begin:
from_rd_antigray
assign
from_rd_addr_r
[
ii
]
=
^
from_rd_addr_gr_rr
[
9
:
ii
]
;
end
endgenerate
// so we've got the following:
// hclk domain: from_wr_addr - current write address
// from_rd_addr_r - read address some hclk ticks ago
// => we can say if the fifo have the possibility to be full
// since actual from_rd_addr could only be incremented
//
// sclk domain: from_rd_addr - current read address
// from_wr_addr_r - write address some sclk ticks ago
// => we can say if the fifo have the possibility to be empty
// since actual from_wr_addr could only be incremented
assign
from_full
=
{
from_wr_addr
,
1'b0
}
==
from_rd_addr_r
+
1'b1
;
assign
from_empty
=
{
from_wr_addr_r
,
1'b0
}
==
from_rd_addr
;
// overflows must never be achieved
// calculate bus responses in order to fifo status:
assign
from_ack
=
from_val
&
~
from_full
;
assign
out_val
=
~
out_busy
&
~
from_empty
;
assign
from_re
=
out_val
;
assign
from_we
=
from_ack
;
// data buffer, recieves 64-bit data from main memory, directs it to sata host
ram_512x64w_1kx32r
#(
.
REGISTERS
(
0
)
)
dma_data_from_mem
(
.
rclk
(
sclk
)
,
.
raddr
(
from_rd_addr
)
,
.
ren
(
from_re
)
,
.
regen
(
1'b0
)
,
.
data_out
(
out_data
)
,
.
wclk
(
hclk
)
,
.
waddr
(
from_wr_addr
)
,
.
we
(
from_we
)
,
.
web
(
8'hff
)
,
.
data_in
(
from_data
)
)
;
/////////////////////////////////////////////////////////////////////////////////
/*
* to main memory resyncronisation circuit
*/
reg
[
8
:
0
]
to_rd_addr
;
reg
[
9
:
0
]
to_wr_addr
;
// incremened addresses
wire
[
9
:
0
]
to_wr_next_addr
;
wire
[
8
:
0
]
to_rd_next_addr
;
// gray coded addresses
reg
[
8
:
0
]
to_rd_addr
;
reg
[
9
:
0
]
to_wr_addr
;
// anti-metastability shift registers for gray-coded addresses
reg
[
8
:
0
]
to_rd_addr_gr_r
;
reg
[
9
:
0
]
to_wr_addr_gr_r
;
reg
[
8
:
0
]
to_rd_addr_gr_rr
;
reg
[
9
:
0
]
to_wr_addr_gr_rr
;
// resynced to opposite clks addresses
wire
[
8
:
0
]
to_rd_addr_r
;
wire
[
9
:
0
]
to_wr_addr_r
;
// fifo states
wire
to_full
;
// MAY BE full. ~full -> MUST NOT be full
wire
to_empty
;
// MAY BE empty. ~empty -> MUST NOT be empty
wire
to_re
;
wire
to_we
;
assign
to_wr_next_addr
=
to_wr_addr
+
1'b1
;
assign
to_rd_next_addr
=
to_rd_addr
+
1'b1
;
// hclk domain counters
always
@
(
posedge
hclk
)
begin
to_wr_addr
<=
rst
?
10'h0
:
to_we
?
to_wr_next_addr
:
to_wr_addr
;
to_wr_addr_gr
<=
rst
?
10'h0
:
to_we
?
to_wr_next_addr
^
{
1'b0
,
to_wr_next_addr
[
9
:
1
]
}
:
to_wr_addr_gr
;
end
// sclk domain counters
always
@
(
posedge
sclk
)
begin
to_rd_addr
<=
rst
?
9'h0
:
to_re
?
to_rd_next_addr
:
to_rd_addr
;
to_rd_addr_gr
<=
rst
?
9'h0
:
to_re
?
to_rd_next_addr
^
{
1'b0
,
to_rd_next_addr
[
8
:
1
]
}
:
to_rd_addr_gr
;
end
// write address -> sclk (rd) domain to compare
always
@
(
posedge
sclk
)
begin
to_wr_addr_gr_r
<=
rst
?
10'h0
:
to_wr_addr
;
to_wr_addr_gr_rr
<=
rst
?
10'h0
:
to_wr_addr_rr
;
end
// read address -> hclk (wr) domain to compare
always
@
(
posedge
hclk
)
begin
to_rd_addr_gr_r
<=
rst
?
9'h0
:
to_rd_addr
;
to_rd_addr_gr_rr
<=
rst
?
9'h0
:
to_rd_addr_rr
;
end
// translate resynced write address into ordinary (non-gray) address
genvar
ii
;
generate
for
(
ii
=
0
;
ii
<
10
;
ii
=
ii
+
1
)
begin:
to_wr_antigray
assign
to_wr_addr_r
[
ii
]
=
^
to_wr_addr_gr_rr
[
9
:
ii
]
;
end
endgenerate
// translate resynced read address into ordinary (non-gray) address
generate
for
(
ii
=
0
;
ii
<
9
;
ii
=
ii
+
1
)
begin:
to_rd_antigray
assign
to_rd_addr_r
[
ii
]
=
^
to_rd_addr_gr_rr
[
8
:
ii
]
;
end
endgenerate
// so we've got the following:
// hclk domain: to_wr_addr - current write address
// to_rd_addr_r - read address some hclk ticks ago
// => we can say if the fifo have the possibility to be full
// since actual to_rd_addr could only be incremented
//
// sclk domain: to_rd_addr - current read address
// to_wr_addr_r - write address some sclk ticks ago
// => we can say if the fifo have the possibility to be empty
// since actual to_wr_addr could only be incremented
assign
to_full
=
{
to_wr_addr
,
1'b0
}
==
to_rd_addr_r
+
1'b1
;
assign
to_empty
=
{
to_wr_addr_r
,
1'b0
}
==
to_rd_addr
;
// overflows must never be achieved
// calculate bus responses in order to fifo status:
assign
to_val
=
~
to_empty
;
assign
in_val
=
~
in_busy
&
~
to_full
;
assign
to_re
=
to_ack
;
assign
to_we
=
in_val
;
// data buffer, recieves 32-bit data from sata host, directs it to the main memory
ram_1kx32w_512x64r
#(
.
REGISTERS
(
0
)
)
dma_data_to_mem
(
.
rclk
(
hclk
)
,
.
raddr
(
to_rd_addr
)
,
.
ren
(
to_re
)
,
.
regen
(
1'b0
)
,
.
data_out
(
to_data
)
,
.
wclk
(
sclk
)
,
.
waddr
(
to_wr_addr
)
,
.
we
(
to_we
)
,
.
web
(
4'hf
)
,
.
data_in
(
in_data
)
)
;
endmodule
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