- 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:
@@ -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
@@ -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;
|
||||
Reference in New Issue
Block a user