- adedd single data rate SDRAM

git-svn-id: http://moon:8086/svn/vhdl/trunk@1211 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2015-05-24 12:54:57 +00:00
parent fa8fadd8cc
commit bd65d611dd
9 changed files with 3136 additions and 0 deletions
@@ -0,0 +1,150 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program 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.
--
-- This program 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.fifo_ctrl_pkg.all;
use work.sdram_config.all;
use work.sdram_types.all;
entity ctrl_sdr_wb32 is
Generic
(
BURST_LEN : natural := 2;
F_SYSCLK : real := 100.0;
F_SDRCLK : real := 100.0;
FIFO_DEPTH : integer := 4
);
Port
(
RST_I : in STD_LOGIC;
CLK_I : in STD_LOGIC;
SDRAM_CLK_I : in STD_LOGIC;
SDRAM_CLK_FB_I : in STD_LOGIC;
CYC_I : in STD_LOGIC;
STB_I : in STD_LOGIC;
SEL_I : in unsigned(3 downto 0);
WE_I : in STD_LOGIC;
ACK_O : out STD_LOGIC;
MRDY_I : in STD_LOGIC;
SRDY_O : out STD_LOGIC;
ADDR_I : in unsigned(31 downto 0);
DAT_I : in unsigned(31 downto 0);
DAT_O : out unsigned(31 downto 0);
-- SDRAM signals
sd_clk : out STD_LOGIC;
sd_cke : out STD_LOGIC;
sd_cs_n : out STD_LOGIC;
sd_cas_n : out STD_LOGIC;
sd_ras_n : out STD_LOGIC;
sd_we_n : out STD_LOGIC;
sd_addr : out sdr_addr_t;
sd_ba : out sdr_ba_t;
sd_dqm : out unsigned(PART_DM_WIDTH-1 downto 0);
sd_data : inout unsigned(PART_DATA_WIDTH-1 downto 0)
);
end ctrl_sdr_wb32;
architecture struct of ctrl_sdr_wb32 is
signal sdram_clk0 : std_logic;
signal sdram_rst0 : std_logic;
signal phy_ctrl : phy_ctrl_t;
signal phy_in : phy_in_t;
signal phy_out : phy_out_t;
begin
-- DDR SDRAM Controller Core
sdram_ctrl_frontend_wb16 : entity work.sdram_ctrl_frontend_wb16
GENERIC MAP
(
BURST_LEN => BURST_LEN,
F_SYSCLK => F_SYSCLK,
F_SDRCLK => F_SDRCLK,
FIFO_DEPTH => FIFO_DEPTH
)
PORT MAP
(
RST_I => RST_I,
CLK_I => CLK_I,
SDRAM_RST0 => sdram_rst0,
SDRAM_CLK0 => sdram_clk0,
CYC_I => CYC_I,
STB_I => STB_I,
SEL_I => SEL_I,
WE_I => WE_I,
ACK_O => ACK_O,
SRDY_O => SRDY_O,
MRDY_I => MRDY_I,
ADDR_I => ADDR_I,
DAT_I => DAT_I,
DAT_O => DAT_O,
-- PHY signals
phy_in => phy_in,
phy_out => phy_out,
phy_ctrl => phy_ctrl
);
-- DDR phy
inst_sdram_phy : entity work.sdram_phy
Generic map
(
F_SDRCLK => F_SDRCLK
)
Port map
(
-- Clock interface
rst => RST_I,
clk => SDRAM_CLK_I,
clk_fb => SDRAM_CLK_FB_I,
clk0_out => sdram_clk0,
rst0_out => sdram_rst0,
-- PHY interface
phy_in => phy_in,
phy_out => phy_out,
phy_ctrl => phy_ctrl,
-- SDRAM part interface
part_clk => sd_clk,
part_addr => sd_addr,
part_ba => sd_ba,
part_dqm => sd_dqm,
part_data => sd_data,
part_cs_n => sd_cs_n,
part_we_n => sd_we_n,
part_cas_n => sd_cas_n,
part_ras_n => sd_ras_n,
part_cke => sd_cke
);
end architecture struct;
File diff suppressed because it is too large Load Diff
+139
View File
@@ -0,0 +1,139 @@
--*****************************************************************************
--
-- Micron Semiconductor Products, Inc.
--
-- Copyright 1997, Micron Semiconductor Products, Inc.
-- All rights reserved.
--
--*****************************************************************************
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
PACKAGE mti_pkg IS
FUNCTION To_StdLogic (s : BIT) RETURN STD_LOGIC;
FUNCTION TO_INTEGER (input : STD_LOGIC) RETURN INTEGER;
FUNCTION TO_INTEGER (input : BIT_VECTOR) RETURN INTEGER;
FUNCTION TO_INTEGER (input : STD_LOGIC_VECTOR) RETURN INTEGER;
PROCEDURE TO_BITVECTOR (VARIABLE input : IN INTEGER; VARIABLE output : OUT BIT_VECTOR);
END mti_pkg;
PACKAGE BODY mti_pkg IS
-- Convert BIT to STD_LOGIC
FUNCTION To_StdLogic (s : BIT) RETURN STD_LOGIC IS
BEGIN
CASE s IS
WHEN '0' => RETURN ('0');
WHEN '1' => RETURN ('1');
WHEN OTHERS => RETURN ('0');
END CASE;
END;
-- Convert STD_LOGIC to INTEGER
FUNCTION TO_INTEGER (input : STD_LOGIC) RETURN INTEGER IS
VARIABLE result : INTEGER := 0;
VARIABLE weight : INTEGER := 1;
BEGIN
IF input = '1' THEN
result := weight;
ELSE
result := 0; -- if unknowns, default to logic 0
END IF;
RETURN result;
END TO_INTEGER;
-- Convert BIT_VECTOR to INTEGER
FUNCTION TO_INTEGER (input : BIT_VECTOR) RETURN INTEGER IS
VARIABLE result : INTEGER := 0;
VARIABLE weight : INTEGER := 1;
BEGIN
FOR i IN input'LOW TO input'HIGH LOOP
IF input(i) = '1' THEN
result := result + weight;
ELSE
result := result + 0; -- if unknowns, default to logic 0
END IF;
weight := weight * 2;
END LOOP;
RETURN result;
END TO_INTEGER;
-- Convert STD_LOGIC_VECTOR to INTEGER
FUNCTION TO_INTEGER (input : STD_LOGIC_VECTOR) RETURN INTEGER IS
VARIABLE result : INTEGER := 0;
VARIABLE weight : INTEGER := 1;
BEGIN
FOR i IN input'LOW TO input'HIGH LOOP
IF input(i) = '1' THEN
result := result + weight;
ELSE
result := result + 0; -- if unknowns, default to logic 0
END IF;
weight := weight * 2;
END LOOP;
RETURN result;
END TO_INTEGER;
-- Conver INTEGER to BIT_VECTOR
PROCEDURE TO_BITVECTOR (VARIABLE input : IN INTEGER; VARIABLE output : OUT BIT_VECTOR) IS
VARIABLE work,offset,outputlen,j : INTEGER := 0;
BEGIN
--length of vector
IF output'LENGTH > 32 THEN
outputlen := 32;
offset := output'LENGTH - 32;
IF input >= 0 THEN
FOR i IN offset-1 DOWNTO 0 LOOP
output(output'HIGH - i) := '0';
END LOOP;
ELSE
FOR i IN offset-1 DOWNTO 0 LOOP
output(output'HIGH - i) := '1';
END LOOP;
END IF;
ELSE
outputlen := output'LENGTH;
END IF;
--positive value
IF (input >= 0) THEN
work := input;
j := outputlen - 1;
FOR i IN 1 to 32 LOOP
IF j >= 0 then
IF (work MOD 2) = 0 THEN
output(output'HIGH-j-offset) := '0';
ELSE
output(output'HIGH-j-offset) := '1';
END IF;
END IF;
work := work / 2;
j := j - 1;
END LOOP;
IF outputlen = 32 THEN
output(output'HIGH) := '0';
END IF;
--negative value
ELSE
work := (-input) - 1;
j := outputlen - 1;
FOR i IN 1 TO 32 LOOP
IF j>= 0 THEN
IF (work MOD 2) = 0 THEN
output(output'HIGH-j-offset) := '1';
ELSE
output(output'HIGH-j-offset) := '0';
END IF;
END IF;
work := work / 2;
j := j - 1;
END LOOP;
IF outputlen = 32 THEN
output(output'HIGH) := '1';
END IF;
END IF;
END TO_BITVECTOR;
END mti_pkg;
@@ -0,0 +1,266 @@
-------------------------------------------------------------------------
-- Project: SDRAM controller
-- This file: DDR physical layer (Virtex-4 specific)
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program 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.
--
-- This program 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
Library UNISIM;
use UNISIM.vcomponents.all;
entity sdram_phy is
Generic
(
F_SDRCLK : real := 100.0
);
Port
(
rst : in STD_LOGIC;
clk : in STD_LOGIC;
clk_fb : in STD_LOGIC;
clk0_out : out STD_LOGIC;
rst0_out : out STD_LOGIC;
phy_in : in phy_in_t;
phy_out : out phy_out_t;
phy_ctrl : in phy_ctrl_t;
part_clk : out STD_LOGIC;
part_dqm : out unsigned(PART_DM_WIDTH-1 downto 0);
part_data : inout unsigned(PART_DATA_WIDTH-1 downto 0);
part_ba : out unsigned(PART_BANK_WIDTH-1 downto 0);
part_addr : out unsigned(PART_ADDR_WIDTH-1 downto 0);
part_cs_n : out STD_LOGIC;
part_we_n : out STD_LOGIC;
part_cas_n : out STD_LOGIC;
part_ras_n : out STD_LOGIC;
part_cke : out STD_LOGIC
);
end sdram_phy;
architecture tech of sdram_phy is
signal drive : std_logic;
signal data_reg_r : unsigned(BUS_DATA_WIDTH-1 downto 0);
signal part_ctrl_reg : part_ctrl_t;
signal we_reg : std_logic;
signal read_en : std_logic;
signal clk0 : std_logic;
signal clk0_s : std_logic;
signal rst0 : std_logic;
signal clk_rd : std_logic;
signal clk_wr : std_logic;
signal locked : std_logic;
signal error : std_logic;
type u_tag_array_t is array (natural range 0 to 4) of user_tag_t;
signal u_tag_pipe : u_tag_array_t;
attribute KEEP : string;
attribute KEEP of clk0 : signal is "TRUE";
begin
clk0_out <= clk0_s;
clk0 <= clk0_s after 10 ps; -- fix delta delay
rst0_out <= rst0;
------------------------------------------------------------------------------------------------------------------------------------------------
inst_sdram_clk : entity work.sdram_clk
GENERIC MAP
(
clk_in_freq => F_SDRCLK,
clk0_out_phaseshift => 0,
clk1_out_phaseshift => 0
)
PORT MAP
(
-- Clocks and Reset
rst => rst, -- external async reset, low active
clk_in => clk, -- system clock (e.g. 100MHz), from board
clk_fb_in => clk_fb, -- feedback clock
clk0_0_out => clk0_s, -- System clock #0, dcm#0 output 0°
clk0_270_out => open, -- System clock #0, dcm#0 output 270°
clk1_0_out => open, -- System clock #1 (e.g. clock for DDR-SDRAM data capture), dcm#1 output 0°
clk1_270_out => open, -- System clock #1 (e.g. clock for DDR-SDRAM data capture), dcm#1 output 270°
locked_out => locked, -- DCM locked status
error_out => error
);
clk_wr <= clk0_s;
clk_rd <= clk0_s;
rst0_gen:
process(clk0)
begin
if rising_edge(clk0) then
rst0 <= not locked;
end if;
end process;
------------------------------------------------------------------------------------------------------------------------------------------------
utag_pipe:
process(clk0)
begin
if rising_edge(clk0) then
for i in u_tag_pipe'length-1 downto 1 loop
u_tag_pipe(i) <= u_tag_pipe(i-1);
end loop;
if phy_ctrl.utag_we = '1' then
u_tag_pipe(0) <= phy_ctrl.u_tag;
end if;
end if;
end process;
WE_REGISTER:
process(clk0)
begin
if rising_edge(clk0) then
if rst0 = '1' then
we_reg <= '0';
else
we_reg <= phy_ctrl.we;
end if;
end if;
end process;
DATA_DRIVE_GEN:
process(clk0)
begin
if falling_edge(clk0) then
drive <= we_reg;
end if;
end process;
DQS_DRIVE_GEN:
process(clk0)
variable p : unsigned(1 downto 0);
begin
if rising_edge(clk0) then
if phy_ctrl.drive_en = '1' then
p := (others => '1');
else
p := p(p'left-1 downto 0) & '0';
end if;
end if;
end process;
------------------------------------------------------------------------------------------------------------------------------------------------
-- SDRAM Clock
part_clk <= clk0;
------------------------------------------------------------------------------------------------------------------------------------------------
-- Data OUT FFs
process (clk_wr) is
begin
if falling_edge(clk_wr) then
part_data <= (others => 'Z');
if (drive = '1') then
part_data <= phy_in.wr_data;
end if;
end if;
end process;
------------------------------------------------------------------------------------------------------------------------------------------------
-- Data-mask OUT DDR-FFs
process (clk_wr) is
begin
if falling_edge(clk_wr) then
part_dqm <= phy_in.wr_dm;
end if;
end process;
------------------------------------------------------------------------------------------------------------------------------------------------
process (clk0) is
begin
if rising_edge(clk0) then
if rst0 = '1' then
part_ctrl_reg.cmd <= COMMAND(SD_DESELECT);
part_ctrl_reg.ba <= (others=>'0');
part_ctrl_reg.addr <= (others=>'0');
part_ctrl_reg.cke <= '0';
else
part_ctrl_reg <= phy_ctrl.part;
end if;
end if;
end process;
process (clk0) is
begin
if falling_edge(clk0) then
part_ras_n <= part_ctrl_reg.cmd.ras_n;
part_cas_n <= part_ctrl_reg.cmd.cas_n;
part_we_n <= part_ctrl_reg.cmd.we_n;
part_cs_n <= part_ctrl_reg.cmd.cs_n;
part_ba <= part_ctrl_reg.ba;
part_addr <= part_ctrl_reg.addr;
part_cke <= part_ctrl_reg.cke;
end if;
end process;
-----------------------------------------------------------------
-- READ DATA Processing
-----------------------------------------------------------------
data_sample_stage:
process (clk0)
begin
if falling_edge(clk0) then
data_reg_r <= part_data;
end if;
end process;
misc_flags_and_data_out:
process (clk0)
variable p : unsigned(3 downto 0);
begin
if rising_edge(clk0) then
if rst0 = '1' then
p := (others => '0');
read_en <= '0';
phy_out.rd_data_we <= '0';
phy_out.wr_data_re <= '0';
else
phy_out.rd_data <= data_reg_r;
if p(3) = '1' then
phy_out.tag_rd <= u_tag_pipe(4);
end if;
if phy_ctrl.we = '1' then
phy_out.tag_wr <= u_tag_pipe(0);
end if;
phy_out.wr_data_re <= phy_ctrl.we;
phy_out.rd_data_we <= p(3);
read_en <= p(1);
if phy_ctrl.re = '1' then
p := p(p'left-1 downto 0) & '1';
else
p := p(p'left-1 downto 0) & '0';
end if;
end if;
end if;
end process;
------------------------------------------------------------------------------------------
end tech;
@@ -0,0 +1,79 @@
-------------------------------------------------------------------------
-- Project: SDRAM controller
-- This file: User SDRAM component adjustments
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program 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.
--
-- This program 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
package sdram_config is
constant PART_DATA_WIDTH : positive := 16; -- External DDR-SDRAM Module data bus width
constant PART_ADDR_WIDTH : positive := 13; -- number of address lines to DDR-SDRAM Device/Module
constant PART_BANK_WIDTH : positive := 2; -- Number of BANK address lines of external DDR-SDRAM
constant PART_ROW_ADDR_WIDTH : positive := 13; --
constant PART_COL_ADDR_WIDTH : positive := 9; --
constant PART_DQS_WIDTH : positive := PART_DATA_WIDTH / 8; -- Number of data strobe lines
constant PART_DM_WIDTH : positive := PART_DATA_WIDTH / 8; -- Number of Data Mask Lines
constant BUS_DATA_WIDTH : positive := PART_DATA_WIDTH; -- SDR => part data width
constant BUS_DM_WIDTH : positive := PART_DM_WIDTH; -- SDR => part data width
constant LMR_REG_BASE : natural := 0;
constant LMR_REG_EXTENDED : natural := 1;
constant LMR_OP_NORMAL : natural := 0;
constant LMR_OP_RES_DLL : natural := 2;
constant LMR_BT_SEQ : natural := 0;
constant LMR_BT_ILVD : natural := 1;
constant LMR_BL2 : natural := 1;
constant LMR_BL4 : natural := 2;
constant LMR_BL8 : natural := 3;
constant LMR_CL2 : natural := 2;
constant LMR_CL3 : natural := 3;
constant LMR_CL2_5 : natural := 6;
-- DDR SDRAM Hardware defined constants
constant BIT_AUTO_PRE : positive := 10; -- bit-position in column address for auto precharge (see Data Sheet)
constant BIT_PRE_ALL : positive := 10; -- bit-position in column address for precharge all (see Data Sheet)
constant ENABLE_PRE_ALL : std_logic := '1';
constant ENABLE_AUTO_PRE : std_logic := '0';
-- DDR-SDR TIMING constants ------------------------------------------------------------------
-- After REFRESH_CLOCKS a refresh cycle is necessary, 64ms / 8192 = max every 7.8125 us refesh
constant REFRESH_INTERVAL : real := 7.8125E3; -- [ns]
-- These values are for your SDRAM part (see datasheet)
constant TCAS : positive := 2; -- CAS latency [clocks]
constant TRP : real := 20.0; -- precharge command period [ns]
constant TRAS : real := 45.0; -- active to precharge delay [ns]
constant TRFC : real := 75.0; -- auto refresh command period [ns]
constant TMRD : positive := 2; -- load mode register command cylce time [clocks]
constant TRCD : real := 20.0; -- active to read or write delay [ns]
constant TWR : real := 15.0; -- write recovery time [ns]
constant PWR_UP_WAIT : real := 1.0E3; -- [ns]
subtype user_tag_t is unsigned(3 downto 0);
----------------------------------------------------------------------------------------------
end sdram_config;
@@ -0,0 +1,235 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program 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.
--
-- This program 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.fifo_ctrl_pkg.all;
use work.sdram_config.all;
use work.sdram_types.all;
entity sdram_ctrl_frontend_wb16 is
Generic
(
BURST_LEN : natural := 2;
F_SYSCLK : real := 100.0;
F_SDRCLK : real := 100.0;
FIFO_DEPTH : integer := 4
);
Port
(
RST_I : in STD_LOGIC;
CLK_I : in STD_LOGIC;
SDRAM_RST0 : in STD_LOGIC;
SDRAM_CLK0 : in STD_LOGIC;
CYC_I : in STD_LOGIC;
STB_I : in STD_LOGIC;
SEL_I : in unsigned(3 downto 0);
WE_I : in STD_LOGIC;
ACK_O : out STD_LOGIC;
MRDY_I : in STD_LOGIC;
SRDY_O : out STD_LOGIC;
ADDR_I : in unsigned(31 downto 0);
DAT_I : in unsigned(31 downto 0);
DAT_O : out unsigned(31 downto 0);
-- PHY interface
phy_ctrl : out phy_ctrl_t;
phy_in : out phy_in_t;
phy_out : in phy_out_t
);
end sdram_ctrl_frontend_wb16;
architecture struct of sdram_ctrl_frontend_wb16 is
signal u_addr : user_addr_t;
signal u_tag_in : user_tag_t;
signal u_cmd : user_cmd_t;
signal u_cmd_we : std_logic;
signal u_busy : std_logic;
signal rdy : std_logic;
constant CAT_FIFO_WIDTH : integer := user_cmd_t'length + user_tag_t'length + PART_ROW_ADDR_WIDTH + PART_BANK_WIDTH + PART_COL_ADDR_WIDTH;
signal cat_fifo_din : unsigned(CAT_FIFO_WIDTH-1 downto 0);
signal cat_fifo_dout : unsigned(CAT_FIFO_WIDTH-1 downto 0);
signal cat_fifo_re : std_logic;
signal cat_fifo_we : std_logic;
signal cat_fifo_full : std_logic;
signal cat_fifo_empty : std_logic;
signal write_fifo_din : unsigned(BUS_DATA_WIDTH + BUS_DM_WIDTH-1 downto 0);
signal write_fifo_dout : unsigned(BUS_DATA_WIDTH + BUS_DM_WIDTH-1 downto 0);
signal write_fifo_re : std_logic;
signal write_fifo_we : std_logic;
signal write_fifo_full : std_logic;
signal write_fifo_empty : std_logic;
signal read_fifo_din : unsigned(BUS_DATA_WIDTH-1 downto 0);
signal read_fifo_dout : unsigned(BUS_DATA_WIDTH-1 downto 0);
signal read_fifo_re : std_logic;
signal read_fifo_we : std_logic;
signal read_fifo_full : std_logic;
signal read_fifo_empty : std_logic;
alias cmd_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-1 downto CAT_FIFO_WIDTH-user_cmd_t'length);
alias tag_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-user_cmd_t'length-1 downto CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length);
alias addr_fifo_in is cat_fifo_din(CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length-1 downto 0);
alias cmd_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-1 downto CAT_FIFO_WIDTH-user_cmd_t'length);
alias tag_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-user_cmd_t'length-1 downto CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length);
alias addr_fifo_out is cat_fifo_dout(CAT_FIFO_WIDTH-user_cmd_t'length-user_tag_t'length-1 downto 0);
alias write_fifo_data_in is write_fifo_din(write_fifo_din'length-1 downto BUS_DM_WIDTH);
alias write_fifo_dm_in is write_fifo_din(BUS_DM_WIDTH-1 downto 0);
alias write_fifo_data_out is write_fifo_dout(write_fifo_dout'length-1 downto BUS_DM_WIDTH);
alias write_fifo_dm_out is write_fifo_dout(BUS_DM_WIDTH-1 downto 0);
alias read_fifo_data_in is read_fifo_din(read_fifo_din'length-1 downto 0);
alias read_fifo_data_out is read_fifo_dout(read_fifo_dout'length-1 downto 0);
begin
-- Instantiate synchronous FIFO
inst_cat_fifo: entity work.fifo_sync
GENERIC MAP
(
addr_width => FIFO_DEPTH,
data_width => CAT_FIFO_WIDTH
)
PORT MAP
(
rst => RST_I,
clk => CLK_I,
we => cat_fifo_we,
re => cat_fifo_re,
fifo_full => cat_fifo_full,
fifo_empty => cat_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => cat_fifo_din,
data_r => cat_fifo_dout
);
-- Instantiate synchronous FIFO
inst_write_fifo: entity work.fifo_async
GENERIC MAP
(
addr_width => FIFO_DEPTH,
data_width => write_fifo_din'length
)
PORT MAP
(
rst => SDRAM_RST0,
clk_w => CLK_I,
clk_r => SDRAM_CLK0,
we => write_fifo_we,
re => write_fifo_re,
fifo_full => write_fifo_full,
fifo_empty => write_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => write_fifo_din,
data_r => write_fifo_dout
);
-- Instantiate synchronous FIFO
inst_read_fifo: entity work.fifo_async
GENERIC MAP
(
addr_width => FIFO_DEPTH,
data_width => read_fifo_din'length
)
PORT MAP
(
rst => SDRAM_RST0,
clk_w => SDRAM_CLK0,
clk_r => CLK_I,
we => read_fifo_we,
re => read_fifo_re,
fifo_full => read_fifo_full,
fifo_empty => read_fifo_empty,
fifo_afull => open,
fifo_aempty => open,
data_w => read_fifo_din,
data_r => read_fifo_dout
);
-- DDR SDRAM Controller Core
inst_sdram_ctrl_top : entity work.sdram_ctrl_top
Generic map
(
BURST_LEN => BURST_LEN,
F_SYSCLK => F_SYSCLK,
F_SDRCLK => F_SDRCLK,
FIFO_DEPTH => FIFO_DEPTH
)
Port map
(
sys_rst_in => RST_I,
sys_clk_in => CLK_I,
sdram_rst0 => SDRAM_RST0,
sdram_clk0 => SDRAM_CLK0,
-- User interface
u_tag => u_tag_in,
u_busy => u_busy,
u_addr => u_addr,
u_cmd => u_cmd,
u_cmd_we => u_cmd_we,
-- Phy control interface
phy_ctrl => phy_ctrl
);
------------------------------------------------------------------------------------------
SRDY_O <= rdy;
ACK_O <= not (read_fifo_empty);
DAT_O <= read_fifo_data_out & read_fifo_data_out;
rdy <= not (cat_fifo_full or write_fifo_full or read_fifo_full) and CYC_I;
write_fifo_we <= STB_I and WE_I and rdy;
write_fifo_data_in <= DAT_I(15 downto 0);
write_fifo_dm_in <= not SEL_I(1 downto 0);
cat_fifo_we <= STB_I and rdy;
cmd_fifo_in <= UCMD_WRITE when WE_I = '1' else UCMD_READ;
addr_fifo_in <= ADDR_I(24 downto 2) & "0";
tag_fifo_in <= "000" & ADDR_I(25);
u_cmd_we <= (not cat_fifo_empty) and (not u_busy);
u_cmd <= cmd_fifo_out;
u_addr <= addr_fifo_out;
phy_in.wr_dm <= write_fifo_dm_out;
u_tag_in <= tag_fifo_out;
phy_in.wr_data <= write_fifo_data_out;
write_fifo_re <= phy_out.wr_data_re and (not write_fifo_empty);
cat_fifo_re <= u_cmd_we;
read_fifo_re <= (not read_fifo_empty) and MRDY_I;
read_fifo_we <= phy_out.rd_data_we;
read_fifo_data_in <= phy_out.rd_data;
end architecture struct;
@@ -0,0 +1,834 @@
-------------------------------------------------------------------------
-- Project: JCPU, a portable 8-bit RISC CPU written in VHDL
-- This file: cpu_embedded using cpu_core and rom
--
-- Copyright (C) 2007 J. Ahrensfeld
--
-- This program 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.
--
-- This program 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/>.
--
-- For questions and ideas, please contact the author at jens@jayfield.org
--
--------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use work.sdram_config.all;
use work.sdram_types.all;
entity tb_ctrl_sdr_wb32 is
end;
architecture struct of tb_ctrl_sdr_wb32 is
constant CLK_PERIOD : time := 10 ns;
constant SDCLK_PERIOD : time := 10 ns;
constant BURST_LEN : natural := 2;
signal sdclk : std_logic := '1';
signal sdclk_fb : std_logic;
signal part_clk : std_logic;
signal part_cke : std_logic;
signal part_cs_n : std_logic;
signal part_we_n : std_logic;
signal part_ras_n : std_logic;
signal part_cas_n : std_logic;
signal part_ba : unsigned(PART_BANK_WIDTH-1 downto 0) := (others => '0');
signal part_dqm : unsigned(PART_DM_WIDTH-1 downto 0) := (others => '0');
signal part_addr : unsigned(PART_ADDR_WIDTH-1 downto 0) := (others => '0');
signal part_data : unsigned(PART_DATA_WIDTH-1 downto 0) := (others => '0');
signal CLK_O : std_logic := '1';
signal RST_O : std_logic := '1';
signal CYC_O : std_logic := '0';
signal STB_O : std_logic := '0';
signal WE_O : std_logic := '0';
signal SEL_O : unsigned(3 downto 0) := (others => '1');
signal ACK_I : std_logic;
signal MRDY_O : std_logic := '1';
signal SRDY_I : std_logic;
signal ADDR_O : unsigned(31 downto 0) := (others => '-');
signal DAT_I : unsigned(31 downto 0);
signal DAT_O : unsigned(31 downto 0) := (others => '-');
signal dout_rst : std_logic := '0';
signal dout_reg : unsigned(31 downto 0);
signal dout_cnt : natural range 0 to 255;
type sd_cmd_t is (nop, lmr, ar, pre, act, write, read, bst);
signal sd_cmd : sd_cmd_t;
begin
process(part_cs_n, part_ras_n, part_cas_n, part_we_n)
variable cmd : unsigned (2 downto 0);
begin
cmd := part_ras_n & part_cas_n & part_we_n;
sd_cmd <= nop;
if part_cs_n = '0' then
case cmd is
when "000" =>
sd_cmd <= lmr;
when "001" =>
sd_cmd <= ar;
when "010" =>
sd_cmd <= pre;
when "011" =>
sd_cmd <= act;
when "100" =>
sd_cmd <= write;
when "101" =>
sd_cmd <= read;
when "110" =>
sd_cmd <= bst;
when "111" =>
sd_cmd <= nop;
when others =>
sd_cmd <= nop;
end case;
end if;
end process;
sdclk_fb <= part_clk after 1 ns;
-- DDR SDRAM Controller Core
uut : entity work.ctrl_sdr_wb32
GENERIC MAP
(
BURST_LEN => BURST_LEN,
F_SYSCLK => 100.000,
F_SDRCLK => 100.000,
FIFO_DEPTH => 4
)
PORT MAP
(
RST_I => RST_O,
CLK_I => CLK_O,
SDRAM_CLK_I => sdclk,
SDRAM_CLK_FB_I => sdclk_fb,
CYC_I => CYC_O,
STB_I => STB_O,
SEL_I => SEL_O,
WE_I => WE_O,
ACK_O => ACK_I,
SRDY_O => SRDY_I,
MRDY_I => MRDY_O,
ADDR_I => ADDR_O,
DAT_I => DAT_O,
DAT_O => DAT_I,
-- SDRAM signals
sd_clk => part_clk,
sd_cke => part_cke,
sd_cs_n => part_cs_n,
sd_cas_n => part_cas_n,
sd_ras_n => part_ras_n,
sd_we_n => part_we_n,
sd_addr => part_addr,
sd_ba => part_ba,
sd_dqm => part_dqm,
sd_data => part_data
);
-- MICRON DDR SDRAM Simulation Model
-- 4M x16x4 Banks
-- IS42S16160B-7
i_mt48lc16m16_0 : entity work.mt48lc16m16a2
generic map
(
tAC => 6.5 ns,
tHZ => 5.4 ns,
tOH => 2.7 ns,
tMRD => 2, -- 2 Clk Cycles
tRAS => 45.0 ns,
tRC => 67.5 ns,
tRCD => 20.0 ns,
tRP => 20.0 ns,
tRRD => 14.0 ns,
tAH => 0.8 ns,
tAS => 1.5 ns,
tCH => 0.8 ns,
tCL => 2.5 ns,
tCK => 10.0 ns,
tDH => 0.8 ns,
tDS => 1.5 ns,
tCKH => 0.8 ns,
tCKS => 1.5 ns,
tCMH => 0.8 ns,
tCMS => 1.5 ns
)
port map
(
unsigned(Dq) => std_logic_vector(part_data),
Addr => std_logic_vector(part_addr),
Ba => std_logic_vector(part_ba),
Clk => part_clk,
Cke => part_cke,
Cs_n => part_cs_n,
Ras_n => part_ras_n,
Cas_n => part_cas_n,
We_n => part_we_n,
Dqm => std_logic_vector(part_dqm)
);
CLK_GEN: process
begin
wait for CLK_PERIOD/2;
CLK_O <= not CLK_O;
end process;
SDCLK_GEN: process
begin
wait for SDCLK_PERIOD/2;
sdclk <= not sdclk;
end process;
read_register:
process(CLK_O)
begin
if rising_edge(CLK_O) then
if dout_rst = '1' then
dout_cnt <= 0;
elsif ACK_I = '1' and WE_O = '0' then
dout_reg <= DAT_I;
dout_cnt <= dout_cnt + 1;
end if;
end if;
end process;
------------------------------------------------------------------------------------------
STIMULUS: process
begin
wait for 3*CLK_PERIOD;
RST_O <= '0';
wait until RST_O = '0';
-- 8 single cycles
CYC_O <= '1';
STB_O <= '1';
WE_O <= '1';
DAT_O <= X"0000_1234";
ADDR_O <= X"0000_0000";
for i in 0 to 8192 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
DAT_O <= DAT_O + 1;
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O);
CYC_O <= '0';
------------------------------------------------------------
wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_0000";
for i in 0 to 31 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 31;
CYC_O <= '0';
------------------------------------------------------------
wait for 3*CLK_PERIOD;
------------------------------------------------------------
wait until rising_edge(CLK_O);
-- 1-word burst cycle
CYC_O <= '1';
STB_O <= '1';
WE_O <= '1';
SEL_O <= "0011";
ADDR_O <= X"0000_0080";
DAT_O <= X"0000_BEEF";
wait until rising_edge(CLK_O) and SRDY_I = '1';
STB_O <= '0';
wait until rising_edge(CLK_O);
CYC_O <= '0';
------------------------------------------------------------
wait for 3*CLK_PERIOD;
------------------------------------------------------------
wait until rising_edge(CLK_O);
-- 1-word burst cycle
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_0080";
wait until rising_edge(CLK_O) and SRDY_I = '1';
STB_O <= '0';
wait until rising_edge(CLK_O) and ACK_I = '1';
CYC_O <= '0';
------------------------------------------------------------
wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_0000";
for i in 0 to 31 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 31;
CYC_O <= '0';
------------------------------------------------------------
wait for 10*CLK_PERIOD;
------------------------------------------------------------
for k in 0 to 3 loop
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_0000";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_0400";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_0800";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_0C00";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
end loop;
------------------------------------------------------------
wait for 10*CLK_PERIOD;
------------------------------------------------------------
for k in 0 to 3 loop
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_1000";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_1400";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_1800";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_1C00";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
end loop;
------------------------------------------------------------
wait for 10*CLK_PERIOD;
------------------------------------------------------------
for k in 0 to 3 loop
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '1';
SEL_O <= "1111";
DAT_O <= X"0000_1111";
ADDR_O <= X"0000_0000";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
DAT_O <= DAT_O + 1;
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O);
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '1';
SEL_O <= "1111";
DAT_O <= X"0000_2222";
ADDR_O <= X"0000_0400";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
DAT_O <= DAT_O + 1;
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O);
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '1';
SEL_O <= "1111";
DAT_O <= X"0000_3333";
ADDR_O <= X"0000_0800";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
DAT_O <= DAT_O + 1;
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O);
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '1';
SEL_O <= "1111";
DAT_O <= X"0000_4444";
ADDR_O <= X"0000_0C00";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
DAT_O <= DAT_O + 1;
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O);
CYC_O <= '0';
end loop;
------------------------------------------------------------
wait for 10*CLK_PERIOD;
------------------------------------------------------------
for k in 0 to 3 loop
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '1';
SEL_O <= "1111";
DAT_O <= X"0000_1111";
ADDR_O <= X"0000_1000";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
DAT_O <= DAT_O + 1;
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O);
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '1';
SEL_O <= "1111";
DAT_O <= X"0000_2222";
ADDR_O <= X"0000_1400";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
DAT_O <= DAT_O + 1;
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O);
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '1';
SEL_O <= "1111";
DAT_O <= X"0000_3333";
ADDR_O <= X"0000_1800";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
DAT_O <= DAT_O + 1;
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O);
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '1';
SEL_O <= "1111";
DAT_O <= X"0000_4444";
ADDR_O <= X"0000_1C00";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
DAT_O <= DAT_O + 1;
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O);
CYC_O <= '0';
end loop;
------------------------------------------------------------
wait for 10*CLK_PERIOD;
------------------------------------------------------------
for k in 0 to 3 loop
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_1000";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_1400";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_1800";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
------------------------------------------------------------
-- wait for 3*CLK_PERIOD;
------------------------------------------------------------
-- 8-word burst cycle
dout_rst <= '1';
wait until rising_edge(CLK_O);
dout_rst <= '0';
CYC_O <= '1';
STB_O <= '1';
WE_O <= '0';
ADDR_O <= X"0000_1C00";
for i in 0 to 7 loop
wait until rising_edge(CLK_O) and SRDY_I = '1';
ADDR_O <= ADDR_O + 4;
end loop;
STB_O <= '0';
wait until rising_edge(CLK_O) and dout_cnt = 7;
CYC_O <= '0';
end loop;
wait;
end process;
end architecture struct;