Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
x393
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
Commits
a445ef42
Commit
a445ef42
authored
Feb 20, 2015
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added another channel for testing - tile write
parent
31a6b971
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
789 additions
and
5056 deletions
+789
-5056
.editor_defines.vh
.editor_defines.vh
+5
-3
axibram.v
axi/axibram.v
+0
-360
axibram_write.v
axi/axibram_write.v
+4
-1
ddrc_test01.v
ddrc_test01.v
+0
-1550
ddrc_test01_testbench.tf
ddrc_test01_testbench.tf
+0
-2867
x393_localparams.vh
includes/x393_localparams.vh
+1
-1
x393_parameters.vh
includes/x393_parameters.vh
+8
-2
x393_tasks_mcntrl_buffers.vh
includes/x393_tasks_mcntrl_buffers.vh
+1
-0
x393_tasks_pio_sequences.vh
includes/x393_tasks_pio_sequences.vh
+8
-8
x393_tasks_status.vh
includes/x393_tasks_status.vh
+3
-0
cmd_encod_linear_rd.v
memctrl/cmd_encod_linear_rd.v
+2
-2
cmd_encod_linear_wr.v
memctrl/cmd_encod_linear_wr.v
+0
-69
cmd_encod_tiled_32_rd.v
memctrl/cmd_encod_tiled_32_rd.v
+1
-1
cmd_encod_tiled_rd.v
memctrl/cmd_encod_tiled_rd.v
+13
-61
mcntrl393.v
memctrl/mcntrl393.v
+254
-43
mcntrl393_test01.v
memctrl/mcntrl393_test01.v
+88
-29
mcntrl_tiled_rw.v
memctrl/mcntrl_tiled_rw.v
+2
-2
memctrl16.v
memctrl/memctrl16.v
+1
-1
ddrc_sequencer.v
memctrl/phy/ddrc_sequencer.v
+1
-0
mcontr_sequencer.v
memctrl/phy/mcontr_sequencer.v
+1
-1
mcont_from_chnbuf_reg.v
util_modules/mcont_from_chnbuf_reg.v
+2
-1
x393.v
x393.v
+39
-6
x393_testbench01.sav
x393_testbench01.sav
+276
-22
x393_testbench01.tf
x393_testbench01.tf
+79
-26
No files found.
.editor_defines.vh
View file @
a445ef42
...
...
@@ -2,7 +2,7 @@
// TODO: Fix VDT - without IVERILOG defined, closure does not include modules needed for Icarus
`define IVERILOG 1
`define USE_CMD_ENCOD_TILED_32_RD 1
// It can be used to check different `ifdef branches
//`define XIL_TIMING //Simprim
`define den4096Mb 1
...
...
@@ -33,8 +33,10 @@
`define def_read_mem_chn4
`define def_tiled_chn4
// chn 5 is disabled
`undef def_enable_mem_chn5
// chn 5 is enabled
`define def_enable_mem_chn5
`undef def_read_mem_chn5
`define def_tiled_chn5
// chn 6 is disabled
`undef def_enable_mem_chn6
...
...
axi/axibram.v
deleted
100644 → 0
View file @
31a6b971
/*******************************************************************************
* Module: axibram
* Date:2014-03-18
* Author: Andrey Filippov
* Description:
*
* Copyright (c) 2014 Elphel, Inc.
* axibram.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.
*
* axibram.v 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/> .
*******************************************************************************/
module
axibram
(
input
aclk
,
// clock - should be buffered
input
aresetn
,
// reset, active low
// AXI Read Address
input
[
31
:
0
]
araddr
,
// ARADDR[31:0], input
input
arvalid
,
// ARVALID, input
output
arready
,
// ARREADY, output
input
[
11
:
0
]
arid
,
// ARID[11:0], input
// input [ 1:0] arlock, // ARLOCK[1:0], input
// input [ 3:0] archache,// ARCACHE[3:0], input
// input [ 2:0] arprot, // ARPROT[2:0], input
input
[
3
:
0
]
arlen
,
// ARLEN[3:0], input
input
[
1
:
0
]
arsize
,
// ARSIZE[1:0], input
input
[
1
:
0
]
arburst
,
// ARBURST[1:0], input
// input [ 3:0] adqos, // ARQOS[3:0], input
// AXI Read Data
output
[
31
:
0
]
rdata
,
// RDATA[31:0], output
output
reg
rvalid
,
// RVALID, output
input
rready
,
// RREADY, input
output
reg
[
11
:
0
]
rid
,
// RID[11:0], output
output
reg
rlast
,
// RLAST, output
output
[
1
:
0
]
rresp
,
// RRESP[1:0], output
// AXI Write Address
input
[
31
:
0
]
awaddr
,
// AWADDR[31:0], input
input
awvalid
,
// AWVALID, input
output
awready
,
// AWREADY, output
input
[
11
:
0
]
awid
,
// AWID[11:0], input
// input [ 1:0] awlock, // AWLOCK[1:0], input
// input [ 3:0] awcache, // AWCACHE[3:0], input
// input [ 2:0] awprot, // AWPROT[2:0], input
input
[
3
:
0
]
awlen
,
// AWLEN[3:0], input
input
[
1
:
0
]
awsize
,
// AWSIZE[1:0], input
input
[
1
:
0
]
awburst
,
// AWBURST[1:0], input
// input [ 3:0] awqos, // AWQOS[3:0], input
// AXI PS Master GP0: Write Data
input
[
31
:
0
]
wdata
,
// WDATA[31:0], input
input
wvalid
,
// WVALID, input
output
wready
,
// WREADY, output
input
[
11
:
0
]
wid
,
// WID[11:0], input
input
wlast
,
// WLAST, input
input
[
3
:
0
]
wstb
,
// WSTRB[3:0], input
// AXI PS Master GP0: Write Responce
output
bvalid
,
// BVALID, output
input
bready
,
// BREADY, input
output
[
11
:
0
]
bid
,
// BID[11:0], output
output
[
1
:
0
]
bresp
// BRESP[1:0], output
)
;
// **** Read channel ****
wire
ar_nempty
;
wire
ar_half_full
;
assign
arready
=~
ar_half_full
;
wire
[
1
:
0
]
arburst_out
;
// SuppressWarnings VEditor all
wire
[
1
:
0
]
arsize_out
;
// not used
wire
[
3
:
0
]
arlen_out
;
wire
[
9
:
0
]
araddr_out
;
wire
[
11
:
0
]
arid_out
;
wire
rst
=~
aresetn
;
reg
read_in_progress
=
0
;
reg
read_in_progress_d
=
0
;
// delayed by one active cycle (not skipped)
reg
read_in_progress_or
=
0
;
// read_in_progress || read_in_progress_d
reg
[
9
:
0
]
read_address
;
// transfer address (not including lower bits
reg
[
3
:
0
]
read_left
;
// number of read transfers
// will ignore arsize - assuming always 32 bits (a*size[2:0]==2)
reg
[
1
:
0
]
rburst
;
// registered burst type
reg
[
3
:
0
]
rlen
;
// registered burst type
wire
[
9
:
0
]
next_rd_address_w
;
// next transfer address;
assign
next_rd_address_w
=
rburst
[
1
]
?
(
rburst
[
0
]
?
(
10'h0
)
:
((
read_address
[
9
:
0
]
+
1
)
&
{
6'h3f
,
~
rlen
[
3
:
0
]
}
))
:
(
rburst
[
0
]
?
(
read_address
[
9
:
0
]
+
1
)
:
(
read_address
[
9
:
0
]))
;
wire
start_read_burst_w
;
// wire bram_re_w;
wire
bram_reg_re_w
;
wire
read_in_progress_w
;
wire
read_in_progress_d_w
;
wire
last_in_burst_w
;
wire
last_in_burst_d_w
;
reg
pre_last_in_burst_r
;
assign
rresp
=
2'b0
;
// reduce combinatorial delay from rready (use it in final mux)
// assign bram_reg_re_w= read_in_progress && (!rvalid || rready);
// assign start_read_burst_w=ar_nempty && (!read_in_progress || (bram_reg_re_w && (read_left==4'b0))); // reduce delay from arready
assign
last_in_burst_w
=
bram_reg_re_w
&&
(
read_left
==
4'b0
)
;
assign
last_in_burst_d_w
=
bram_reg_re_w
&&
pre_last_in_burst_r
;
// make sure ar_nempty is updated
// assign start_read_burst_w=ar_nempty && (!read_in_progress || last_in_burst_w); // reduce delay from arready
assign
read_in_progress_w
=
start_read_burst_w
||
(
read_in_progress
&&
!
last_in_burst_w
)
;
// reduce delay from arready
assign
read_in_progress_d_w
=
(
read_in_progress
&&
bram_reg_re_w
)
||
(
read_in_progress
&&
!
last_in_burst_d_w
)
;
// reduce delay from arready
// assign read_in_progress_d_w=read_in_progress_d;
wire
pre_rvalid_w
;
assign
pre_rvalid_w
=
bram_reg_re_w
||
(
rvalid
&&
!
rready
)
;
reg
bram_reg_re_0
;
wire
pre_left_zero_w
;
reg
last_in_burst_1
;
reg
last_in_burst_0
;
reg
start_read_burst_0
;
reg
start_read_burst_1
;
reg
[
11
:
0
]
pre_rid0
;
reg
[
11
:
0
]
pre_rid
;
always
@
(
posedge
aclk
or
posedge
rst
)
begin
if
(
rst
)
pre_last_in_burst_r
<=
0
;
// else if (start_read_burst_w) pre_last_in_burst_r <= (read_left==4'b0);
else
if
(
bram_reg_re_w
)
pre_last_in_burst_r
<=
(
read_left
==
4'b0
)
;
if
(
rst
)
rburst
[
1
:
0
]
<=
0
;
else
if
(
start_read_burst_w
)
rburst
[
1
:
0
]
<=
arburst_out
[
1
:
0
]
;
if
(
rst
)
rlen
[
3
:
0
]
<=
0
;
else
if
(
start_read_burst_w
)
rlen
[
3
:
0
]
<=
arlen_out
[
3
:
0
]
;
if
(
rst
)
read_in_progress
<=
0
;
else
read_in_progress
<=
read_in_progress_w
;
if
(
rst
)
read_in_progress_d
<=
0
;
// else read_in_progress_d <= read_in_progress_d_w;
else
if
(
bram_reg_re_w
)
read_in_progress_d
<=
read_in_progress_d_w
;
if
(
rst
)
read_in_progress_or
<=
0
;
// else read_in_progress_or <= read_in_progress_d_w || read_in_progress_w;
// else if (bram_reg_re_w) read_in_progress_or <= read_in_progress_d_w || read_in_progress_w;
// FIXME:
else
if
(
bram_reg_re_w
||
!
read_in_progress_or
)
read_in_progress_or
<=
read_in_progress_d_w
||
read_in_progress_w
;
// reg read_in_progress_d=0; // delayed by one active cycle (not skipped)
// reg read_in_progress_or=0; // read_in_progress || read_in_progress_d
if
(
rst
)
read_left
<=
0
;
else
if
(
start_read_burst_w
)
read_left
<=
arlen_out
[
3
:
0
]
;
// precedence over inc
else
if
(
bram_reg_re_w
)
read_left
<=
read_left
-
1
;
if
(
rst
)
read_address
<=
10'b0
;
else
if
(
start_read_burst_w
)
read_address
<=
araddr_out
[
9
:
0
]
;
// precedence over inc
else
if
(
bram_reg_re_w
)
read_address
<=
next_rd_address_w
;
if
(
rst
)
rvalid
<=
1'b0
;
else
if
(
bram_reg_re_w
&&
read_in_progress_d
)
rvalid
<=
1'b1
;
else
if
(
rready
)
rvalid
<=
1'b0
;
if
(
rst
)
rlast
<=
1'b0
;
else
if
(
last_in_burst_d_w
)
rlast
<=
1'b1
;
else
if
(
rready
)
rlast
<=
1'b0
;
end
always
@
(
posedge
aclk
)
begin
// bram_reg_re_0 <= read_in_progress_w && !pre_rvalid_w;
bram_reg_re_0
<=
(
ar_nempty
&&
!
read_in_progress
)
||
(
read_in_progress
&&
!
read_in_progress
)
;
last_in_burst_1
<=
read_in_progress_w
&&
pre_left_zero_w
;
last_in_burst_0
<=
read_in_progress_w
&&
!
pre_rvalid_w
&&
pre_left_zero_w
;
start_read_burst_1
<=
!
read_in_progress_w
||
pre_left_zero_w
;
start_read_burst_0
<=
!
read_in_progress_w
||
(
!
pre_rvalid_w
&&
pre_left_zero_w
)
;
if
(
start_read_burst_w
)
pre_rid0
[
11
:
0
]
<=
arid_out
[
11
:
0
]
;
if
(
bram_reg_re_w
)
pre_rid
[
11
:
0
]
<=
pre_rid0
[
11
:
0
]
;
if
(
bram_reg_re_w
)
rid
[
11
:
0
]
<=
pre_rid
[
11
:
0
]
;
end
// reducing rready combinatorial delay
assign
pre_left_zero_w
=
start_read_burst_w
?
(
arlen_out
[
3
:
0
]
==
4'b0
)
:
(
bram_reg_re_w
&&
(
read_left
==
4'b0001
))
;
// assign bram_reg_re_w= read_in_progress && (!rvalid || rready);
assign
bram_reg_re_w
=
read_in_progress_or
&&
(
!
rvalid
||
rready
)
;
// slower/simplier
// assign bram_reg_re_w= rready? read_in_progress : bram_reg_re_0; // faster - more verification
assign
last_in_burst_w
=
bram_reg_re_w
&&
(
read_left
==
4'b0
)
;
// slower/simplier
// assign last_in_burst_w=rready? (read_in_progress && (read_left==4'b0)): (bram_reg_re_0 && (read_left==4'b0));
// assign last_in_burst_w=rready? last_in_burst_1: last_in_burst_0; // faster (unfinished) - more verification
assign
start_read_burst_w
=
ar_nempty
&&
(
!
read_in_progress
||
(
bram_reg_re_w
&&
(
read_left
==
4'b0
)))
;
// reduce delay from rready
// assign start_read_burst_w=ar_nempty && (!read_in_progress || ((rready? read_in_progress : bram_reg_re_0) && (read_left==4'b0)));
// assign start_read_burst_w=
// rready?
// (ar_nempty && (!read_in_progress || ((read_in_progress) && (read_left==4'b0)))):
// (ar_nempty && (!read_in_progress || ((bram_reg_re_0 ) && (read_left==4'b0))));
/*
assign start_read_burst_w=
ar_nempty*(rready?
(!read_in_progress || (read_left==4'b0)):
((!read_in_progress || ((bram_reg_re_0 ) && (read_left==4'b0)))));
*/
// assign start_read_burst_w= ar_nempty && (rready?start_read_burst_1:start_read_burst_0);
// **** Write channel: ****
wire
aw_nempty
;
wire
aw_half_full
;
assign
awready
=~
aw_half_full
;
wire
[
1
:
0
]
awburst_out
;
// SuppressWarnings VEditor all
wire
[
1
:
0
]
awsize_out
;
// not used
wire
[
3
:
0
]
awlen_out
;
wire
[
9
:
0
]
awaddr_out
;
// SuppressWarnings VEditor all
wire
[
11
:
0
]
awid_out
;
// not used
wire
w_nempty
;
wire
w_half_full
;
assign
wready
=~
w_half_full
;
wire
[
31
:
0
]
wdata_out
;
// SuppressWarnings VEditor all
wire
wlast_out
;
// not used
wire
[
3
:
0
]
wstb_out
;
// WSTRB[3:0], input
wire
[
11
:
0
]
wid_out
;
reg
write_in_progress
=
0
;
reg
[
9
:
0
]
write_address
;
// transfer address (not including lower bits
reg
[
3
:
0
]
write_left
;
// number of read transfers
// will ignore arsize - assuming always 32 bits (a*size[2:0]==2)
reg
[
1
:
0
]
wburst
;
// registered burst type
reg
[
3
:
0
]
wlen
;
// registered awlen type (for wrapped over transfers)
wire
[
9
:
0
]
next_wr_address_w
;
// next transfer address;
wire
bram_we_w
;
// write BRAM memory
wire
start_write_burst_w
;
wire
write_in_progress_w
;
assign
next_wr_address_w
=
wburst
[
1
]
?
(
wburst
[
0
]
?
(
10'h0
)
:
((
write_address
[
9
:
0
]
+
1
)
&
{
6'h3f
,
~
wlen
[
3
:
0
]
}
))
:
(
wburst
[
0
]
?
(
write_address
[
9
:
0
]
+
1
)
:
(
write_address
[
9
:
0
]))
;
assign
bram_we_w
=
w_nempty
&&
write_in_progress
;
assign
start_write_burst_w
=
aw_nempty
&&
(
!
write_in_progress
||
(
w_nempty
&&
(
write_left
[
3
:
0
]
==
4'b0
)))
;
assign
write_in_progress_w
=
aw_nempty
||
(
write_in_progress
&&
!
(
w_nempty
&&
(
write_left
[
3
:
0
]
==
4'b0
)))
;
always
@
(
posedge
aclk
or
posedge
rst
)
begin
if
(
rst
)
wburst
[
1
:
0
]
<=
0
;
else
if
(
start_write_burst_w
)
wburst
[
1
:
0
]
<=
awburst_out
[
1
:
0
]
;
if
(
rst
)
wlen
[
3
:
0
]
<=
0
;
else
if
(
start_write_burst_w
)
wlen
[
3
:
0
]
<=
awlen_out
[
3
:
0
]
;
if
(
rst
)
write_in_progress
<=
0
;
else
write_in_progress
<=
write_in_progress_w
;
if
(
rst
)
write_left
<=
0
;
else
if
(
start_write_burst_w
)
write_left
<=
awlen_out
[
3
:
0
]
;
// precedence over inc
else
if
(
bram_we_w
)
write_left
<=
write_left
-
1
;
if
(
rst
)
write_address
<=
10'b0
;
else
if
(
start_write_burst_w
)
write_address
<=
awaddr_out
[
9
:
0
]
;
// precedence over inc
else
if
(
bram_we_w
)
write_address
<=
next_wr_address_w
;
end
// **** Write responce channel ****
wire
[
1
:
0
]
bresp_in
;
assign
bresp_in
=
2'b0
;
/*
output bvalid, // BVALID, output
input bready, // BREADY, input
output [11:0] bid, // BID[11:0], output
output [ 1:0] bresp // BRESP[1:0], output
*/
/*
reg bram_reg_re_r;
always @ (posedge aclk) begin
bram_reg_re_r <= bram_reg_re_w;
end
*/
ram_1kx32_1kx32
#(
.
REGISTERS
(
1
)
// 1 - registered output
)
ram_1kx32_1kx32_i
(
.
rclk
(
aclk
)
,
// clock for read port
.
raddr
(
read_in_progress
?
read_address
[
9
:
0
]
:
10'h3ff
)
,
// read address
// .ren(read_in_progress_or) , // read port enable
.
ren
(
bram_reg_re_w
)
,
// read port enable
.
regen
(
bram_reg_re_w
)
,
// output register enable
// .regen(bram_reg_re_r), // output register enable
.
data_out
(
rdata
[
31
:
0
])
,
// data out
.
wclk
(
aclk
)
,
// clock for read port
.
waddr
(
write_address
[
9
:
0
])
,
// write address
.
we
(
bram_we_w
)
,
// write port enable
.
web
(
wstb_out
[
3
:
0
])
,
// write byte enable
.
data_in
(
wdata_out
[
31
:
0
])
// data out
)
;
fifo_same_clock
#(
.
DATA_WIDTH
(
30
)
,.
DATA_DEPTH
(
4
))
raddr_i
(
.
rst
(
rst
)
,
.
clk
(
aclk
)
,
.
we
(
arvalid
&&
arready
)
,
.
re
(
start_read_burst_w
)
,
.
data_in
(
{
arid
[
11
:
0
]
,
arburst
[
1
:
0
]
,
arsize
[
1
:
0
]
,
arlen
[
3
:
0
]
,
araddr
[
11
:
2
]
}
)
,
.
data_out
(
{
arid_out
[
11
:
0
]
,
arburst_out
[
1
:
0
]
,
arsize_out
[
1
:
0
]
,
arlen_out
[
3
:
0
]
,
araddr_out
[
9
:
0
]
}
)
,
.
nempty
(
ar_nempty
)
,
.
full
()
,
.
half_full
(
ar_half_full
)
)
;
fifo_same_clock
#(
.
DATA_WIDTH
(
30
)
,.
DATA_DEPTH
(
4
))
waddr_i
(
.
rst
(
rst
)
,
.
clk
(
aclk
)
,
.
we
(
awvalid
&&
awready
)
,
.
re
(
start_write_burst_w
)
,
.
data_in
(
{
awid
[
11
:
0
]
,
awburst
[
1
:
0
]
,
awsize
[
1
:
0
]
,
awlen
[
3
:
0
]
,
awaddr
[
11
:
2
]
}
)
,
.
data_out
(
{
awid_out
[
11
:
0
]
,
awburst_out
[
1
:
0
]
,
awsize_out
[
1
:
0
]
,
awlen_out
[
3
:
0
]
,
awaddr_out
[
9
:
0
]
}
)
,
.
nempty
(
aw_nempty
)
,
.
full
()
,
.
half_full
(
aw_half_full
)
)
;
fifo_same_clock
#(
.
DATA_WIDTH
(
49
)
,.
DATA_DEPTH
(
4
))
wdata_i
(
.
rst
(
rst
)
,
.
clk
(
aclk
)
,
.
we
(
wvalid
&&
wready
)
,
.
re
(
bram_we_w
)
,
//start_write_burst_w), // wrong
.
data_in
(
{
wid
[
11
:
0
]
,
wlast
,
wstb
[
3
:
0
]
,
wdata
[
31
:
0
]
}
)
,
.
data_out
(
{
wid_out
[
11
:
0
]
,
wlast_out
,
wstb_out
[
3
:
0
]
,
wdata_out
[
31
:
0
]
}
)
,
.
nempty
(
w_nempty
)
,
.
full
()
,
.
half_full
(
w_half_full
)
)
;
fifo_same_clock
#(
.
DATA_WIDTH
(
14
)
,.
DATA_DEPTH
(
4
))
wresp_i
(
.
rst
(
rst
)
,
.
clk
(
aclk
)
,
.
we
(
bram_we_w
)
,
.
re
(
bready
&&
bvalid
)
,
.
data_in
(
{
wid_out
[
11
:
0
]
,
bresp_in
[
1
:
0
]
}
)
,
.
data_out
(
{
bid
[
11
:
0
]
,
bresp
[
1
:
0
]
}
)
,
.
nempty
(
bvalid
)
,
.
full
()
,
.
half_full
()
)
;
endmodule
axi/axibram_write.v
View file @
a445ef42
...
...
@@ -19,7 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`define
DEBUG_FIFO 1
//
`define DEBUG_FIFO 1
module
axibram_write
#(
parameter
ADDRESS_BITS
=
10
// number of memory address bits
)(
...
...
@@ -197,6 +197,7 @@ fifo_same_clock #( .DATA_WIDTH(20+ADDRESS_BITS),.DATA_DEPTH(4))
waddr_i
(
.
rst
(
rst
)
,
.
clk
(
aclk
)
,
.
sync_rst
(
1'b0
)
,
.
we
(
awvalid
&&
awready
)
,
.
re
(
start_write_burst_w
)
,
.
data_in
(
{
awid
[
11
:
0
]
,
awburst
[
1
:
0
]
,
awsize
[
1
:
0
]
,
awlen
[
3
:
0
]
,
awaddr
[
ADDRESS_BITS
+
1
:
2
]
}
)
,
...
...
@@ -216,6 +217,7 @@ fifo_same_clock #( .DATA_WIDTH(49),.DATA_DEPTH(4))
wdata_i
(
.
rst
(
rst
)
,
.
clk
(
aclk
)
,
.
sync_rst
(
1'b0
)
,
.
we
(
wvalid
&&
wready
)
,
.
re
(
bram_we_w
)
,
//start_write_burst_w), // wrong
.
data_in
(
{
wid
[
11
:
0
]
,
wlast
,
wstb
[
3
:
0
]
,
wdata
[
31
:
0
]
}
)
,
...
...
@@ -244,6 +246,7 @@ fifo_same_clock #( .DATA_WIDTH(14),.DATA_DEPTH(4))
wresp_i
(
.
rst
(
rst
)
,
.
clk
(
aclk
)
,
.
sync_rst
(
1'b0
)
,
.
we
(
bram_we_w
)
,
// .re(bready && bvalid),
.
re
(
bresp_re
)
,
// not allowing RE next cycle after bvalid
...
...
ddrc_test01.v
deleted
100644 → 0
View file @
31a6b971
/*******************************************************************************
* Module: ddrc_test01
* Date:2014-05-18
* Author: Andrey Filippov
* Description: DDR3 controller test with axi
*
* Copyright (c) 2014 Elphel, Inc.
* ddrc_test01.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.
*
* ddrc_test01.v 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/> .
*******************************************************************************/
`timescale
1
ns
/
1
ps
`define
use200Mhz 1
`define
DEBUG_FIFO 1
module
ddrc_test01
#(
parameter
PHASE_WIDTH
=
8
,
parameter
SLEW_DQ
=
"SLOW"
,
parameter
SLEW_DQS
=
"SLOW"
,
parameter
SLEW_CMDA
=
"SLOW"
,
parameter
SLEW_CLK
=
"SLOW"
,
parameter
IBUF_LOW_PWR
=
"TRUE"
,
`ifdef
use200Mhz
parameter
real
REFCLK_FREQUENCY
=
200.0
,
// 300.0,
parameter
HIGH_PERFORMANCE_MODE
=
"FALSE"
,
parameter
CLKIN_PERIOD
=
20
,
// 10, //ns >1.25, 600<Fvco<1200 // Hardware 150MHz , change to | 6.667
parameter
CLKFBOUT_MULT
=
16
,
// 8, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE | 16
parameter
CLKFBOUT_MULT_REF
=
16
,
// 18, // 9, // Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE | 6
parameter
CLKFBOUT_DIV_REF
=
4
,
// 200Mhz 3, // To get 300MHz for the reference clock
`else
parameter
real
REFCLK_FREQUENCY
=
300.0
,
parameter
HIGH_PERFORMANCE_MODE
=
"FALSE"
,
parameter
CLKIN_PERIOD
=
10
,
//ns >1.25, 600<Fvco<1200
parameter
CLKFBOUT_MULT
=
8
,
// Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
parameter
CLKFBOUT_MULT_REF
=
9
,
// Fvco=Fclkin*CLKFBOUT_MULT_F/DIVCLK_DIVIDE, Fout=Fvco/CLKOUT#_DIVIDE
parameter
CLKFBOUT_DIV_REF
=
3
,
// To get 300MHz for the reference clock
`endif
parameter
DIVCLK_DIVIDE
=
1
,
parameter
CLKFBOUT_PHASE
=
0.000
,
parameter
SDCLK_PHASE
=
0.000
,
parameter
CLK_PHASE
=
0.000
,
parameter
CLK_DIV_PHASE
=
0.000
,
parameter
MCLK_PHASE
=
90.000
,
parameter
REF_JITTER1
=
0.010
,
parameter
SS_EN
=
"FALSE"
,
parameter
SS_MODE
=
"CENTER_HIGH"
,
parameter
SS_MOD_PERIOD
=
10000
,
parameter
CMD_PAUSE_BITS
=
10
,
parameter
CMD_DONE_BIT
=
10
,
parameter
AXI_WR_ADDR_BITS
=
13
,
parameter
AXI_RD_ADDR_BITS
=
13
,
parameter
CONTROL_ADDR
=
'h1000
,
// AXI write address of control write registers
parameter
CONTROL_ADDR_MASK
=
'h1400
,
// AXI write address of control registers
parameter
STATUS_ADDR
=
'h1400
,
// AXI write address of status read registers
parameter
STATUS_ADDR_MASK
=
'h1400
,
// AXI write address of status registers
parameter
BUSY_WR_ADDR
=
'h1800
,
// AXI write address to generate busy
parameter
BUSY_WR_ADDR_MASK
=
'h1c00
,
// AXI write address mask to generate busy
parameter
CMD0_ADDR
=
'h0800
,
// AXI write to command sequence memory
parameter
CMD0_ADDR_MASK
=
'h1800
,
// AXI read address mask for the command sequence memory
parameter
PORT0_RD_ADDR
=
'h0000
,
// AXI read address to generate busy
parameter
PORT0_RD_ADDR_MASK
=
'h1c00
,
// AXI read address mask to generate busy
parameter
PORT1_WR_ADDR
=
'h0400
,
// AXI read address to generate busy
parameter
PORT1_WR_ADDR_MASK
=
'h1c00
,
// AXI read address mask to generate busy
// parameters below to be ORed with CONTROL_ADDR and CONTROL_ADDR_MASK respectively
parameter
DLY_LD_REL
=
'h080
,
// address to generate delay load
parameter
DLY_LD_REL_MASK
=
'h380
,
// address mask to generate delay load
parameter
DLY_SET_REL
=
'h070
,
// address to generate delay set
parameter
DLY_SET_REL_MASK
=
'h3ff
,
// address mask to generate delay set
parameter
RUN_CHN_REL
=
'h000
,
// address to set sequnecer channel and run (4 LSB-s - channel)
parameter
RUN_CHN_REL_MASK
=
'h3f0
,
// address mask to generate sequencer channel/run
parameter
PATTERNS_REL
=
'h020
,
// address to set DQM and DQS patterns (16'h0055)
parameter
PATTERNS_REL_MASK
=
'h3ff
,
// address mask to set DQM and DQS patterns
parameter
PATTERNS_TRI_REL
=
'h021
,
// address to set DQM and DQS tristate on/off patterns {dqs_off,dqs_on, dq_off,dq_on} - 4 bits each
parameter
PATTERNS_TRI_REL_MASK
=
'h3ff
,
// address mask to set DQM and DQS tristate patterns
parameter
WBUF_DELAY_REL
=
'h022
,
// extra delay (in mclk cycles) to add to write buffer enable (DDR3 read data)
parameter
WBUF_DELAY_REL_MASK
=
'h3ff
,
// address mask to set extra delay
parameter
PAGES_REL
=
'h023
,
// address to set buffer pages {port1_page[1:0],port1_int_page[1:0],port0_page[1:0],port0_int_page[1:0]}
parameter
PAGES_REL_MASK
=
'h3ff
,
// address mask to set DQM and DQS patterns
parameter
CMDA_EN_REL
=
'h024
,
// address to enable('h825)/disable('h824) command/address outputs
parameter
CMDA_EN_REL_MASK
=
'h3fe
,
// address mask for command/address outputs
parameter
SDRST_ACT_REL
=
'h026
,
// address to activate('h827)/deactivate('h826) active-low reset signal to DDR3 memory
parameter
SDRST_ACT_REL_MASK
=
'h3fe
,
// address mask for reset DDR3
parameter
CKE_EN_REL
=
'h028
,
// address to enable('h829)/disable('h828) CKE signal to memory
parameter
CKE_EN_REL_MASK
=
'h3fe
,
// address mask for command/address outputs
parameter
DCI_RST_REL
=
'h02a
,
// address to activate('h82b)/deactivate('h82a) Zynq DCI calibrate circuitry
parameter
DCI_RST_REL_MASK
=
'h3fe
,
// address mask for DCI calibrate circuitry
parameter
DLY_RST_REL
=
'h02c
,
// address to activate('h82d)/deactivate('h82c) delay calibration circuitry
parameter
DLY_RST_REL_MASK
=
'h3fe
,
// address mask for delay calibration circuitry
parameter
EXTRA_REL
=
'h02e
,
// address to set extra parameters (currently just inv_clk_div)
parameter
EXTRA_REL_MASK
=
'h3ff
,
// address mask for extra parameters
parameter
REFRESH_EN_REL
=
'h030
,
// address to enable('h31) and disable ('h30) DDR refresh
parameter
REFRESH_EN_REL_MASK
=
'h3fe
,
// address mask to enable/disable DDR refresh
parameter
REFRESH_PER_REL
=
'h032
,
// address to set refresh period in 32 x tCK
parameter
REFRESH_PER_REL_MASK
=
'h3ff
,
// address mask set refresh period
parameter
REFRESH_ADDR_REL
=
'h033
,
// address to set sequencer start address for DDR refresh
parameter
REFRESH_ADDR_REL_MASK
=
'h3ff
// address mask set refresh sequencer address
)(
// DDR3 interface
output
SDRST
,
// DDR3 reset (active low)
output
SDCLK
,
// DDR3 clock differential output, positive
output
SDNCLK
,
// DDR3 clock differential output, negative
output
[
ADDRESS_NUMBER
-
1
:
0
]
SDA
,
// output address ports (14:0) for 4Gb device
output
[
2
:
0
]
SDBA
,
// output bank address ports
output
SDWE
,
// output WE port
output
SDRAS
,
// output RAS port
output
SDCAS
,
// output CAS port
output
SDCKE
,
// output Clock Enable port
output
SDODT
,
// output ODT port
inout
[
15
:
0
]
SDD
,
// DQ I/O pads
output
SDDML
,
// LDM I/O pad (actually only output)
inout
DQSL
,
// LDQS I/O pad
inout
NDQSL
,
// ~LDQS I/O pad
output
SDDMU
,
// UDM I/O pad (actually only output)
inout
DQSU
,
// UDQS I/O pad
inout
NDQSU
,
output
DUMMY_TO_KEEP
,
// to keep PS7 signals from "optimization"
input
MEMCLK
// ~UDQS I/O pad
// AXI write (ps -> pl)
)
;
localparam
ADDRESS_NUMBER
=
15
;
// Source for reset and clock
wire
[
3
:
0
]
fclk
;
// PL Clocks [3:0], output
wire
[
3
:
0
]
frst
;
// PL Clocks [3:0], output
// AXI write interface signals
//(* keep = "true" *)
wire
axi_aclk
;
// clock - should be buffered
// wire axi_naclk; // debugging
// wire axi_aresetn; // reset, active low
//(* dont_touch = "true" *)
wire
axi_rst
;
// reset, active high
// AXI Write Address
wire
[
31
:
0
]
axi_awaddr
;
// AWADDR[31:0], input
wire
axi_awvalid
;
// AWVALID, input
wire
axi_awready
;
// AWREADY, output
wire
[
11
:
0
]
axi_awid
;
// AWID[11:0], input
// input [ 1:0] awlock, // AWLOCK[1:0], input
// input [ 3:0] awcache, // AWCACHE[3:0], input
// input [ 2:0] awprot, // AWPROT[2:0], input
wire
[
3
:
0
]
axi_awlen
;
// AWLEN[3:0], input
wire
[
1
:
0
]
axi_awsize
;
// AWSIZE[1:0], input
wire
[
1
:
0
]
axi_awburst
;
// AWBURST[1:0], input
// input [ 3:0] awqos, // AWQOS[3:0], input
// AXI PS Master GP0: Write Data
wire
[
31
:
0
]
axi_wdata
;
// WDATA[31:0], input
wire
axi_wvalid
;
// WVALID, input
wire
axi_wready
;
// WREADY, output
wire
[
11
:
0
]
axi_wid
;
// WID[11:0], input
wire
axi_wlast
;
// WLAST, input
wire
[
3
:
0
]
axi_wstb
;
// WSTRB[3:0], input
// AXI PS Master GP0: Write Responce
wire
axi_bvalid
;
// BVALID, output
wire
axi_bready
;
// BREADY, input
wire
[
11
:
0
]
axi_bid
;
// BID[11:0], output
wire
[
1
:
0
]
axi_bresp
;
// BRESP[1:0], output
// BRAM (and other write modules) interface from AXI write
wire
[
AXI_WR_ADDR_BITS
-
1
:
0
]
axiwr_pre_awaddr
;
// same as awaddr_out, early address to decode and return dev_ready
wire
axiwr_start_burst
;
// start of write burst, valid pre_awaddr, save externally to control ext. dev_ready multiplexer
wire
axiwr_dev_ready
;
// extrernal combinatorial ready signal, multiplexed from different sources according to pre_awaddr@start_burst
wire
axiwr_bram_wclk
;
wire
[
AXI_WR_ADDR_BITS
-
1
:
0
]
axiwr_bram_waddr
;
wire
axiwr_bram_wen
;
// external memory write enable, (internally combined with registered dev_ready
// SuppressWarnings VEditor unused (yet?)
wire
[
3
:
0
]
axiwr_bram_wstb
;
wire
[
31
:
0
]
axiwr_bram_wdata
;
// AXI Read Address
wire
[
31
:
0
]
axi_araddr
;
// ARADDR[31:0], input
wire
axi_arvalid
;
// ARVALID, input
wire
axi_arready
;
// ARREADY, output
wire
[
11
:
0
]
axi_arid
;
// ARID[11:0], input
// input [ 1:0] arlock, // ARLOCK[1:0], input
// input [ 3:0] archache,// ARCACHE[3:0], input
// input [ 2:0] arprot, // ARPROT[2:0], input
wire
[
3
:
0
]
axi_arlen
;
// ARLEN[3:0], input
wire
[
1
:
0
]
axi_arsize
;
// ARSIZE[1:0], input
wire
[
1
:
0
]
axi_arburst
;
// ARBURST[1:0], input
// input [ 3:0] adqos, // ARQOS[3:0], input
// AXI Read Data
wire
[
31
:
0
]
axi_rdata
;
// RDATA[31:0], output
wire
axi_rvalid
;
// RVALID, output
wire
axi_rready
;
// RREADY, input
wire
[
11
:
0
]
axi_rid
;
// RID[11:0], output
wire
axi_rlast
;
// RLAST, output
wire
[
1
:
0
]
axi_rresp
;
// External memory synchronization
wire
[
AXI_RD_ADDR_BITS
-
1
:
0
]
axird_pre_araddr
;
// same as awaddr_out, early address to decode and return dev_ready
wire
axird_start_burst
;
// start of read burst, valid pre_araddr, save externally to control ext. dev_ready multiplexer
wire
axird_dev_ready
;
// extrernal combinatorial ready signal, multiplexed from different sources according to pre_araddr@start_burst
// External memory interface
// SuppressWarnings VEditor unused (yet?) - use mclk
wire
axird_bram_rclk
;
// .rclk(aclk), // clock for read port
wire
[
AXI_RD_ADDR_BITS
-
1
:
0
]
axird_bram_raddr
;
// .raddr(read_in_progress?read_address[9:0]:10'h3ff), // read address
wire
axird_bram_ren
;
// .ren(bram_reg_re_w) , // read port enable
wire
axird_bram_regen
;
// .regen(bram_reg_re_w), // output register enable
wire
[
31
:
0
]
axird_bram_rdata
;
// .data_out(rdata[31:0]), // data out
wire
[
31
:
0
]
port0_rdata
;
//
wire
[
31
:
0
]
status_rdata
;
//
wire
mclk
;
wire
en_cmd0_wr
;
wire
[
10
:
0
]
axi_run_addr
;
wire
[
3
:
0
]
axi_run_chn
;
wire
axi_run_seq
;
wire
[
10
:
0
]
run_addr
;
// multiplexed - from refresh or axi
wire
[
3
:
0
]
run_chn
;
// multiplexed - from refresh or axi
wire
run_seq
;
wire
run_seq_rq_in
;
// higher priority request to run sequence
wire
run_seq_rq_gen
;
// SuppressThisWarning VEditor : unused this wants to run sequencer
// wire run_seq_busy; // sequencer is busy or access granted to other master
// wire run_done; // output
wire
run_busy
;
// TODO: add to ddrc_sequencer
wire
[
7
:
0
]
dly_data
;
// input[7:0]
wire
[
6
:
0
]
dly_addr
;
// input[6:0]
wire
ld_delay
;
// input
wire
set
;
// input
wire
locked
;
// output
wire
locked_mmcm
;
wire
locked_pll
;
wire
dly_ready
;
wire
dci_ready
;
wire
phy_locked_mmcm
;
wire
phy_locked_pll
;
wire
phy_dly_ready
;
wire
phy_dci_ready
;
wire
[
7
:
0
]
tmp_debug
;
wire
ps_rdy
;
// output
wire
[
7
:
0
]
ps_out
;
// output[7:0]
wire
en_port0_rd
;
wire
en_port0_regen
;
wire
en_port1_wr
;
wire
[
1
:
0
]
port0_page
;
// input[1:0]
wire
[
1
:
0
]
port0_int_page
;
// input[1:0]
wire
[
1
:
0
]
port1_page
;
// input[1:0]
wire
[
1
:
0
]
port1_int_page
;
// input[1:0]
// additional control signals
wire
cmda_en
;
// enable DDR3 memory control and addreee outputs
wire
ddr_rst
;
// generate DDR3 memory reset (active hight)
wire
dci_rst
;
// active high - reset DCI circuitry
wire
dly_rst
;
// active high - reset delay calibration circuitry
wire
ddr_cke
;
// control of the DDR3 memory CKE signal
wire
inv_clk_div
;
// input
wire
[
7
:
0
]
dqs_pattern
;
// input[7:0] 8'h55
wire
[
7
:
0
]
dqm_pattern
;
// input[7:0] 8'h00
reg
select_port0
;
reg
select_status
;
wire
axiwr_dev_busy
;
wire
axird_dev_busy
;
wire
[
3
:
0
]
dq_tri_on_pattern
;
wire
[
3
:
0
]
dq_tri_off_pattern
;
wire
[
3
:
0
]
dqs_tri_on_pattern
;
wire
[
3
:
0
]
dqs_tri_off_pattern
;
wire
[
3
:
0
]
wbuf_delay
;
wire
port0_rd_match
;
reg
port0_rd_match_r
;
// rd address matched in previous cycle
wire
[
7
:
0
]
refresh_period
;
wire
[
10
:
0
]
refresh_address
;
wire
refresh_en
;
wire
refresh_set
;
assign
port0_rd_match
=
(((
axird_bram_raddr
^
PORT0_RD_ADDR
)
&
PORT0_RD_ADDR_MASK
)
==
0
)
;
assign
en_cmd0_wr
=
axiwr_bram_wen
&&
(((
axiwr_bram_waddr
^
CMD0_ADDR
)
&
CMD0_ADDR_MASK
)
==
0
)
;
assign
en_port0_rd
=
axird_bram_ren
&&
port0_rd_match
;
assign
en_port0_regen
=
axird_bram_regen
&&
port0_rd_match_r
;
assign
en_port1_wr
=
axiwr_bram_wen
&&
(((
axiwr_bram_waddr
^
PORT1_WR_ADDR
)
&
PORT1_WR_ADDR_MASK
)
==
0
)
;
assign
axiwr_dev_ready
=
~
axiwr_dev_busy
;
//may combine (AND) multiple sources if needed
assign
axird_bram_rdata
=
select_port0
?
port0_rdata
[
31
:
0
]
:
(
select_status
?
status_rdata
[
31
:
0
]
:
32'bx
)
;
assign
axird_dev_ready
=
~
axird_dev_busy
;
//may combine (AND) multiple sources if needed
assign
locked
=
locked_mmcm
&&
locked_pll
;