Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
ddr3-sp6-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
hdl-core-lib
ddr3-sp6-core
Commits
3b7baa89
Commit
3b7baa89
authored
Jun 23, 2015
by
Timon Heim
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Deadlock fix, to be tested
parent
8de0e83e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
253 additions
and
346 deletions
+253
-346
ddr3_ctrl_wb.vhd
hdl/rtl/ddr3_ctrl_wb.vhd
+253
-346
No files found.
hdl/rtl/ddr3_ctrl_wb.vhd
View file @
3b7baa89
--==============================================================================
--! @file ddr3_ctrl_wb.vhd
--==============================================================================
--! Standard library
library
IEEE
;
--! Standard packages
use
IEEE
.
STD_LOGIC_1164
.
all
;
use
IEEE
.
NUMERIC_STD
.
all
;
--! Specific packages
library
work
;
use
work
.
ddr3_ctrl_pkg
.
all
;
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- DDR3 Controller Wishbone Interface
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--! @brief
--! DDR3 Controller Wishbone Interface
--------------------------------------------------------------------------------
--! @details
--! Wishbone interface for DDR3 controller.
--------------------------------------------------------------------------------
--! @version
--! 0.1 | mc | 12.07.2011 | File creation and Doxygen comments
--!
--! @author
--! mc : Matthieu Cattin, CERN (BE-CO-HT)
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
--------------------------------------------------------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version. This source 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 Lesser General Public License for more details. You should have
-- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--------------------------------------------------------------------------------
library
work
;
use
work
.
ddr3_ctrl_pkg
.
all
;
--==============================================================================
--! Entity declaration for ddr3_ctrl_wb
--==============================================================================
entity
ddr3_ctrl_wb
is
generic
(
--! DDR3 byte address width
g_BYTE_ADDR_WIDTH
:
integer
:
=
30
;
--! Data mask size (8-bit granularity)
g_MASK_SIZE
:
integer
:
=
4
;
--! Data width
g_DATA_PORT_SIZE
:
integer
:
=
32
generic
(
g_BYTE_ADDR_WIDTH
:
integer
:
=
30
;
g_MASK_SIZE
:
integer
:
=
4
;
g_DATA_PORT_SIZE
:
integer
:
=
32
);
port
(
----------------------------------------------------------------------------
-- Reset input (active low)
----------------------------------------------------------------------------
rst_n_i
:
in
std_logic
;
----------------------------------------------------------------------------
-- Status
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-- DDR controller port
----------------------------------------------------------------------------
ddr_cmd_clk_o
:
out
std_logic
;
ddr_cmd_en_o
:
out
std_logic
;
ddr_cmd_instr_o
:
out
std_logic_vector
(
2
downto
0
);
ddr_cmd_bl_o
:
out
std_logic_vector
(
5
downto
0
);
ddr_cmd_byte_addr_o
:
out
std_logic_vector
(
g_BYTE_ADDR_WIDTH
-
1
downto
0
);
ddr_cmd_empty_i
:
in
std_logic
;
ddr_cmd_full_i
:
in
std_logic
;
ddr_wr_clk_o
:
out
std_logic
;
ddr_wr_en_o
:
out
std_logic
;
ddr_wr_mask_o
:
out
std_logic_vector
(
g_MASK_SIZE
-
1
downto
0
);
ddr_wr_data_o
:
out
std_logic_vector
(
g_DATA_PORT_SIZE
-
1
downto
0
);
ddr_wr_full_i
:
in
std_logic
;
ddr_wr_empty_i
:
in
std_logic
;
ddr_wr_count_i
:
in
std_logic_vector
(
6
downto
0
);
ddr_wr_underrun_i
:
in
std_logic
;
ddr_wr_error_i
:
in
std_logic
;
ddr_rd_clk_o
:
out
std_logic
;
ddr_rd_en_o
:
out
std_logic
;
ddr_rd_data_i
:
in
std_logic_vector
(
g_DATA_PORT_SIZE
-
1
downto
0
);
ddr_rd_full_i
:
in
std_logic
;
ddr_rd_empty_i
:
in
std_logic
;
ddr_rd_count_i
:
in
std_logic_vector
(
6
downto
0
);
ddr_rd_overflow_i
:
in
std_logic
;
ddr_rd_error_i
:
in
std_logic
;
----------------------------------------------------------------------------
-- Wishbone bus port
----------------------------------------------------------------------------
wb_clk_i
:
in
std_logic
;
wb_sel_i
:
in
std_logic_vector
(
g_MASK_SIZE
-
1
downto
0
);
wb_cyc_i
:
in
std_logic
;
wb_stb_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_addr_i
:
in
std_logic_vector
(
31
downto
0
);
wb_data_i
:
in
std_logic_vector
(
g_DATA_PORT_SIZE
-
1
downto
0
);
wb_data_o
:
out
std_logic_vector
(
g_DATA_PORT_SIZE
-
1
downto
0
);
wb_ack_o
:
out
std_logic
;
wb_stall_o
:
out
std_logic
port
(
----------------------------------------------------------------------------
-- Reset input (active low)
----------------------------------------------------------------------------
rst_n_i
:
in
std_logic
;
----------------------------------------------------------------------------
-- Status
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-- DDR controller port
----------------------------------------------------------------------------
ddr_cmd_clk_o
:
out
std_logic
;
ddr_cmd_en_o
:
out
std_logic
;
ddr_cmd_instr_o
:
out
std_logic_vector
(
2
downto
0
);
ddr_cmd_bl_o
:
out
std_logic_vector
(
5
downto
0
);
ddr_cmd_byte_addr_o
:
out
std_logic_vector
(
g_BYTE_ADDR_WIDTH
-
1
downto
0
);
ddr_cmd_empty_i
:
in
std_logic
;
ddr_cmd_full_i
:
in
std_logic
;
ddr_wr_clk_o
:
out
std_logic
;
ddr_wr_en_o
:
out
std_logic
;
ddr_wr_mask_o
:
out
std_logic_vector
(
g_MASK_SIZE
-
1
downto
0
);
ddr_wr_data_o
:
out
std_logic_vector
(
g_DATA_PORT_SIZE
-
1
downto
0
);
ddr_wr_full_i
:
in
std_logic
;
ddr_wr_empty_i
:
in
std_logic
;
ddr_wr_count_i
:
in
std_logic_vector
(
6
downto
0
);
ddr_wr_underrun_i
:
in
std_logic
;
ddr_wr_error_i
:
in
std_logic
;
ddr_rd_clk_o
:
out
std_logic
;
ddr_rd_en_o
:
out
std_logic
;
ddr_rd_data_i
:
in
std_logic_vector
(
g_DATA_PORT_SIZE
-
1
downto
0
);
ddr_rd_full_i
:
in
std_logic
;
ddr_rd_empty_i
:
in
std_logic
;
ddr_rd_count_i
:
in
std_logic_vector
(
6
downto
0
);
ddr_rd_overflow_i
:
in
std_logic
;
ddr_rd_error_i
:
in
std_logic
;
----------------------------------------------------------------------------
-- Wishbone bus port
----------------------------------------------------------------------------
wb_clk_i
:
in
std_logic
;
wb_sel_i
:
in
std_logic_vector
(
g_MASK_SIZE
-
1
downto
0
);
wb_cyc_i
:
in
std_logic
;
wb_stb_i
:
in
std_logic
;
wb_we_i
:
in
std_logic
;
wb_addr_i
:
in
std_logic_vector
(
31
downto
0
);
wb_data_i
:
in
std_logic_vector
(
g_DATA_PORT_SIZE
-
1
downto
0
);
wb_data_o
:
out
std_logic_vector
(
g_DATA_PORT_SIZE
-
1
downto
0
);
wb_ack_o
:
out
std_logic
;
wb_stall_o
:
out
std_logic
);
end
entity
ddr3_ctrl_wb
;
--==============================================================================
--! Architecure declaration for ddr3_ctrl_wb
--==============================================================================
architecture
rtl
of
ddr3_ctrl_wb
is
------------------------------------------------------------------------------
-- Constants declaration
------------------------------------------------------------------------------
constant
c_DDR_BURST_LENGTH
:
integer
:
=
32
;
-- must not exceed 63
constant
c_FIFO_ALMOST_FULL
:
std_logic_vector
(
6
downto
0
)
:
=
std_logic_vector
(
to_unsigned
(
57
,
7
));
constant
c_ADDR_SHIFT
:
integer
:
=
log2_ceil
(
g_DATA_PORT_SIZE
/
8
);
------------------------------------------------------------------------------
-- Types declaration
------------------------------------------------------------------------------
--type t_wb_fsm_states is (WB_IDLE, WB_WRITE, WB_READ_REQ, WB_READ_WAIT,
-- WB_READ_ACK, WB_READ_REQ_ACK);
------------------------------------------------------------------------------
-- Signals declaration
------------------------------------------------------------------------------
signal
rst_n
:
std_logic
;
signal
wb_cyc_d
:
std_logic
;
signal
wb_cyc_f_edge
:
std_logic
;
signal
wb_cyc_r_edge
:
std_logic
;
signal
wb_stb_valid
:
std_logic
;
signal
wb_stb_d
:
std_logic
;
signal
wb_stb_f_edge
:
std_logic
;
signal
wb_we_d
:
std_logic
;
signal
wb_we_f_edge
:
std_logic
;
signal
wb_addr_d
:
std_logic_vector
(
31
downto
0
);
signal
ddr_burst_cnt
:
unsigned
(
5
downto
0
);
signal
ddr_cmd_en
:
std_logic
;
signal
ddr_cmd_en_d
:
std_logic
;
signal
ddr_cmd_en_r_edge
:
std_logic
;
signal
ddr_cmd_instr
:
std_logic_vector
(
2
downto
0
);
signal
ddr_cmd_bl
:
std_logic_vector
(
5
downto
0
);
signal
ddr_cmd_byte_addr
:
std_logic_vector
(
g_BYTE_ADDR_WIDTH
-
1
downto
0
);
signal
addr_shift
:
std_logic_vector
(
c_ADDR_SHIFT
-1
downto
0
);
signal
ddr_wr_en
:
std_logic
;
signal
ddr_wr_mask
:
std_logic_vector
(
g_MASK_SIZE
-
1
downto
0
);
signal
ddr_wr_data
:
std_logic_vector
(
g_DATA_PORT_SIZE
-
1
downto
0
);
signal
ddr_rd_en
:
std_logic
;
--==============================================================================
--! Architecure begin
--==============================================================================
architecture
behavioral
of
ddr3_ctrl_wb
is
--------------------------------------
-- Constants
--------------------------------------
constant
c_DDR_BURST_LENGTH
:
unsigned
(
5
downto
0
)
:
=
TO_UNSIGNED
(
16
,
6
);
constant
c_READ_STALL_ASSERT
:
unsigned
(
6
downto
0
)
:
=
TO_UNSIGNED
(
54
,
7
);
constant
c_READ_STALL_NEGATE
:
unsigned
(
6
downto
0
)
:
=
TO_UNSIGNED
(
42
,
7
);
constant
c_WRITE_STALL_ASSERT
:
unsigned
(
6
downto
0
)
:
=
TO_UNSIGNED
(
52
,
7
);
constant
c_WRITE_STALL_NEGATE
:
unsigned
(
6
downto
0
)
:
=
TO_UNSIGNED
(
42
,
7
);
constant
c_ADDR_SHIFT
:
integer
:
=
log2_ceil
(
g_DATA_PORT_SIZE
/
8
);
constant
c_STALL_TIME
:
unsigned
(
3
downto
0
)
:
=
TO_UNSIGNED
(
15
,
4
);
--------------------------------------
-- Signals
--------------------------------------
signal
ddr_wr_ack
:
std_logic
;
signal
ddr_rd_ack
:
std_logic
;
signal
ddr_rd_en
:
std_logic
;
signal
ddr_cmd_en
:
std_logic
;
signal
ddr_cmd_full
:
std_logic
;
signal
wb_stall
:
std_logic
;
signal
wb_stall_d
:
std_logic
;
signal
wb_stall_dd
:
std_logic
;
signal
wb_we_d
:
std_logic
;
signal
wb_addr_d
:
std_logic_vector
(
g_DATA_PORT_SIZE
-
1
downto
0
);
signal
wb_stall_restart
:
std_logic
;
signal
addr_shift
:
std_logic_vector
(
c_ADDR_SHIFT
-1
downto
0
);
--------------------------------------
-- Counter
--------------------------------------
signal
wb_stall_cnt
:
unsigned
(
3
downto
0
);
signal
ddr_burst_cnt
:
unsigned
(
5
downto
0
);
signal
ddr_burst_cnt_d
:
unsigned
(
5
downto
0
);
signal
read_cnt
:
unsigned
(
7
downto
0
);
signal
write_cnt
:
unsigned
(
7
downto
0
);
begin
------------------------------------------------------------------------------
-- Wishbone interface
------------------------------------------------------------------------------
-- Reset sync to wishbone clock
p_rst_sync
:
process
(
rst_n_i
,
wb_clk_i
)
begin
if
(
rst_n_i
=
'0'
)
then
rst_n
<=
'0'
;
elsif
rising_edge
(
wb_clk_i
)
then
rst_n
<=
'1'
;
end
if
;
end
process
p_rst_sync
;
-- Clocking
ddr_cmd_clk_o
<=
wb_clk_i
;
ddr_wr_clk_o
<=
wb_clk_i
;
ddr_rd_clk_o
<=
wb_clk_i
;
-- stb is valid only if cyc is '1'
wb_stb_valid
<=
wb_stb_i
and
wb_cyc_i
;
-- Cycle, we and strobe rising and falling edge detection
p_wb_cyc_f_edge
:
process
(
wb_clk_i
)
begin
if
rising_edge
(
wb_clk_i
)
then
if
(
rst_n
=
'0'
)
then
wb_cyc_d
<=
'0'
;
wb_stb_d
<=
'0'
;
wb_we_d
<=
'0'
;
else
wb_cyc_d
<=
wb_cyc_i
;
wb_stb_d
<=
wb_stb_valid
;
wb_we_d
<=
wb_we_i
;
end
if
;
end
if
;
end
process
p_wb_cyc_f_edge
;
wb_cyc_f_edge
<=
not
(
wb_cyc_i
)
and
wb_cyc_d
;
wb_cyc_r_edge
<=
wb_cyc_i
and
not
(
wb_cyc_d
);
wb_stb_f_edge
<=
not
(
wb_stb_valid
)
and
wb_stb_d
;
wb_we_f_edge
<=
not
(
wb_we_i
)
and
wb_we_d
;
-- Data inputs
p_ddr_inputs
:
process
(
wb_clk_i
)
begin
if
rising_edge
(
wb_clk_i
)
then
if
(
rst_n
=
'0'
)
then
ddr_wr_data
<=
(
others
=>
'0'
);
ddr_wr_en
<=
'0'
;
else
if
(
wb_stb_valid
=
'1'
)
and
(
wb_cyc_i
=
'1'
)
and
(
wb_we_i
=
'1'
)
then
ddr_wr_en
<=
'1'
;
else
ddr_wr_en
<=
'0'
;
-- Tie offs
ddr_wr_clk_o
<=
wb_clk_i
;
ddr_rd_clk_o
<=
wb_clk_i
;
ddr_cmd_clk_o
<=
wb_clk_i
;
wb_ack_o
<=
ddr_wr_ack
or
ddr_rd_ack
;
--------------------------------------
-- Wishbone write
--------------------------------------
p_wb_write
:
process
(
wb_clk_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
ddr_wr_en_o
<=
'0'
;
ddr_wr_ack
<=
'0'
;
ddr_wr_data_o
<=
(
others
=>
'0'
);
ddr_wr_mask_o
<=
(
others
=>
'0'
);
elsif
rising_edge
(
wb_clk_i
)
then
if
(
wb_cyc_i
=
'1'
and
wb_stb_i
=
'1'
and
wb_we_i
=
'1'
)
then
ddr_wr_data_o
<=
wb_data_i
;
ddr_wr_mask_o
<=
not
(
wb_sel_i
);
ddr_wr_en_o
<=
'1'
;
ddr_wr_ack
<=
'1'
;
else
ddr_wr_data_o
<=
(
others
=>
'0'
);
ddr_wr_mask_o
<=
(
others
=>
'0'
);
ddr_wr_en_o
<=
'0'
;
ddr_wr_ack
<=
'0'
;
end
if
;
end
if
;
ddr_wr_data
<=
wb_data_i
;
ddr_wr_mask
<=
not
(
wb_sel_i
);
end
if
;
end
if
;
end
process
p_ddr_inputs
;
-- Command parameters (burst length and address) registration
p_ddr_cmd
:
process
(
wb_clk_i
)
begin
if
rising_edge
(
wb_clk_i
)
then
if
(
rst_n
=
'0'
)
then
ddr_cmd_byte_addr
<=
(
others
=>
'0'
);
ddr_cmd_instr
<=
"000"
;
ddr_cmd_bl
<=
(
others
=>
'0'
);
wb_addr_d
<=
(
others
=>
'0'
);
else
wb_addr_d
<=
wb_addr_i
;
if
((
ddr_burst_cnt
=
0
and
wb_cyc_r_edge
=
'1'
and
wb_stb_valid
=
'1'
)
or
(
ddr_burst_cnt
=
to_unsigned
(
1
,
ddr_burst_cnt
'length
)))
then
ddr_cmd_byte_addr
<=
wb_addr_d
(
g_BYTE_ADDR_WIDTH
-
c_ADDR_SHIFT
-1
downto
0
)
&
addr_shift
;
ddr_cmd_instr
<=
"00"
&
not
(
wb_we_d
);
end
process
p_wb_write
;
--------------------------------------
-- Wishbone read
--------------------------------------
ddr_rd_en_o
<=
ddr_rd_en
;
p_wb_read
:
process
(
wb_clk_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
ddr_rd_en
<=
'0'
;
ddr_rd_ack
<=
'0'
;
wb_data_o
<=
(
others
=>
'0'
);
elsif
rising_edge
(
wb_clk_i
)
then
if
(
wb_cyc_i
=
'1'
and
ddr_rd_empty_i
=
'0'
)
then
ddr_rd_en
<=
'1'
;
else
ddr_rd_en
<=
'0'
;
end
if
;
if
(
ddr_rd_en
=
'1'
and
ddr_rd_empty_i
=
'0'
)
then
ddr_rd_ack
<=
'1'
;
wb_data_o
<=
ddr_rd_data_i
;
else
ddr_rd_ack
<=
'0'
;
wb_data_o
<=
(
others
=>
'1'
);
end
if
;
end
if
;
ddr_cmd_bl
<=
std_logic_vector
(
ddr_burst_cnt
-
1
);
end
if
;
end
if
;
end
process
p_ddr_cmd
;
addr_shift
<=
(
others
=>
'0'
);
-- Command enable signal generation
p_ddr_cmd_en
:
process
(
wb_clk_i
)
begin
if
rising_edge
(
wb_clk_i
)
then
if
(
rst_n
=
'0'
)
then
ddr_cmd_en
<=
'0'
;
ddr_cmd_en_d
<=
'0'
;
else
ddr_cmd_en_d
<=
ddr_cmd_en
;
if
(((
ddr_burst_cnt
=
c_DDR_BURST_LENGTH
)
or
(
wb_cyc_f_edge
=
'1'
and
wb_we_d
=
'1'
)
or
(
wb_stb_f_edge
=
'1'
and
wb_we_d
=
'0'
))
and
ddr_cmd_full_i
=
'0'
)
then
ddr_cmd_en
<=
'1'
;
-- might have problem if burst_cnt = BURST_LENGTH for more than 2 clk cycles
else
ddr_cmd_en
<=
'0'
;
end
process
p_wb_read
;
--------------------------------------
-- DDR Control
--------------------------------------
addr_shift
<=
(
others
=>
'0'
);
ddr_cmd_en_o
<=
ddr_cmd_en
;
p_ddr_ctrl
:
process
(
wb_clk_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
ddr_burst_cnt
<=
(
others
=>
'0'
);
ddr_cmd_en
<=
'0'
;
ddr_cmd_byte_addr_o
<=
(
others
=>
'0'
);
ddr_cmd_instr_o
<=
(
others
=>
'0'
);
ddr_cmd_bl_o
<=
(
others
=>
'0'
);
wb_addr_d
<=
(
others
=>
'0'
);
wb_we_d
<=
'0'
;
wb_stall_restart
<=
'1'
;
read_cnt
<=
(
others
=>
'0'
);
write_cnt
<=
(
others
=>
'0'
);
elsif
rising_edge
(
wb_clk_i
)
then
if
(
wb_cyc_i
=
'1'
and
wb_stb_i
=
'1'
)
then
if
(
ddr_burst_cnt
=
c_DDR_BURST_LENGTH
)
then
ddr_burst_cnt
<=
TO_UNSIGNED
(
1
,
6
);
ddr_cmd_en
<=
'1'
;
else
ddr_burst_cnt
<=
ddr_burst_cnt
+
1
;
ddr_cmd_en
<=
'0'
;
end
if
;
elsif
(
wb_cyc_i
=
'1'
and
wb_stb_i
=
'0'
and
ddr_burst_cnt
>
0
and
wb_stall_dd
=
'0'
)
then
ddr_burst_cnt
<=
TO_UNSIGNED
(
0
,
6
);
ddr_cmd_en
<=
'1'
;
else
ddr_cmd_en
<=
'0'
;
end
if
;
ddr_cmd_bl_o
<=
STD_LOGIC_VECTOR
(
ddr_burst_cnt
-
1
);
ddr_burst_cnt_d
<=
ddr_burst_cnt
;
if
(
wb_stb_i
=
'1'
)
then
wb_addr_d
<=
wb_addr_i
;
wb_we_d
<=
wb_we_i
;
end
if
;
if
(
ddr_burst_cnt
=
0
)
then
ddr_cmd_byte_addr_o
<=
wb_addr_i
(
g_BYTE_ADDR_WIDTH
-
c_ADDR_SHIFT
-1
downto
0
)
&
addr_shift
;
ddr_cmd_instr_o
<=
"00"
&
not
(
wb_we_i
);
elsif
(
ddr_cmd_en
=
'1'
)
then
ddr_cmd_byte_addr_o
<=
wb_addr_d
(
g_BYTE_ADDR_WIDTH
-
c_ADDR_SHIFT
-1
downto
0
)
&
addr_shift
;
ddr_cmd_instr_o
<=
"00"
&
not
(
wb_we_d
);
end
if
;
if
(
wb_we_i
=
'0'
)
then
if
(
ddr_cmd_en
=
'1'
and
ddr_rd_ack
=
'0'
)
then
read_cnt
<=
read_cnt
+
ddr_burst_cnt_d
;
elsif
(
ddr_cmd_en
=
'1'
and
ddr_rd_ack
=
'1'
)
then
read_cnt
<=
read_cnt
+
ddr_burst_cnt_d
-
1
;
elsif
(
ddr_cmd_en
=
'0'
and
ddr_rd_ack
=
'1'
and
read_cnt
>
0
)
then
read_cnt
<=
read_cnt
-
1
;
end
if
;
else
if
(
ddr_cmd_en
=
'1'
and
ddr_wr_ack
=
'0'
and
write_cnt
>=
ddr_burst_cnt_d
)
then
write_cnt
<=
write_cnt
-
ddr_burst_cnt_d
;
elsif
(
ddr_cmd_en
=
'1'
and
ddr_wr_ack
=
'1'
and
write_cnt
>=
ddr_burst_cnt_d
)
then
write_cnt
<=
(
write_cnt
-
ddr_burst_cnt_d
)
+
1
;
elsif
(
ddr_cmd_en
=
'0'
and
ddr_wr_ack
=
'1'
)
then
write_cnt
<=
write_cnt
+
1
;
end
if
;
end
if
;
if
(
wb_stall
=
'1'
)
then
wb_stall_restart
<=
'0'
;
elsif
(
wb_stb_i
=
'1'
)
then
wb_stall_restart
<=
'1'
;
end
if
;
end
if
;
end
if
;
end
if
;
end
process
p_ddr_cmd_en
;
-- Command enable rising edge detection
ddr_cmd_en_r_edge
<=
ddr_cmd_en
and
not
(
ddr_cmd_en_d
);
-- Burst counter
p_ddr_burst_cnt
:
process
(
wb_clk_i
)
begin
if
rising_edge
(
wb_clk_i
)
then
if
(
rst_n
=
'0'
)
then
ddr_burst_cnt
<=
(
others
=>
'0'
);
else
if
(
wb_cyc_f_edge
=
'1'
)
then
ddr_burst_cnt
<=
to_unsigned
(
0
,
ddr_burst_cnt
'length
);
elsif
(
wb_stb_valid
=
'1'
and
wb_cyc_i
=
'1'
)
then
if
(
ddr_burst_cnt
=
c_DDR_BURST_LENGTH
)
then
ddr_burst_cnt
<=
to_unsigned
(
1
,
ddr_burst_cnt
'length
);
else
ddr_burst_cnt
<=
ddr_burst_cnt
+
1
;
end
if
;
elsif
(
ddr_burst_cnt
=
c_DDR_BURST_LENGTH
)
then
ddr_burst_cnt
<=
to_unsigned
(
0
,
ddr_burst_cnt
'length
);
end
if
;
end
if
;
end
if
;
end
process
p_ddr_burst_cnt
;
-- Read enable signal generation
ddr_rd_en
<=
not
(
ddr_rd_empty_i
);
-- Data output and ack
p_ddr_outputs
:
process
(
wb_clk_i
)
begin
if
rising_edge
(
wb_clk_i
)
then
if
(
rst_n
=
'0'
)
then
wb_ack_o
<=
'0'
;
wb_data_o
<=
(
others
=>
'0'
);
else
-- Generates ack signal
if
(
ddr_rd_en
=
'1'
)
or
(
ddr_wr_en
=
'1'
)
then
wb_ack_o
<=
'1'
;
else
wb_ack_o
<=
'0'
;
end
if
;
-- Registered data output
wb_data_o
<=
ddr_rd_data_i
;
end
if
;
end
if
;
end
process
p_ddr_outputs
;
-- Stall signal output
p_ddr_stall
:
process
(
wb_clk_i
)
begin
if
rising_edge
(
wb_clk_i
)
then
if
(
rst_n
=
'0'
)
then
wb_stall_o
<=
'0'
;
else
if
((
ddr_wr_count_i
>
c_FIFO_ALMOST_FULL
)
or
(
ddr_wr_full_i
=
'1'
)
or
(
ddr_rd_count_i
>
c_FIFO_ALMOST_FULL
)
or
(
ddr_rd_full_i
=
'1'
))
then
wb_stall_o
<=
'1'
;
else
wb_stall_o
<=
'0'
;
end
process
p_ddr_ctrl
;
--------------------------------------
-- Stall proc
--------------------------------------
wb_stall_o
<=
wb_stall
;
p_wb_stall
:
process
(
wb_clk_i
,
rst_n_i
)
begin
if
(
rst_n_i
=
'0'
)
then
wb_stall
<=
'0'
;
wb_stall_d
<=
'0'
;
wb_stall_dd
<=
'0'
;
ddr_cmd_full
<=
'0'
;
wb_stall_cnt
<=
(
others
=>
'0'
);
elsif
rising_edge
(
wb_clk_i
)
then
ddr_cmd_full
<=
ddr_cmd_full_i
;
if
(
ddr_cmd_full
=
'1'
or
read_cnt
>
c_READ_STALL_ASSERT
or
unsigned
(
ddr_wr_count_i
)
>
c_WRITE_STALL_ASSERT
)
then
wb_stall
<=
'1'
;
elsif
(
ddr_cmd_full
=
'0'
and
read_cnt
<
c_READ_STALL_NEGATE
and
unsigned
(
ddr_wr_count_i
)
<
c_WRITE_STALL_NEGATE
)
then
wb_stall
<=
'0'
;
end
if
;
wb_stall_d
<=
wb_stall
;
wb_stall_dd
<=
wb_stall_d
;
end
if
;
end
if
;
end
if
;
end
process
p_ddr_stall
;
--wb_stall_o <= ddr_cmd_full_i or ddr_wr_full_i or ddr_rd_full_i;
-- Assign outputs
ddr_cmd_en_o
<=
ddr_cmd_en
;
ddr_cmd_instr_o
<=
ddr_cmd_instr
;
ddr_cmd_bl_o
<=
ddr_cmd_bl
;
ddr_cmd_byte_addr_o
<=
ddr_cmd_byte_addr
;
ddr_wr_en_o
<=
ddr_wr_en
;
ddr_wr_mask_o
<=
ddr_wr_mask
;
ddr_wr_data_o
<=
ddr_wr_data
;
ddr_rd_en_o
<=
ddr_rd_en
;
end
process
p_wb_stall
;
end
architecture
behavioral
;
end
architecture
rtl
;
--==============================================================================
--! Architecure end
--==============================================================================
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