📄 ddr_sdram_tb.vhd
字号:
--/******************************************************************************
--*
--* LOGIC CORE: SDR SDRAM Controller test bench
--* MODULE NAME: sdr_sdram_tb()
--* COMPANY: Northwest Logic Design, Inc.
--* www.nwlogic.com
--*
--* REVISION HISTORY:
--*
--* Revision 1.0 06/27/2000 Description: Initial Release.
--*
--* FUNCTIONAL DESCRIPTION:
--*
--* This module is the test bench for the DDR SDRAM controller.
--*
--* Copyright Northwest Logic Design, Inc., 2000. All rights reserved.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--library arithmetic;
--use arithmetic.std_logic_arith.all;
entity ddr_sdram_tb is
generic (
ASIZE : integer := 22;
DSIZE : integer := 128;
ROWSIZE : integer := 12;
COLSIZE : integer := 8;
BANKSIZE : integer := 2;
ROWSTART : integer := 8;
COLSTART : integer := 0;
BANKSTART : integer := 19
);
end ddr_sdram_tb;
architecture rtl of ddr_sdram_tb is
component ddr_sdram
port (
CLK : in std_logic; --System Clock
RESET_N : in std_logic; --System Reset
ADDR : in std_logic_vector(ASIZE-1 downto 0); --Address for controller requests
CMD : in std_logic_vector(2 downto 0); --Controller command
CMDACK : out std_logic; --Controller command acknowledgement
DATAIN : in std_logic_vector(DSIZE-1 downto 0); --Data input
DATAOUT : out std_logic_vector(DSIZE-1 downto 0); --Data output
DM : in std_logic_vector(DSIZE/8-1 downto 0); --Data mask input
SA : out std_logic_vector(11 downto 0); --SDRAM address output
BA : out std_logic_vector(1 downto 0); --SDRAM bank address
CS_N : out std_logic_vector(1 downto 0); --SDRAM Chip Selects
CKE : out std_logic; --SDRAM clock enable
RAS_N : out std_logic; --SDRAM Row address Strobe
CAS_N : out std_logic; --SDRAM Column address Strobe
WE_N : out std_logic; --SDRAM write enable
DQ : inout std_logic_vector(DSIZE/2-1 downto 0); --SDRAM data bus
DQM : out std_logic_vector(DSIZE/16-1 downto 0); --SDRAM data mask lines
DQS : inout std_logic_vector(DSIZE/16-1 downto 0)
);
end component;
component mt46v4m16
PORT (
Dq : INOUT STD_LOGIC_VECTOR (15 DOWNTO 0) := (OTHERS => 'Z');
Dqs : INOUT STD_LOGIC_VECTOR (1 DOWNTO 0);
Addr : IN STD_LOGIC_VECTOR (11 DOWNTO 0) := (OTHERS => '0');
Ba : IN STD_LOGIC_VECTOR := "00";
Clk : IN STD_LOGIC := '0';
Clk_n : IN STD_LOGIC;
Cke : IN STD_LOGIC := '0';
Cs_n : IN STD_LOGIC := '1';
Ras_n : IN STD_LOGIC := '0';
Cas_n : IN STD_LOGIC := '0';
We_n : IN STD_LOGIC := '0';
Dm : IN STD_LOGIC_VECTOR (1 DOWNTO 0) := (OTHERS => '0')
);
END component;
signal clk : std_logic := '0';
signal clk2 : std_logic := '0';
signal clk2n : std_logic := '1';
signal reset_n : std_logic;
signal sa : std_logic_vector(11 downto 0);
signal ba : std_logic_vector(1 downto 0);
signal cs_n : std_logic_vector(1 downto 0);
signal cke : std_logic;
signal ras_n : std_logic;
signal cas_n : std_logic;
signal we_n : std_logic;
signal cmd : std_logic_vector(2 downto 0);
signal cmdack : std_logic;
signal addr : std_logic_vector(ASIZE-1 downto 0);
signal datain : std_logic_vector(DSIZE-1 downto 0);
signal dataout : std_logic_vector(DSIZE-1 downto 0);
signal dm : std_logic_vector(DSIZE/8-1 downto 0);
signal dq : std_logic_vector(DSIZE/2-1 downto 0);
signal dqm : std_logic_vector(DSIZE/16-1 downto 0);
signal dqs : std_logic_vector(DSIZE/16-1 downto 0);
signal mode_reg : std_logic_vector(11 downto 0);
signal test_addr : std_logic_vector(ASIZE-1 downto 0);
signal test_data : std_logic_vector(DSIZE-1 downto 0);
signal y : std_logic_vector(2 downto 0);
signal z : std_logic_vector(1 downto 0);
-- write_burst(start_data, start_addr, bl, rcd, mask, addr, dataout, dqm, cmdack, cmd)
--
-- This task performs a write access of size BL
-- at SDRAM address to the SDRAM controller
--
-- start_data : Starting value for the burst write sequence. The write burst procedure
-- simply increments the data values from the start_data value.
-- start_addr : Address in SDRAM to start the burst access
-- bl : bl is the burst length the sdram devices have been configured for.
-- rcd : rcd value that was set during configuration
-- mask : Byte data mask for all cycles in the burst.
-- addr : Address output
-- dataout : Data output
-- dqm : data mask output
-- cmdack : Command ack input
-- cmd : Command output
procedure burst_write (
start_data: std_logic_vector(DSIZE-1 downto 0);
start_addr: std_logic_vector(ASIZE-1 downto 0);
bl : integer;
rcd : integer;
mask : std_logic_vector(DSIZE/8-1 downto 0);
signal addr: out std_logic_vector(ASIZE-1 downto 0);
signal dataout: out std_logic_vector(DSIZE-1 downto 0);
signal dqm: out std_logic_vector(DSIZE/8-1 downto 0);
signal cmdack: std_logic;
signal cmd: out std_logic_vector(2 downto 0)) is
variable i : integer;
begin
wait until (CLK'event and CLK = '1');
wait for 1 ns;
cmd <= "010"; -- issued a WRITEA command
addr <= start_addr;
dataout <= start_data; -- issue the first data value
dqm <= mask;
wait until (cmdack = '1'); -- wait for a ack from the controller
wait until (CLK'event and CLK = '1');
wait for 1 ns;
cmd <= "000"; -- NOP the commmand input
for i in 1 to rcd-2 loop -- wait for RAS to CAS to expire
wait until (CLK'event and CLK = '1');
wait for 2 ns;
end loop;
for i in 1 to bl loop -- loop from 1 to bl
dataout <= start_data + i; -- clock the data into the controller
wait until (CLK'event and CLK = '1');
wait for 2 ns;
end loop;
dqm <= "0000000000000000";
end burst_write;
-- burst_read(address, start_value, CL, RCD, BL)
--
-- This task performs a read access of size BL
-- at SDRAM address to the SDRAM controller
--
-- start_data : Starting value for the burst read sequence. The read burst task
-- simply increments and compares the data values from the start_value.
-- start_addr : Address in SDRAM to start the burst access.
-- bl : bl is the burst length the sdram devices have been configured for.
-- cl : CAS latency the sdram devices have been configured for.
-- rcd : rcd value the controller has been configured for.
-- addr : Address output
-- datain : Data input
-- cmdack : Command ack input
-- cmd : Command output
procedure burst_read (
start_data: std_logic_vector(DSIZE-1 downto 0);
start_addr: std_logic_vector(ASIZE-1 downto 0);
bl : integer;
cl : integer;
rcd : integer;
signal addr: out std_logic_vector(ASIZE-1 downto 0);
signal datain: std_logic_vector(DSIZE-1 downto 0);
signal cmdack: std_logic;
signal cmd: out std_logic_vector(2 downto 0)) is
variable i: std_logic_vector(3 downto 0) := "0000";
variable ddr_cl : integer := 0;
begin
if (cl = 2) then -- cas latency = 2.0
ddr_cl := 2;
elsif (cl = 3) then -- cas latency = 2.5
ddr_cl := 2;
elsif (cl = 4) then -- cas latency = 3.0
ddr_cl := 3;
end if;
wait until (CLK'event and CLK = '1');
wait for 1 ns;
cmd <= "001"; -- issue a READA command
addr <= start_addr;
wait until (cmdack = '1'); -- wait for command ack
wait until (CLK'event and CLK = '1');
wait for 1 ns;
cmd <= "000"; -- NOP the command input
for i in 1 to (ddr_cl+rcd+4) loop -- wait for RAS to CAS and cl to expire
wait until (CLK'event and CLK = '1');
end loop;
for i in 1 to bl loop -- loop from 1 to burst length(BL),
wait until (CLK'event and CLK = '1'); -- collecting and comparing the data
-- wait for 3 ns;
if (datain /= start_data + i - 1 ) then
assert false
REPORT "read data mis-match"
SEVERITY FAILURE;
end if;
end loop;
end burst_read;
-- config(cl, rc, bl, pm, ref)
--
-- This task cofigures the SDRAM devices and the controller
--
-- cl : Cas latency, 2 or 3
-- rc : Ras to Cas delay.
-- bl : Burst length 1,2,4, or 8
-- pm : page mode setting
-- ref : refresh period setting
procedure config ( cl: std_logic_vector(2 downto 0);
rc: std_logic_vector(1 downto 0);
bl: integer;
pm: std_logic;
ref: std_logic_vector(15 downto 0);
signal addr: out std_logic_vector(ASIZE-1 downto 0);
signal cmdack: std_logic;
signal cmd: out std_logic_vector(2 downto 0)) is
begin
addr <= (others => '0');
wait until (CLK'event and CLK = '1');
wait for 1 ns;
cmd <= "100";
wait until (cmdack = '1');
wait until (CLK'event and CLK = '1'); -- Wait for the controller to ack the command
wait for 1 ns;
cmd <= "000"; -- Clear the command by issuing a NOP
if (bl = 2) then
addr(2 downto 0) <= "001"; -- Set the Burst length portion of the mode data
elsif (bl = 4) then
addr(2 downto 0) <= "010";
elsif (bl = 8) then
addr(2 downto 0) <= "011";
end if;
if (cl = 2) then
addr(6 downto 4) <= "010";
elsif (cl = 3) then
addr(6 downto 4) <= "110";
elsif (cl = 4) then
addr(6 downto 4) <= "011";
end if;
cmd <= "100"; -- issue precharge
wait until (cmdack = '1');
wait until (CLK'event and CLK = '1');
wait for 1 ns;
cmd <= "000";
wait until (CLK'event and CLK = '1');
cmd <= "101";
wait until (cmdack = '1'); -- Wait for the controller to ack the command
wait until (CLK'event and CLK = '1');
wait for 1 ns;
cmd <= "000"; -- Clear the command by issuing a NOP
wait until (CLK'event and CLK = '1');
wait until (CLK'event and CLK = '1');
wait for 1 ns;
addr(15 downto 0) <= ref;
cmd <= "111"; -- load refresh counter
wait until (cmdack = '1'); -- Wait for the controller to ack the command
wait until (CLK'event and CLK = '1');
wait for 1 ns;
cmd <= "000"; -- Clear the command by issuing a NOP
addr(1 downto 0) <= cl(1 downto 0); -- load contorller reg1
addr(3 downto 2) <= rc;
addr(8) <= pm;
if (bl = 2) then
addr(12 downto 9) <= "0001"; -- Set the Burst length portion of the mode data
elsif (bl = 4) then
addr(12 downto 9) <= "0010";
elsif (bl = 8) then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -