1
0
mirror of https://github.com/wfjm/w11.git synced 2026-04-07 22:50:38 +00:00

add sys_tst_mig_arty system: a MIG tester

This commit is contained in:
wfjm
2019-01-01 22:41:44 +01:00
parent 14362b2a56
commit f50a85e646
27 changed files with 2294 additions and 16 deletions

View File

@@ -48,19 +48,20 @@ before_script:
#
script:
- make -C tools/src
- make -C tools/src/testtclsh
- make -j 2 -C tools/src
- make -j 2 -C tools/src/testtclsh
- make all_tcl
- make -C tools/asm-11/tests allexp
- make -C tools/asm-11/tests-err allexp
- |
tbrun -nomake \
tbrun -j 2 -nomake \
-tag default,memlib \
-tag default,genlib \
-tag default,comlib \
-tag default,rlink \
-tag default,serport \
-tag default,bplib \
-tag default,mig \
-tag default,w11a \
-tag default,sys_tst_serloop \
-tag default,sys_tst_serloop1 \
@@ -70,6 +71,7 @@ script:
-tag default,sys_tst_rlink_cuff,baseser \
-tag default,sys_tst_sram,base \
-tag default,sys_tst_sram,n4 \
-tag default,sys_tst_mig,base \
-tag default,sys_w11a,stim1 \
-tag default,sys_w11a,n4
- tbfilt -all -sum -comp

View File

@@ -1,4 +1,4 @@
# $Id: Makefile 1055 2018-10-12 17:53:52Z mueller $
# $Id: Makefile 1098 2018-12-30 11:40:42Z mueller $
#
# 'Meta Makefile' for whole retro project
# allows to make all synthesis targets
@@ -74,6 +74,7 @@ SYN_viv += rtl/sys_gen/tst_sram/nexys4
SYN_viv += rtl/sys_gen/w11a/nexys4
# Arty ---------------------------------------
SYN_viv += rtl/sys_gen/tst_mig/arty
SYN_viv += rtl/sys_gen/tst_rlink/arty
SYN_viv += rtl/sys_gen/w11a/arty_bram
@@ -130,6 +131,7 @@ SIM_viv += rtl/sys_gen/tst_sram/nexys4/tb
SIM_viv += rtl/sys_gen/w11a/nexys4/tb
# Arty ---------------------------------------
SIM_viv += rtl/sys_gen/tst_mig/arty/tb
SIM_viv += rtl/sys_gen/tst_rlink/arty/tb
SIM_viv += rtl/sys_gen/w11a/arty_bram/tb

View File

@@ -25,15 +25,22 @@ The full set of tests is only run for tagged releases.
- arty board support
### New features
- s7_cmt_sfs_2: dual-channel frequency synthesis MMCM/PLL wrapper
- s7_cmt_1ce1ce2c: clocking block for 7-Series: 2 clk+CEs + 2 clk
- cdc_signal_s1_as: clock domain crossing for a signal, 2 stage, asyn input
- migui_core_gsim: highly simplified MIG UI simulation model
- new systems
- sys_tst_mig_arty design: a MIG tester
- new components
- s7_cmt_sfs_2: dual-channel frequency synthesis MMCM/PLL wrapper
- s7_cmt_1ce1ce2c: clocking block for 7-Series: 2 clk+CEs + 2 clk
- cdc_signal_s1_as: clock domain crossing for a signal, 2 stage, asyn input
- migui_core_gsim: highly simplified MIG UI simulation model
### Changes
- viv_tools_build: export log and rpt generated in OOC synthesis runs
- viv_tools_build
- export log and rpt generated in OOC synthesis runs
- downgrade SSN critical warnings to warnings
### Bug Fixes
- nexys4d_pins.xdc: BUFFIX: Fix faulty IO voltage for I_SWI[8,9]
### Known issues
<!-- --------------------------------------------------------------------- -->

View File

@@ -1,4 +1,4 @@
# $Id: mig_arty.tcl 1092 2018-12-24 08:01:50Z mueller $
# $Id: mig_arty.tcl 1099 2018-12-31 09:07:36Z mueller $
#
# Copyright 2018- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see License.txt in $RETROBASE directory
@@ -32,7 +32,7 @@ puts [format "## available MIG version: %s" $vers]
if {$mprj ne ""} {
puts [format "## selected MIG version: %s with %s" $vers $mprj]
} else {
error "sramif_mig_arty: no tested MIG version found"
error "mig_arty: no tested MIG version found"
}
create_ip -vlnv "xilinx.com:ip:mig_7series:$vers" -module_name migui_arty

View File

@@ -3,6 +3,7 @@ and is organized in
| Directory | Content |
| --------- | ------- |
| [tst_mig](tst_mig) | MIG core tester |
| [tst_rlink](tst_rlink) | rlink tester (over serial links) |
| [tst_rlink_cuff](tst_rlink_cuff) | rlink tester (over Cypress FX2 USB) |
| [tst_serloop](tst_serloop) | serial port loop back tester |

View File

@@ -0,0 +1,25 @@
# $Id: Makefile 1092 2018-12-24 08:01:50Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2018-12-23 1092 1.0 Initial version
#
VBOM_all = sys_tst_mig_arty.vbom
BIT_all = $(VBOM_all:.vbom=.bit)
#
include ${RETROBASE}/rtl/make_viv/viv_default_arty.mk
#
.PHONY : all clean
#
all : $(BIT_all)
#
clean : viv_clean
#
#----
#
include ${RETROBASE}/rtl/make_viv/generic_vivado.mk
#
ifndef DONTINCDEP
include $(VBOM_all:.vbom=.dep_vsyn)
endif
#

View File

@@ -0,0 +1,60 @@
-- $Id: sys_conf.vhd 1092 2018-12-24 08:01:50Z mueller $
--
-- Copyright 2018- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 3, 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 complete details.
--
------------------------------------------------------------------------------
-- Package Name: sys_conf
-- Description: Definitions for sys_tst_mig_arty (for synthesis)
--
-- Dependencies: -
-- Tool versions: viv 2017.2; ghdl 0.34
-- Revision History:
-- Date Rev Version Comment
-- 2018-12-23 1092 1.0 Initial version
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.slvtypes.all;
package sys_conf is
constant sys_conf_clksys_vcodivide : positive := 1;
constant sys_conf_clksys_vcomultiply : positive := 8; -- vco 800 MHz
constant sys_conf_clksys_outdivide : positive := 10; -- sys 80 MHz
constant sys_conf_clksys_gentype : string := "MMCM";
-- dual clock design, clkser = 120 MHz
constant sys_conf_clkser_vcodivide : positive := 1;
constant sys_conf_clkser_vcomultiply : positive := 12; -- vco 1200 MHz
constant sys_conf_clkser_outdivide : positive := 10; -- sys 120 MHz
constant sys_conf_clkser_gentype : string := "PLL";
-- configure rlink and hio interfaces --------------------------------------
constant sys_conf_ser2rri_defbaud : integer := 115200; -- default 115k baud
-- derived constants
constant sys_conf_clksys : integer :=
((100000000/sys_conf_clksys_vcodivide)*sys_conf_clksys_vcomultiply) /
sys_conf_clksys_outdivide;
constant sys_conf_clksys_mhz : integer := sys_conf_clksys/1000000;
constant sys_conf_clkser : integer :=
((100000000/sys_conf_clkser_vcodivide)*sys_conf_clkser_vcomultiply) /
sys_conf_clkser_outdivide;
constant sys_conf_clkser_mhz : integer := sys_conf_clkser/1000000;
constant sys_conf_ser2rri_cdinit : integer :=
(sys_conf_clkser/sys_conf_ser2rri_defbaud)-1;
end package sys_conf;

View File

@@ -0,0 +1,28 @@
# libs
../../../vlib/slvtypes.vhd
../../../vlib/cdclib/cdclib.vhd
../../../vlib/serport/serportlib.vbom
../../../vlib/rbus/rblib.vhd
../../../vlib/rbus/rbdlib.vhd
../../../vlib/rlink/rlinklib.vbom
../../../bplib/bpgen/bpgenlib.vbom
../../../bplib/sysmon/sysmonrbuslib.vbom
../../../bplib/arty/miglib_arty.vbom
${sys_conf := sys_conf.vhd}
@lib:unisim
# components
../../../bplib/bpgen/s7_cmt_1ce1ce2c.vbom
../../../vlib/cdclib/cdc_pulse.vbom
../../../vlib/cdclib/cdc_signal_s1_as.vbom
../../../bplib/bpgen/bp_rs232_2line_iob.vbom
../../../vlib/rlink/rlink_sp2c.vbom
../tst_mig.vbom
@tcl:../../../bplib/arty/mig_arty.tcl
[ghdl,vsim]../../../bplib/arty/migui_arty_gsim.vbom
../../../bplib/sysmon/sysmonx_rbus_arty.vbom
../../../vlib/rbus/rbd_usracc.vbom
../../../vlib/rbus/rb_sres_or_3.vbom
# design
sys_tst_mig_arty.vhd
@xdc:../../../bplib/arty/arty_pclk.xdc
@xdc:../../../bplib/arty/arty_pins.xdc

View File

@@ -0,0 +1,454 @@
-- $Id: sys_tst_mig_arty.vhd 1096 2018-12-29 07:54:17Z mueller $
--
-- Copyright 2018- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 3, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: sys_tst_mig_arty - syn
-- Description: test of arty ddr and its mig controller
--
-- Dependencies: bplib/bpgen/s7_cmt_1ce1ce2c
-- cdclib/cdc_signal_s1_as
-- cdclib/cdc_pulse
-- bplib/bpgen/bp_rs232_2line_iob
-- rlink/rlink_sp2c
-- tst_mig
-- bplib/arty/migui_arty (generated core)
-- bplib/sysmon/sysmonx_rbus_arty
-- rbus/rbd_usracc
-- rbus/rb_sres_or_3
--
-- Test bench: tb/tb_tst_mig_arty
--
-- Target Devices: generic
-- Tool versions: viv 2017.2; ghdl 0.34
--
-- Synthesized (viv):
-- Date Rev viv Target flop lutl lutm bram slic
-- 2018-12-28 1096 2017.2 xc7a35t-1l 4320 4773 462 1 1770
--
-- Revision History:
-- Date Rev Version Comment
-- 2018-12-26 1094 1.0 Initial version
-- 2018-12-23 1092 0.1 First draft
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.slvtypes.all;
use work.cdclib.all;
use work.serportlib.all;
use work.rblib.all;
use work.rbdlib.all;
use work.rlinklib.all;
use work.bpgenlib.all;
use work.sysmonrbuslib.all;
use work.miglib_arty.all;
use work.sys_conf.all;
library unisim;
use unisim.vcomponents.ALL;
-- ----------------------------------------------------------------------------
entity sys_tst_mig_arty is -- top level
-- implements arty_mig_aif
port (
I_CLK100 : in slbit; -- 100 MHz clock
I_RXD : in slbit; -- receive data (board view)
O_TXD : out slbit; -- transmit data (board view)
I_SWI : in slv4; -- arty switches
I_BTN : in slv4; -- arty buttons
O_LED : out slv4; -- arty leds
O_RGBLED0 : out slv3; -- arty rgb-led 0
O_RGBLED1 : out slv3; -- arty rgb-led 1
O_RGBLED2 : out slv3; -- arty rgb-led 2
O_RGBLED3 : out slv3; -- arty rgb-led 3
A_VPWRN : in slv4; -- arty pwrmon (neg)
A_VPWRP : in slv4; -- arty pwrmon (pos)
DDR3_DQ : inout slv16; -- dram: data in/out
DDR3_DQS_P : inout slv2; -- dram: data strobe (diff-p)
DDR3_DQS_N : inout slv2; -- dram: data strobe (diff-n)
DDR3_ADDR : out slv14; -- dram: address
DDR3_BA : out slv3; -- dram: bank address
DDR3_RAS_N : out slbit; -- dram: row addr strobe (act.low)
DDR3_CAS_N : out slbit; -- dram: column addr strobe (act.low)
DDR3_WE_N : out slbit; -- dram: write enable (act.low)
DDR3_RESET_N : out slbit; -- dram: reset (act.low)
DDR3_CK_P : out slv1; -- dram: clock (diff-p)
DDR3_CK_N : out slv1; -- dram: clock (diff-n)
DDR3_CKE : out slv1; -- dram: clock enable
DDR3_CS_N : out slv1; -- dram: chip select (act.low)
DDR3_DM : out slv2; -- dram: data input mask
DDR3_ODT : out slv1 -- dram: on-die termination
);
end sys_tst_mig_arty;
architecture syn of sys_tst_mig_arty is
signal CLK100_BUF : slbit := '0';
signal XX_CLK : slbit := '0'; -- kept to keep clock setup similar
signal XX_CE_USEC : slbit := '0'; -- to w11a or other 'normal' systems
signal XX_CE_MSEC : slbit := '0'; --
signal CLK : slbit := '0';
signal CE_USEC : slbit := '0';
signal CE_MSEC : slbit := '0';
signal CLKS : slbit := '0';
signal CES_MSEC : slbit := '0';
signal CLKMIG : slbit := '0';
signal CLKREF : slbit := '0';
signal LOCKED : slbit := '0'; -- raw LOCKED
signal LOCKED_CLKMIG : slbit := '0'; -- sync'ed to CLKMIG
signal MEM_RESET : slbit := '0';
signal MEM_RESET_RRI : slbit := '0';
signal RXD : slbit := '1';
signal TXD : slbit := '0';
signal SWI : slv16 := (others=>'0');
signal BTN : slv5 := (others=>'0');
signal LED : slv16 := (others=>'0');
signal DSP_DAT : slv32 := (others=>'0');
signal DSP_DP : slv8 := (others=>'0');
signal RB_MREQ : rb_mreq_type := rb_mreq_init;
signal RB_SRES : rb_sres_type := rb_sres_init;
signal RB_LAM : slv16 := (others=>'0');
signal RB_STAT : slv4 := (others=>'0');
signal SER_MONI : serport_moni_type := serport_moni_init;
signal RB_SRES_TST : rb_sres_type := rb_sres_init;
signal RB_SRES_SYSMON : rb_sres_type := rb_sres_init;
signal RB_SRES_USRACC : rb_sres_type := rb_sres_init;
signal RB_LAM_TST : slbit := '0';
signal APP_ADDR : slv(mig_mawidth-1 downto 0) := (others=>'0');
signal APP_CMD : slv3 := (others=>'0');
signal APP_EN : slbit := '0';
signal APP_WDF_DATA : slv(mig_dwidth-1 downto 0) := (others=>'0');
signal APP_WDF_END : slbit := '0';
signal APP_WDF_MASK : slv(mig_mwidth-1 downto 0) := (others=>'0');
signal APP_WDF_WREN : slbit := '0';
signal APP_RD_DATA : slv(mig_dwidth-1 downto 0) := (others=>'0');
signal APP_RD_DATA_END : slbit := '0';
signal APP_RD_DATA_VALID : slbit := '0';
signal APP_RDY : slbit := '0';
signal APP_WDF_RDY : slbit := '0';
signal APP_SR_REQ : slbit := '0';
signal APP_REF_REQ : slbit := '0';
signal APP_ZQ_REQ : slbit := '0';
signal APP_SR_ACTIVE : slbit := '0';
signal APP_REF_ACK : slbit := '0';
signal APP_ZQ_ACK : slbit := '0';
signal MIG_UI_CLK : slbit := '0';
signal MIG_UI_CLK_SYNC_RST : slbit := '0';
signal MIG_INIT_CALIB_COMPLETE : slbit := '0';
signal MIG_SYS_RST : slbit := '0';
signal XADC_TEMP : slv12 := (others=>'0'); -- xadc die temp; on CLK
signal R_DIMCNT : slv2 := (others=>'0');
signal R_DIMFLG : slbit := '0';
constant rbaddr_rbmon : slv16 := x"ffe8"; -- ffe8/0008: 1111 1111 1110 1xxx
constant rbaddr_sysmon: slv16 := x"fb00"; -- fb00/0080: 1111 1011 0xxx xxxx
constant sysid_proj : slv16 := x"0105"; -- tst_mig
constant sysid_board : slv8 := x"07"; -- arty
constant sysid_vers : slv8 := x"00";
begin
CLK100_BUFG: bufg
port map (
I => I_CLK100,
O => CLK100_BUF
);
GEN_CLKALL : s7_cmt_1ce1ce2c -- clock generator system ------------
generic map (
CLKIN_PERIOD => 10.0,
CLKIN_JITTER => 0.01,
STARTUP_WAIT => false,
CLK0_VCODIV => sys_conf_clksys_vcodivide,
CLK0_VCOMUL => sys_conf_clksys_vcomultiply,
CLK0_OUTDIV => sys_conf_clksys_outdivide,
CLK0_GENTYPE => sys_conf_clksys_gentype,
CLK0_CDUWIDTH => 7,
CLK0_USECDIV => sys_conf_clksys_mhz,
CLK0_MSECDIV => 1000,
CLK1_VCODIV => sys_conf_clkser_vcodivide,
CLK1_VCOMUL => sys_conf_clkser_vcomultiply,
CLK1_OUTDIV => sys_conf_clkser_outdivide,
CLK1_GENTYPE => sys_conf_clkser_gentype,
CLK1_CDUWIDTH => 7,
CLK1_USECDIV => sys_conf_clkser_mhz,
CLK1_MSECDIV => 1000,
CLK23_VCODIV => 1,
CLK23_VCOMUL => 10, -- vco 1000 MHz
CLK2_OUTDIV => 6, -- mig sys 166.6 MHz
CLK3_OUTDIV => 5, -- mig ref 200.0 MHz
CLK23_GENTYPE => "PLL")
port map (
CLKIN => CLK100_BUF,
CLK0 => XX_CLK,
CE0_USEC => XX_CE_USEC,
CE0_MSEC => XX_CE_MSEC,
CLK1 => CLKS,
CE1_USEC => open,
CE1_MSEC => CES_MSEC,
CLK2 => CLKMIG,
CLK3 => CLKREF,
LOCKED => LOCKED
);
-- Note: CLK0 is generated as in 'normal' systems to keep PPL/MMCM setup
-- as similar as possible. The CE_USEC and CE_MSEC pulses are forwarded
-- from the 80 MHz CLK0 domain to the 83.333 MHz MIG UI_CLK domain
CDC_CEUSEC : cdc_pulse -- provide CLK side CE_USEC
generic map (
POUT_SINGLE => true,
BUSY_WACK => false)
port map (
CLKM => XX_CLK,
RESET => '0',
CLKS => CLK,
PIN => XX_CE_USEC,
BUSY => open,
POUT => CE_USEC
);
CDC_CEMSEC : cdc_pulse -- provide CLK side CE_MSEC
generic map (
POUT_SINGLE => true,
BUSY_WACK => false)
port map (
CLKM => XX_CLK,
RESET => '0',
CLKS => CLK,
PIN => XX_CE_MSEC,
BUSY => open,
POUT => CE_MSEC
);
CDC_CLKMIG_LOCKED : cdc_signal_s1_as
port map (
CLKO => CLKMIG,
DI => LOCKED,
DO => LOCKED_CLKMIG
);
IOB_RS232 : bp_rs232_2line_iob
port map (
CLK => CLKS,
RXD => RXD,
TXD => TXD,
I_RXD => I_RXD,
O_TXD => O_TXD
);
RLINK : rlink_sp2c
generic map (
BTOWIDTH => 8, -- 256 cycles, for slow mem iface
RTAWIDTH => 12,
SYSID => sysid_proj & sysid_board & sysid_vers,
IFAWIDTH => 5, -- 32 word input fifo
OFAWIDTH => 5, -- 32 word output fifo
ENAPIN_RLMON => sbcntl_sbf_rlmon,
ENAPIN_RBMON => sbcntl_sbf_rbmon,
CDWIDTH => 12,
CDINIT => sys_conf_ser2rri_cdinit,
RBMON_AWIDTH => 0,
RBMON_RBADDR => rbaddr_rbmon)
port map (
CLK => CLK,
CE_USEC => CE_USEC,
CE_MSEC => CE_MSEC,
CE_INT => CE_MSEC,
RESET => '0', -- FIXME: no RESET
CLKS => CLKS,
CES_MSEC => CES_MSEC,
ENAXON => '1',
ESCFILL => '0',
RXSD => RXD,
TXSD => TXD,
CTS_N => '0',
RTS_N => open,
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES,
RB_LAM => RB_LAM,
RB_STAT => RB_STAT,
RL_MONI => open,
SER_MONI => SER_MONI
);
TST : entity work.tst_mig
generic map (
RB_ADDR => slv(to_unsigned(2#0000000000000000#,16)),
MAWIDTH => mig_mawidth,
MWIDTH => mig_mwidth)
port map (
CLK => CLK,
CE_USEC => CE_USEC,
RESET => '0', -- FIXME: no RESET
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES_TST,
RB_STAT => RB_STAT,
RB_LAM => RB_LAM_TST,
APP_ADDR => APP_ADDR,
APP_CMD => APP_CMD,
APP_EN => APP_EN,
APP_WDF_DATA => APP_WDF_DATA,
APP_WDF_END => APP_WDF_END,
APP_WDF_MASK => APP_WDF_MASK,
APP_WDF_WREN => APP_WDF_WREN,
APP_RD_DATA => APP_RD_DATA,
APP_RD_DATA_END => APP_RD_DATA_END,
APP_RD_DATA_VALID => APP_RD_DATA_VALID,
APP_RDY => APP_RDY,
APP_WDF_RDY => APP_WDF_RDY,
APP_SR_REQ => APP_SR_REQ,
APP_REF_REQ => APP_REF_REQ,
APP_ZQ_REQ => APP_ZQ_REQ,
APP_SR_ACTIVE => APP_SR_ACTIVE,
APP_REF_ACK => APP_REF_ACK,
APP_ZQ_ACK => APP_ZQ_ACK,
MIG_UI_CLK_SYNC_RST => MIG_UI_CLK_SYNC_RST,
MIG_INIT_CALIB_COMPLETE => MIG_INIT_CALIB_COMPLETE,
MIG_DEVICE_TEMP_I => XADC_TEMP
);
MIG_CTL: migui_arty -- MIG iface -----------------
port map (
DDR3_DQ => DDR3_DQ,
DDR3_DQS_P => DDR3_DQS_P,
DDR3_DQS_N => DDR3_DQS_N,
DDR3_ADDR => DDR3_ADDR,
DDR3_BA => DDR3_BA,
DDR3_RAS_N => DDR3_RAS_N,
DDR3_CAS_N => DDR3_CAS_N,
DDR3_WE_N => DDR3_WE_N,
DDR3_RESET_N => DDR3_RESET_N,
DDR3_CK_P => DDR3_CK_P,
DDR3_CK_N => DDR3_CK_N,
DDR3_CKE => DDR3_CKE,
DDR3_CS_N => DDR3_CS_N,
DDR3_DM => DDR3_DM,
DDR3_ODT => DDR3_ODT,
APP_ADDR => APP_ADDR,
APP_CMD => APP_CMD,
APP_EN => APP_EN,
APP_WDF_DATA => APP_WDF_DATA,
APP_WDF_END => APP_WDF_END,
APP_WDF_MASK => APP_WDF_MASK,
APP_WDF_WREN => APP_WDF_WREN,
APP_RD_DATA => APP_RD_DATA,
APP_RD_DATA_END => APP_RD_DATA_END,
APP_RD_DATA_VALID => APP_RD_DATA_VALID,
APP_RDY => APP_RDY,
APP_WDF_RDY => APP_WDF_RDY,
APP_SR_REQ => APP_SR_REQ,
APP_REF_REQ => APP_REF_REQ,
APP_ZQ_REQ => APP_ZQ_REQ,
APP_SR_ACTIVE => APP_SR_ACTIVE,
APP_REF_ACK => APP_REF_ACK,
APP_ZQ_ACK => APP_ZQ_ACK,
UI_CLK => CLK,
UI_CLK_SYNC_RST => MIG_UI_CLK_SYNC_RST,
INIT_CALIB_COMPLETE => MIG_INIT_CALIB_COMPLETE,
SYS_CLK_I => CLKMIG,
CLK_REF_I => CLKREF,
DEVICE_TEMP_I => XADC_TEMP,
SYS_RST => MIG_SYS_RST
);
MIG_SYS_RST <= (not LOCKED_CLKMIG) or I_BTN(3); -- provisional !
SMRB: sysmonx_rbus_arty
generic map ( -- use default INIT_ (LP: Vccint=0.95)
CLK_MHZ => sys_conf_clksys_mhz,
RB_ADDR => rbaddr_sysmon)
port map (
CLK => CLK,
RESET => '0', -- FIXME: no RESET
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES_SYSMON,
ALM => open,
OT => open,
TEMP => XADC_TEMP,
VPWRN => A_VPWRN,
VPWRP => A_VPWRP
);
UARB : rbd_usracc
port map (
CLK => CLK,
RB_MREQ => RB_MREQ,
RB_SRES => RB_SRES_USRACC
);
RB_SRES_OR : rb_sres_or_3 -- rbus or ---------------------------
port map (
RB_SRES_1 => RB_SRES_TST,
RB_SRES_2 => RB_SRES_SYSMON,
RB_SRES_3 => RB_SRES_USRACC,
RB_SRES_OR => RB_SRES
);
proc_dim: process (CLKMIG)
begin
if rising_edge(CLKMIG) then
R_DIMCNT <= slv(unsigned(R_DIMCNT) + 1);
if unsigned(R_DIMCNT) = 0 then
R_DIMFLG <= '1';
else
R_DIMFLG <= '0';
end if;
end if;
end process proc_dim;
RB_LAM(0) <= RB_LAM_TST;
O_LED(1) <= SER_MONI.txact;
O_LED(0) <= SER_MONI.rxact;
-- red LED for serious error conditions
O_RGBLED0(0) <= R_DIMFLG and (I_BTN(0) or not LOCKED);
O_RGBLED1(0) <= R_DIMFLG and (I_BTN(0));
O_RGBLED2(0) <= R_DIMFLG and (I_BTN(0) or MIG_UI_CLK_SYNC_RST);
O_RGBLED3(0) <= R_DIMFLG and (I_BTN(0) or not MIG_INIT_CALIB_COMPLETE);
-- green LED for activity
O_RGBLED0(1) <= R_DIMFLG and (I_BTN(1));
O_RGBLED1(1) <= R_DIMFLG and (I_BTN(1));
O_RGBLED2(1) <= R_DIMFLG and (I_BTN(1) or not APP_RDY);
O_RGBLED3(1) <= R_DIMFLG and (I_BTN(1) or not APP_WDF_RDY);
-- blue LED currently unused
O_RGBLED0(2) <= R_DIMFLG and (I_BTN(2));
O_RGBLED1(2) <= R_DIMFLG and (I_BTN(2));
O_RGBLED2(2) <= R_DIMFLG and (I_BTN(2));
O_RGBLED3(2) <= R_DIMFLG and (I_BTN(2));
end syn;

View File

@@ -0,0 +1,56 @@
# $Id: sys_tst_mig_arty.vmfset 1095 2018-12-28 11:53:13Z mueller $
#
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[syn]
# general issues -----------------------------------------------
{2018.2:}
# stupid new warning, Xilinx suggests to safely ingnore
i [Constraints 18-5210] # generic
{:}
# false_path -hold ignored by synth ----------------------------
I [Designutils 20-1567] # generic
# port driven by constant --------------------------------------
# tying undriven pin to constant -------------------------------
# only few LAMs used # OK 2018-12-23
i [Synth 8-3295] RLINK:RB_LAM[\d*]
# unconnected ports --------------------------------------------
I [Synth 8-3331] RB_MREQ # generic
# --> I_SWI not used # OK 2018-12-23
i [Synth 8-3331] I_SWI[\d]
# --> O_LED only partially used # OK 2018-12-23
i [Synth 8-3331] O_LED[(2|3)]
# --> rlink_sp2c doesn't use CE_USEC and CE_MSEC # OK 2018-12-23
i [Synth 8-3331] rlink_sp2c.*CE_(USEC|MSEC)
# --> APP_SR_ACTIVE is unused (reserved port) # OK 2018-12-23
i [Synth 8-3331] APP_SR_ACTIVE
# sequential element removed (2017.1 nonsense) -----------------
I [Synth 8-6014] _reg # generic
# unused sequential element ------------------------------------
I [Synth 8-3332] R_LREGS_reg[attn][\d*] # generic
# --> usec unused # OK 2018-12-23
i [Synth 8-3332] R_REGS_reg[usec].* sys_tst_mig_arty
# --> no stat used; moneop and monattn unused # OK 2018-12-23
i [Synth 8-3332] R_BREGS_reg[stat][(0|1|2|3)].* sys_tst_mig_arty
i [Synth 8-3332] R_LREGS_reg[(moneop|monattn)].* sys_tst_mig_arty
# --> no rbinit used # OK 2018-12-27
i [Synth 8-3332] R_BREGS_reg[rbinit].* sys_tst_mig_arty
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[imp]
I [Vivado 12-2489] # multiple of 1 ps
I [Physopt 32-742] # BRAM Flop Optimization
# --> spurious Invalid VCCINTIO messages # OK 2018-11-25
{:2017.2}
i [Designutils 20-266] Invalid Voltage Source VCCINTIO
{:}
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[bit]
# see https://www.xilinx.com/support/answers/64180.html # OK 2018-12-22
i [DRC REQP-1709] PLLE2_ADV

View File

@@ -0,0 +1,2 @@
tb_tst_mig_arty
sysmon_stim

View File

@@ -0,0 +1,39 @@
# $Id: Makefile 1092 2018-12-24 08:01:50Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2018-12-23 1092 1.0 Initial version
#
EXE_all = tb_tst_mig_arty
#
include ${RETROBASE}/rtl/make_viv/viv_default_arty.mk
#
.PHONY : all all_ssim all_osim clean
.PHONY : all_XSim all_XSim_ssim all_XSim_osim all_XSim_tsim
#
all : $(EXE_all)
all_ssim : $(EXE_all:=_ssim)
all_osim : $(EXE_all:=_osim)
#
all_XSim : $(EXE_all:=_XSim)
all_XSim_ssim : $(EXE_all:=_XSim_ssim)
all_XSim_osim : $(EXE_all:=_XSim_osim)
all_XSim_tsim : $(EXE_all:=_XSim_tsim)
#
clean : viv_clean ghdl_clean xsim_clean
#
#-----
#
include ${RETROBASE}/rtl/make_viv/generic_ghdl.mk
include ${RETROBASE}/rtl/make_viv/generic_xsim.mk
include ${RETROBASE}/rtl/make_viv/generic_vivado.mk
#
VBOM_all = $(wildcard *.vbom)
#
ifndef DONTINCDEP
include $(VBOM_all:.vbom=.dep_vsyn)
include $(VBOM_all:.vbom=.dep_ghdl)
include $(VBOM_all:.vbom=.dep_vsim)
include $(wildcard *.o.dep_ghdl)
endif
#

View File

@@ -0,0 +1,57 @@
-- $Id: sys_conf_sim.vhd 1092 2018-12-24 08:01:50Z mueller $
--
-- Copyright 2018- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 3, 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 complete details.
--
------------------------------------------------------------------------------
-- Package Name: sys_conf
-- Description: Definitions for sys_tst_mig_arty (for simulation)
--
-- Dependencies: -
-- Tool versions: viv 2017.2; ghdl 0.34
-- Revision History:
-- Date Rev Version Comment
-- 2018-12-23 1092 1.0 Initial version
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.slvtypes.all;
package sys_conf is
constant sys_conf_clksys_vcodivide : positive := 1;
constant sys_conf_clksys_vcomultiply : positive := 8; -- vco 800 MHz
constant sys_conf_clksys_outdivide : positive := 10; -- sys 80 MHz
constant sys_conf_clksys_gentype : string := "MMCM";
-- dual clock design, clkser = 120 MHz
constant sys_conf_clkser_vcodivide : positive := 1;
constant sys_conf_clkser_vcomultiply : positive := 12; -- vco 1200 MHz
constant sys_conf_clkser_outdivide : positive := 10; -- sys 120 MHz
constant sys_conf_clkser_gentype : string := "PLL";
-- configure rlink and hio interfaces --------------------------------------
constant sys_conf_ser2rri_cdinit : integer := 1-1; -- 1 cycle/bit in sim
-- derived constants
constant sys_conf_clksys : integer :=
((12000000/sys_conf_clksys_vcodivide)*sys_conf_clksys_vcomultiply) /
sys_conf_clksys_outdivide;
constant sys_conf_clksys_mhz : integer := sys_conf_clksys/1000000;
constant sys_conf_clkser : integer :=
((12000000/sys_conf_clkser_vcodivide)*sys_conf_clkser_vcomultiply) /
sys_conf_clkser_outdivide;
constant sys_conf_clkser_mhz : integer := sys_conf_clkser/1000000;
end package sys_conf;

View File

@@ -0,0 +1,9 @@
# configure tb_arty_dram with sys_tst_mig_arty target;
# use vhdl configure file (tb_tst_mig_arty.vhd) to allow
# that all configurations will co-exist in work library
# configure
arty_dram_aif = ../sys_tst_mig_arty.vbom
sys_conf = sys_conf_sim.vhd
# design
../../../../bplib/arty/tb/tb_arty_dram.vbom
tb_tst_mig_arty.vhd

View File

@@ -0,0 +1,35 @@
-- $Id: tb_tst_mig_arty.vhd 1092 2018-12-24 08:01:50Z mueller $
--
-- Copyright 2018- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 3, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: tb_tst_mig_arty
-- Description: Configuration for tb_tst_mig_arty for tb_arty_dram
--
-- Dependencies: sys_tst_mig_arty
--
-- To test: sys_tst_mig_arty
--
-- Revision History:
-- Date Rev Version Comment
-- 2018-12-23 1092 1.0 Initial version
------------------------------------------------------------------------------
configuration tb_tst_mig_arty of tb_arty_dram is
for sim
for all : arty_dram_aif
use entity work.sys_tst_mig_arty;
end for;
end for;
end tb_tst_mig_arty;

View File

@@ -0,0 +1,13 @@
# $Id: tbrun.yml 1092 2018-12-24 08:01:50Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2018-12-23 1092 1.0 Initial version
#
- default:
mode: ${viv_modes}
#
- tag: [default, viv, sys_tst_mig, arty, base]
test: |
tbrun_tbwrri --hxon --lsuf base --pack tst_mig tb_tst_mig_arty${ms} \
tst_mig::setup tst_mig::test_all

View File

@@ -0,0 +1,7 @@
# $Id: tbw.dat 1092 2018-12-24 08:01:50Z mueller $
#
[tb_tst_mig_arty]
rlink_cext_fifo_rx = <fifo>
rlink_cext_fifo_tx = <fifo>
rlink_cext_conf = <null>
sysmon_stim = ../../../../bplib/sysmon/tb/sysmon_stim_arty.dat

View File

@@ -0,0 +1,7 @@
# $Id: tbrun.yml 1092 2018-12-24 08:01:50Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2018-12-23 1092 1.0 Initial version
#
- include: arty/tb/tbrun.yml

View File

@@ -0,0 +1,8 @@
# libs
../../vlib/slvtypes.vhd
../../vlib/rutil.vhd
../../vlib/rbus/rblib.vhd
${sys_conf}
# components
# design
tst_mig.vhd

View File

@@ -0,0 +1,683 @@
-- $Id: tst_mig.vhd 1096 2018-12-29 07:54:17Z mueller $
--
-- Copyright 2018- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- Software Foundation, either version 3, 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 complete details.
--
------------------------------------------------------------------------------
-- Module Name: tst_mig - syn
-- Description: test of mig
--
-- Dependencies: -
--
-- Test bench: arty/tb/tb_tst_mig_arty (with ddr3 via mig)
--
-- Target Devices: generic
-- Tool versions: viv 2017.2; ghdl 0.34
--
-- Revision History:
-- Date Rev Version Comment
-- 2018-12-28 1096 1.0 Initial version
-- 2018-12-23 1092 0.1 First draft
------------------------------------------------------------------------------
--
-- rbus registers:
--
-- Addr Bits Name r/w/f Function
-- 00000 cntl -/-/f Control register
-- 15:13 cmd 0/w/- commmand code for func=cmd
-- 12 wren 0/w/- wren option for func=cmd
-- 11 dwend 0/w/- disable wend for func=cmd,wren
-- 03:00 func 0/-/f function command
-- 0000 noop
-- 0001 rd read memory
-- 0010 wr write memory
-- 0011 pat sample rdy pattern
-- 0100 ref refresh
-- 0101 cal ZQ cal
-- 0110 cmd send command to mem
-- 0111 wren send wren strobe to mem
-- 00001 stat r/-/- Status register
-- 06 zqpend r/-/- ZQ cal req pending
-- 05 refpend r/-/- refresh req pending
-- 04 rdend r/-/- RD_DATA_END seen
-- 03 uirst r/-/- reset from ui
-- 02 caco r/-/- calibration complete
-- 01 wrdy r/-/- write ready
-- 00 crdy r/-/- cmd ready
-- 00010 conf r/-/- Configuration register
-- 9:05 mawidth r/-/- MAWIDTH
-- 4:00 mwidth r/-/- MWIDTH
-- 00011 15:00 mask r/w/- Mask register
-- 00100 15:00 addrl r/w/- Address register (low part)
-- 00101 15:00 addrh r/w/- Address register (high part)
-- 00110 15:00 temp r/-/- Device temperature
-- 00111 15:00 dvalcnt r/-/- Data valid counter
-- 01000 15:00 crpat r/-/- Command ready pattern
-- 01001 15:00 wrpat r/-/- Write ready pattern
-- 01010 15:00 cwait r/-/- Command wait
-- 01011 15:00 rwait r/-/- Read wait
-- 01100 15:00 xwait r/-/- Request wait
-- 01101 ircnt r/-/- Init/Reset count
-- 15:08 rstcnt r/-/- reset count
-- 7:00 inicnt r/-/- init count
-- 01110 15:00 rsttime r/-/- length of last reset
-- 01111 15:00 initime r/-/- length of last init
-- 10xxx datrd[0-7] r/-/- Data read register
-- 11xxx datwr[0-7] r/w/- Data write register
-- ----------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.slvtypes.all;
use work.rutil.all;
use work.memlib.all;
use work.rblib.all;
-- ----------------------------------------------------------------------------
entity tst_mig is -- tester for mig
generic (
RB_ADDR : slv16 := slv(to_unsigned(2#0000000000000000#,16));
MAWIDTH : natural := 28;
MWIDTH : natural := 16);
port (
CLK : in slbit; -- clock
CE_USEC : in slbit; -- usec pulse
RESET : in slbit; -- reset
RB_MREQ : in rb_mreq_type; -- rbus: request
RB_SRES : out rb_sres_type; -- rbus: response
RB_STAT : out slv4; -- rbus: status flags
RB_LAM : out slbit; -- remote attention
APP_ADDR : out slv(MAWIDTH-1 downto 0); -- MIGUI address
APP_CMD : out slv3; -- MIGUI command
APP_EN : out slbit; -- MIGUI command enable
APP_WDF_DATA : out slv(8*MWIDTH-1 downto 0);-- MIGUI write data
APP_WDF_END : out slbit; -- MIGUI write end
APP_WDF_MASK : out slv(MWIDTH-1 downto 0); -- MIGUI write mask
APP_WDF_WREN : out slbit; -- MIGUI write enable
APP_RD_DATA : in slv(8*MWIDTH-1 downto 0);-- MIGUI read data
APP_RD_DATA_END : in slbit; -- MIGUI read end
APP_RD_DATA_VALID : in slbit; -- MIGUI read valid
APP_RDY : in slbit; -- MIGUI ready for cmd
APP_WDF_RDY : in slbit; -- MIGUI ready for data write
APP_SR_REQ : out slbit; -- MIGUI reserved (tie to 0)
APP_REF_REQ : out slbit; -- MIGUI refresh request
APP_ZQ_REQ : out slbit; -- MIGUI ZQ calibrate request
APP_SR_ACTIVE : in slbit; -- MIGUI reserved (ignore)
APP_REF_ACK : in slbit; -- MIGUI refresh acknowledge
APP_ZQ_ACK : in slbit; -- MIGUI ZQ calibrate acknowledge
MIG_UI_CLK_SYNC_RST : in slbit; -- MIGUI reset
MIG_INIT_CALIB_COMPLETE : in slbit; -- MIGUI calibration done
MIG_DEVICE_TEMP_I : in slv12 -- MIGUI xadc temperature
);
end tst_mig;
architecture syn of tst_mig is
type state_type is (
s_idle, -- s_idle: wait for input
s_rdcwait, -- s_rdcwait: read cmd wait
s_rdrwait, -- s_rdrwait: read res wait
s_wrcwait, -- s_wrcwait: write cmd wait
s_cmdwait, -- s_cmdwait: cmd wait
s_wrenwait -- s_wrenwait: wren wait
);
type regs_type is record
state : state_type; -- state
rbsel : slbit; -- rbus select
mask : slv16; -- memory mask
addr : slv32; -- memory address
datrd : slv(127 downto 0); -- memory data read
datwr : slv(127 downto 0); -- memory data write
dvalcnt : slv16; -- data valid counter
crpat : slv16; -- command ready pattern
wrpat : slv16; -- write ready pattern
cwait : slv16; -- command wait counter
rwait : slv16; -- read wait counter
xwait : slv16; -- request wait counter
rstcnt : slv8; -- reset counter
inicnt : slv8; -- init counter
rsttime : slv16; -- reset time counter
initime : slv16; -- init time counter
crsreg : slv15; -- command ready shift register
wrsreg : slv15; -- write ready shift register
rdend : slbit; -- RD_DATA_END capture
refpend : slbit; -- ref req pending
zqpend : slbit; -- zq req pending
caco_1 : slbit; -- last caco
uirst_1 : slbit; -- last uirst
end record regs_type;
constant regs_init : regs_type := (
s_idle, -- state
'0', -- rbsel
(others=>'0'), -- mask
(others=>'0'), -- addr
(others=>'0'), -- datrd
(others=>'0'), -- datwr
(others=>'0'), -- dvalcnt
(others=>'0'), -- crpat
(others=>'0'), -- wrpat
(others=>'0'), -- cwait
(others=>'0'), -- rwait
(others=>'0'), -- xwait
(others=>'0'), -- rstcnt
(others=>'0'), -- inicnt
(others=>'0'), -- rsttime
(others=>'0'), -- initime
(others=>'0'), -- crsreg
(others=>'0'), -- wrsreg
'0','0','0', -- rdend,refpend,zqpend
'0','0' -- caco_1,uirst_1
);
signal R_REGS : regs_type := regs_init;
signal N_REGS : regs_type; -- don't init (vivado fix for fsm infer)
constant rbaddr_cntl: slv5 := "00000"; -- 0 -/-/f
constant rbaddr_stat: slv5 := "00001"; -- 1 r/-/-
constant rbaddr_conf: slv5 := "00010"; -- 2 r/-/-
constant rbaddr_mask: slv5 := "00011"; -- 3 r/w/-
constant rbaddr_addrl: slv5 := "00100"; -- 4 r/w/-
constant rbaddr_addrh: slv5 := "00101"; -- 5 r/w/-
constant rbaddr_temp: slv5 := "00110"; -- 6 r/-/-
constant rbaddr_dvalcnt: slv5 := "00111"; -- 7 r/-/-
constant rbaddr_crpat: slv5 := "01000"; -- 8 r/-/-
constant rbaddr_wrpat: slv5 := "01001"; -- 9 r/-/-
constant rbaddr_cwait: slv5 := "01010"; -- 10 r/-/-
constant rbaddr_rwait: slv5 := "01011"; -- 11 r/-/-
constant rbaddr_xwait: slv5 := "01100"; -- 12 r/-/-
constant rbaddr_ircnt: slv5 := "01101"; -- 13 r/-/-
constant rbaddr_rsttime: slv5 := "01110"; -- 14 r/-/-
constant rbaddr_initime: slv5 := "01111"; -- 15 r/-/-
constant rbaddr_datrd0: slv5 := "10000"; -- 16 r/-/-
constant rbaddr_datrd1: slv5 := "10001"; -- 17 r/-/-
constant rbaddr_datrd2: slv5 := "10010"; -- 18 r/-/-
constant rbaddr_datrd3: slv5 := "10011"; -- 19 r/-/-
constant rbaddr_datrd4: slv5 := "10100"; -- 20 r/-/-
constant rbaddr_datrd5: slv5 := "10101"; -- 21 r/-/-
constant rbaddr_datrd6: slv5 := "10110"; -- 22 r/-/-
constant rbaddr_datrd7: slv5 := "10111"; -- 23 r/-/-
constant rbaddr_datwr0: slv5 := "11000"; -- 14 r/w/-
constant rbaddr_datwr1: slv5 := "11001"; -- 15 r/w/-
constant rbaddr_datwr2: slv5 := "11010"; -- 16 r/w/-
constant rbaddr_datwr3: slv5 := "11011"; -- 17 r/w/-
constant rbaddr_datwr4: slv5 := "11100"; -- 28 r/w/-
constant rbaddr_datwr5: slv5 := "11101"; -- 29 r/w/-
constant rbaddr_datwr6: slv5 := "11110"; -- 30 r/w/-
constant rbaddr_datwr7: slv5 := "11111"; -- 31 r/w/-
subtype cntl_rbf_cmd is integer range 15 downto 13;
constant cntl_rbf_wren : integer := 12;
constant cntl_rbf_dwend : integer := 11;
subtype cntl_rbf_func is integer range 3 downto 0;
constant stat_rbf_zqpend : integer := 6;
constant stat_rbf_refpend : integer := 5;
constant stat_rbf_rdend : integer := 4;
constant stat_rbf_uirst : integer := 3;
constant stat_rbf_caco : integer := 2;
constant stat_rbf_wrdy : integer := 1;
constant stat_rbf_crdy : integer := 0;
subtype conf_rbf_mawidth is integer range 9 downto 5;
subtype conf_rbf_mwidth is integer range 4 downto 0;
subtype ircnt_rbf_rstcnt is integer range 15 downto 8;
subtype ircnt_rbf_inicnt is integer range 7 downto 0;
constant func_noop : slv4 := "0000"; -- func: noop
constant func_rd : slv4 := "0001"; -- func: rd read memory
constant func_wr : slv4 := "0010"; -- func: wr write memory
constant func_pat : slv4 := "0011"; -- func: pat sample rdy pattern
constant func_ref : slv4 := "0100"; -- func: ref refresh
constant func_cal : slv4 := "0101"; -- func: cal ZQ cal
constant func_cmd : slv4 := "0110"; -- func: cmd send command to mem
constant func_wren : slv4 := "0111"; -- func: wren send wren strobe to mem
subtype df_word0 is integer range 15 downto 0;
subtype df_word1 is integer range 31 downto 16;
subtype df_word2 is integer range 47 downto 32;
subtype df_word3 is integer range 63 downto 48;
subtype df_word4 is integer range 79 downto 64;
subtype df_word5 is integer range 95 downto 80;
subtype df_word6 is integer range 111 downto 96;
subtype df_word7 is integer range 127 downto 112;
constant migui_cmd_read : slv3 := "001";
constant migui_cmd_write : slv3 := "000";
begin
assert MAWIDTH <= 32
report "assert(MAWIDTH <= 32): unsupported MAWIDTH"
severity failure;
assert MWIDTH = 8 or MWIDTH = 16
report "assert(MWIDTH = 8 or 16): unsupported MWIDTH"
severity failure;
proc_regs: process (CLK)
begin
if rising_edge(CLK) then
if RESET = '1' then
R_REGS <= regs_init;
else
R_REGS <= N_REGS;
end if;
end if;
end process proc_regs;
proc_next: process (R_REGS, RB_MREQ, CE_USEC,
APP_RD_DATA, APP_RD_DATA_END, APP_RD_DATA_VALID,
APP_RDY, APP_WDF_RDY, APP_REF_ACK, APP_ZQ_ACK,
MIG_UI_CLK_SYNC_RST, MIG_INIT_CALIB_COMPLETE,
MIG_DEVICE_TEMP_I)
variable r : regs_type := regs_init;
variable n : regs_type := regs_init;
variable irb_ack : slbit := '0';
variable irb_busy : slbit := '0';
variable irb_err : slbit := '0';
variable irb_dout : slv16 := (others=>'0');
variable irbena : slbit := '0'; -- re or we -> rbus request
variable iappcmd : slv3 := (others=>'0');
variable iappen : slbit := '0';
variable iappwren : slbit := '0';
variable iappwend : slbit := '0';
variable iappref : slbit := '0';
variable iappzq : slbit := '0';
variable ncrpat : slv16 := (others=>'0');
variable nwrpat : slv16 := (others=>'0');
begin
r := R_REGS;
n := R_REGS;
irb_ack := '0';
irb_busy := '0';
irb_err := '0';
irb_dout := (others=>'0');
iappcmd := migui_cmd_read;
iappen := '0';
iappwren := '0';
iappwend := '0';
iappref := '0';
iappzq := '0';
ncrpat := r.crsreg & APP_RDY; -- current ready patterns
nwrpat := r.wrsreg & APP_WDF_RDY;
irbena := RB_MREQ.re or RB_MREQ.we;
-- rbus address decoder
n.rbsel := '0';
if RB_MREQ.aval='1' and RB_MREQ.addr(15 downto 5)=RB_ADDR(15 downto 5) then
n.rbsel := '1';
end if;
if r.rbsel='1' and irbena='1' then
irb_ack := '1'; -- ack all (maybe rejected later)
end if;
case r.state is
when s_idle => -- s_idle: ---------------------------
-- rbus transactions
if r.rbsel = '1' then
case RB_MREQ.addr(4 downto 0) is
when rbaddr_cntl => -- cntl ---------------
if RB_MREQ.we = '1' then
case RB_MREQ.din(cntl_rbf_func) is
when func_noop => null; -- func: noop -----
when func_rd => -- func: rd -------
n.rdend := '0';
n.cwait := (others=>'0');
n.rwait := (others=>'0');
irb_busy := '1';
n.state := s_rdcwait;
when func_wr => -- func: wr -------
n.cwait := (others=>'0');
n.rwait := (others=>'0');
irb_busy := '1';
n.state := s_wrcwait;
when func_pat => -- func: pat ------
n.crpat := ncrpat;
n.wrpat := nwrpat;
when func_ref => -- func: ref ------
n.xwait := (others=>'0');
if r.refpend = '0' then
n.refpend := '1';
iappref := '1';
else
irb_err := '1';
end if;
when func_cal => -- func: cal ------
n.xwait := (others=>'0');
if r.zqpend = '0' then
n.zqpend := '1';
iappzq := '1';
else
irb_err := '1';
end if;
when func_cmd => -- func: cmd ------
n.cwait := (others=>'0');
n.rwait := (others=>'0');
irb_busy := '1';
n.state := s_cmdwait;
when func_wren => -- func: wren -----
n.cwait := (others=>'0');
n.rwait := (others=>'0');
irb_busy := '1';
n.state := s_wrenwait;
when others => -- <> not yet defined codes
irb_err := '1';
end case;
end if;
when rbaddr_stat => irb_err := RB_MREQ.we;
when rbaddr_conf => irb_err := RB_MREQ.we;
when rbaddr_mask => -- mask ---------------
if RB_MREQ.we = '1' then
n.mask := RB_MREQ.din;
end if;
when rbaddr_addrl => -- addrl --------------
if RB_MREQ.we = '1' then n.addr(df_word0) := RB_MREQ.din; end if;
when rbaddr_addrh => -- addrh --------------
if RB_MREQ.we = '1' then n.addr(df_word1) := RB_MREQ.din; end if;
when rbaddr_temp => irb_err := RB_MREQ.we;
when rbaddr_dvalcnt => irb_err := RB_MREQ.we;
when rbaddr_crpat => irb_err := RB_MREQ.we;
when rbaddr_wrpat => irb_err := RB_MREQ.we;
when rbaddr_cwait => irb_err := RB_MREQ.we;
when rbaddr_rwait => irb_err := RB_MREQ.we;
when rbaddr_xwait => irb_err := RB_MREQ.we;
when rbaddr_ircnt => irb_err := RB_MREQ.we;
when rbaddr_rsttime => irb_err := RB_MREQ.we;
when rbaddr_initime => irb_err := RB_MREQ.we;
when rbaddr_datrd0|rbaddr_datrd1| -- datrd* ----------------
rbaddr_datrd2|rbaddr_datrd3|
rbaddr_datrd4|rbaddr_datrd5|
rbaddr_datrd6|rbaddr_datrd7 => irb_err := RB_MREQ.we;
when rbaddr_datwr0 => -- datwr* ----------------
if RB_MREQ.we = '1' then n.datwr(df_word0) := RB_MREQ.din; end if;
when rbaddr_datwr1 =>
if RB_MREQ.we = '1' then n.datwr(df_word1) := RB_MREQ.din; end if;
when rbaddr_datwr2 =>
if RB_MREQ.we = '1' then n.datwr(df_word2) := RB_MREQ.din; end if;
when rbaddr_datwr3 =>
if RB_MREQ.we = '1' then n.datwr(df_word3) := RB_MREQ.din; end if;
when rbaddr_datwr4 =>
if RB_MREQ.we = '1' then n.datwr(df_word4) := RB_MREQ.din; end if;
when rbaddr_datwr5 =>
if RB_MREQ.we = '1' then n.datwr(df_word5) := RB_MREQ.din; end if;
when rbaddr_datwr6 =>
if RB_MREQ.we = '1' then n.datwr(df_word6) := RB_MREQ.din; end if;
when rbaddr_datwr7 =>
if RB_MREQ.we = '1' then n.datwr(df_word7) := RB_MREQ.din; end if;
when others => -- <> --------------------
irb_ack := '0';
end case;
end if;
when s_rdcwait => -- s_rdcwait -------------------------
iappcmd := migui_cmd_read; -- setup cmd
n.crpat := ncrpat; -- follow RDY patterns
n.wrpat := nwrpat;
if r.rbsel='0' or irbena='0' then -- rbus cycle abort
n.state := s_idle;
else
if APP_RDY = '1' then
iappen := '1';
irb_busy := '1';
n.state := s_rdrwait;
else
n.cwait := slv(unsigned(r.cwait) + 1);
irb_busy := '1';
end if;
end if;
when s_rdrwait => -- s_rdrwait -------------------------
n.rwait := slv(unsigned(r.rwait) + 1);
if r.rbsel='0' or irbena='0' then -- rbus cycle abort
n.state := s_idle;
else
if APP_RD_DATA_VALID = '1' then
n.state := s_idle;
else
irb_busy := '1';
end if;
end if;
when s_wrcwait => -- s_wrcwait -------------------------
iappcmd := migui_cmd_write; -- setup cmd
n.crpat := ncrpat; -- follow RDY patterns
n.wrpat := nwrpat;
if r.rbsel='0' or irbena='0' then -- rbus cycle abort
n.state := s_idle;
else
if APP_RDY = '1' and APP_WDF_RDY = '1' then
iappen := '1';
iappwren := '1';
iappwend := '1';
n.state := s_idle;
else
n.cwait := slv(unsigned(r.cwait) + 1);
irb_busy := '1';
end if;
end if;
when s_cmdwait => -- s_cmdwait -------------------------
iappcmd := RB_MREQ.din(cntl_rbf_cmd); -- setup cmd
n.crpat := ncrpat; -- follow RDY pattern
if r.rbsel='0' or irbena='0' then -- rbus cycle abort
n.state := s_idle;
else
if APP_RDY = '1' then
iappen := '1';
iappwren := RB_MREQ.din(cntl_rbf_wren);
iappwend := RB_MREQ.din(cntl_rbf_wren) and
not RB_MREQ.din(cntl_rbf_dwend);
n.state := s_idle;
else
n.cwait := slv(unsigned(r.cwait) + 1);
irb_busy := '1';
end if;
end if;
when s_wrenwait => -- s_wrenwait ------------------------
n.wrpat := nwrpat; -- follow RDY pattern
if r.rbsel='0' or irbena='0' then -- rbus cycle abort
n.state := s_idle;
else
if APP_WDF_RDY = '1' then
iappwren := '1';
iappwend := not RB_MREQ.din(cntl_rbf_dwend);
n.state := s_idle;
else
n.cwait := slv(unsigned(r.cwait) + 1);
irb_busy := '1';
end if;
end if;
when others => null;
end case;
-- rbus output driver
if r.rbsel = '1' then
case RB_MREQ.addr(4 downto 0) is
when rbaddr_stat =>
irb_dout(stat_rbf_zqpend) := r.zqpend;
irb_dout(stat_rbf_refpend) := r.refpend;
irb_dout(stat_rbf_rdend) := r.rdend;
irb_dout(stat_rbf_uirst) := MIG_UI_CLK_SYNC_RST;
irb_dout(stat_rbf_caco) := MIG_INIT_CALIB_COMPLETE;
irb_dout(stat_rbf_wrdy) := APP_WDF_RDY;
irb_dout(stat_rbf_crdy) := APP_RDY;
when rbaddr_conf =>
irb_dout(conf_rbf_mawidth) := slv(to_unsigned(MAWIDTH,5));
irb_dout(conf_rbf_mwidth) := slv(to_unsigned(MWIDTH,5));
when rbaddr_mask => irb_dout := r.mask;
when rbaddr_addrl => irb_dout := r.addr(df_word0);
when rbaddr_addrh => irb_dout := r.addr(df_word1);
when rbaddr_temp =>
irb_dout(MIG_DEVICE_TEMP_I'range) := MIG_DEVICE_TEMP_I;
when rbaddr_dvalcnt => irb_dout := r.dvalcnt;
when rbaddr_crpat => irb_dout := r.crpat;
when rbaddr_wrpat => irb_dout := r.wrpat;
when rbaddr_cwait => irb_dout := r.cwait;
when rbaddr_rwait => irb_dout := r.rwait;
when rbaddr_xwait => irb_dout := r.xwait;
when rbaddr_ircnt =>
irb_dout(ircnt_rbf_rstcnt) := r.rstcnt;
irb_dout(ircnt_rbf_inicnt) := r.inicnt;
when rbaddr_rsttime => irb_dout := r.rsttime;
when rbaddr_initime => irb_dout := r.initime;
when rbaddr_datrd0 => irb_dout := r.datrd(df_word0);
when rbaddr_datrd1 => irb_dout := r.datrd(df_word1);
when rbaddr_datrd2 => irb_dout := r.datrd(df_word2);
when rbaddr_datrd3 => irb_dout := r.datrd(df_word3);
when rbaddr_datrd4 => irb_dout := r.datrd(df_word4);
when rbaddr_datrd5 => irb_dout := r.datrd(df_word5);
when rbaddr_datrd6 => irb_dout := r.datrd(df_word6);
when rbaddr_datrd7 => irb_dout := r.datrd(df_word7);
when rbaddr_datwr0 => irb_dout := r.datwr(df_word0);
when rbaddr_datwr1 => irb_dout := r.datwr(df_word1);
when rbaddr_datwr2 => irb_dout := r.datwr(df_word2);
when rbaddr_datwr3 => irb_dout := r.datwr(df_word3);
when rbaddr_datwr4 => irb_dout := r.datwr(df_word4);
when rbaddr_datwr5 => irb_dout := r.datwr(df_word5);
when rbaddr_datwr6 => irb_dout := r.datwr(df_word6);
when rbaddr_datwr7 => irb_dout := r.datwr(df_word7);
when others => null;
end case;
end if;
-- update ready shift registers
n.crsreg := ncrpat(n.crsreg'range);
n.wrsreg := nwrpat(n.wrsreg'range);
-- ready data capture
if APP_RD_DATA_VALID = '1' then
n.rdend := APP_RD_DATA_END;
n.datrd(APP_RD_DATA'range) := APP_RD_DATA;
n.dvalcnt := slv(unsigned(r.dvalcnt) + 1);
end if;
-- REF and ZQ handling
if r.refpend = '1' or r.zqpend = '1' then
n.xwait := slv(unsigned(r.xwait) + 1);
end if;
if APP_REF_ACK = '1' then -- REF done
n.refpend := '0';
n.crpat := ncrpat; -- record RDY patterns too
n.wrpat := nwrpat;
end if;
if APP_ZQ_ACK = '1' then -- ZQ done
n.zqpend := '0';
n.crpat := ncrpat; -- record RDY patterns too
n.wrpat := nwrpat;
end if;
-- CACO monitor (length in CE_USEC)
n.caco_1 := MIG_INIT_CALIB_COMPLETE;
if MIG_INIT_CALIB_COMPLETE = '0' then
if r.caco_1 = '1' then
n.initime := (others => '0');
if r.inicnt /= x"ff" then
n.inicnt := slv(unsigned(r.inicnt) + 1);
end if;
else
if r.initime /= x"ffff" then
if CE_USEC = '1' then
n.initime := slv(unsigned(r.initime) + 1);
end if;
end if;
end if;
end if;
-- UIRST monitor (length in CE_USC)
n.uirst_1 := MIG_UI_CLK_SYNC_RST;
if MIG_UI_CLK_SYNC_RST = '1' then
if r.uirst_1 = '0' then
n.rsttime := (others => '0');
if r.rstcnt /= x"ff" then
n.rstcnt := slv(unsigned(r.rstcnt) + 1);
end if;
else
if r.rsttime /= x"ffff" then
if CE_USEC = '1' then
n.rsttime := slv(unsigned(r.rsttime) + 1);
end if;
end if;
end if;
end if;
N_REGS <= n;
RB_SRES <= rb_sres_init;
RB_SRES.ack <= irb_ack;
RB_SRES.busy <= irb_busy;
RB_SRES.err <= irb_err;
RB_SRES.dout <= irb_dout;
RB_LAM <= '0';
APP_ADDR <= r.addr(APP_ADDR'range);
APP_CMD <= iappcmd;
APP_EN <= iappen;
APP_WDF_DATA <= r.datwr(APP_WDF_DATA'range);
APP_WDF_END <= iappwend;
APP_WDF_MASK <= r.mask(APP_WDF_MASK'range);
APP_WDF_WREN <= iappwren;
APP_REF_REQ <= iappref;
APP_ZQ_REQ <= iappzq;
APP_SR_REQ <= '0';
end process proc_next;
RB_STAT(3) <= '0';
RB_STAT(2) <= '0';
RB_STAT(1) <= '0';
RB_STAT(0) <= '0';
end syn;

View File

@@ -1,4 +1,4 @@
-- $Id: tst_sram.vhd 984 2018-01-02 20:56:27Z mueller $
-- $Id: tst_sram.vhd 1092 2018-12-24 08:01:50Z mueller $
--
-- Copyright 2007-2017 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
@@ -17,9 +17,9 @@
--
-- Dependencies: vlib/memlib/ram_1swsr_wfirst_gen
-- vlib/memlib/ram_2swsr_wfirst_gen
-- vlib/rlink/rlink_base_serport
--
-- Test bench: cmoda7/tb/tb_tst_sram_c7 (with sram)
-- Test bench: arty/tb/tb_tst_sram_arty (with ddr3 via mig)
-- cmoda7/tb/tb_tst_sram_c7 (with sram)
-- nexys4/tb/tb_tst_sram_n4 (with cram)
-- nexys3/tb/tb_tst_sram_n3 (with cram)
-- nexys2/tb/tb_tst_sram_n2 (with cram)

View File

@@ -1,7 +1,8 @@
# $Id: tbrun.yml 913 2017-06-13 20:18:49Z mueller $
# $Id: tbrun.yml 1098 2018-12-30 11:40:42Z mueller $
#
# Revision History:
# Date Rev Version Comment
# 2018-12-30 1097 1.0.1 add tst_mig
# 2016-08-27 802 1.0 Initial version
#
- include: rtl/vlib/comlib/tb/tbrun.yml
@@ -16,5 +17,6 @@
- include: rtl/sys_gen/tst_serloop/tbrun.yml
- include: rtl/sys_gen/tst_rlink/tbrun.yml
- include: rtl/sys_gen/tst_rlink_cuff/tbrun.yml
- include: rtl/sys_gen/tst_mig/tbrun.yml
- include: rtl/sys_gen/tst_sram/tbrun.yml
- include: rtl/sys_gen/w11a/tbrun.yml

View File

@@ -1,5 +1,5 @@
#! /usr/bin/env tclshcpp
# $Id: setup_packages 1053 2018-10-06 20:34:52Z mueller $
# $Id: setup_packages 1093 2018-12-25 19:52:53Z mueller $
#
# pkg_mkIndex uses tclLog to write, which by default writes to stderr
# this is 'make -s' unfriendly, so redefined tclLog to use plain puts
@@ -36,5 +36,6 @@ pkg_mkIndex -verbose ibd_rk11 *.tcl
pkg_mkIndex -verbose ibd_rl11 *.tcl
pkg_mkIndex -verbose ibd_tm11 *.tcl
#
pkg_mkIndex -verbose tst_mig *.tcl
pkg_mkIndex -verbose tst_rlink *.tcl
pkg_mkIndex -verbose tst_sram *.tcl

View File

@@ -0,0 +1,40 @@
# $Id: test_all.tcl 1094 2018-12-27 15:18:27Z mueller $
#
# Copyright 2018- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
# This program is free software; you may redistribute and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3, 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 complete details.
#
# Revision History:
# Date Rev Version Comment
# 2018-12-27 1094 1.0 Initial version
#
package provide tst_mig 1.0
package require rutiltpp
package require rutil
package require rlink
namespace eval tst_mig {
#
# test_all: Driver for all tst_mig tests
#
proc test_all {{tout 10.}} {
#
set errcnt 0
tst_mig::setup
incr errcnt [test_regs]
incr errcnt [test_mem]
puts "tst_mig::test_all errcnt = $errcnt --> [rutil::errcnt2txt $errcnt]"
return $errcnt
}
}

View File

@@ -0,0 +1,103 @@
# $Id: test_mem.tcl 1096 2018-12-29 07:54:17Z mueller $
#
# Copyright 2018- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
# This program is free software; you may redistribute and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3, 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 complete details.
#
# Revision History:
# Date Rev Version Comment
# 2018-12-28 1096 1.0 Initial version
#
package provide tst_mig 1.0
package require rutiltpp
package require rutil
package require rlink
namespace eval tst_mig {
#
# test_regs: Test register access
#
proc test_mem {} {
variable mwidth
#
set errcnt 0
rlc errcnt -clear
#
rlc log "tst_mig::test_mem ----------------------------------------------"
rlc log " test 1: check memory status: pend,uirst=0 and caco=1"
rlc exec \
-rreg mt.stat -edata [regbld tst_mig::STAT caco] \
[regbld tst_mig::STAT zqpend refpend uirst caco]
#
#-------------------------------------------------------------------------
rlc log " test 2: basic write read back"
set dat0 {0x0000 0x0001 0x0002 0x0003}
set dat1 {0x0100 0x0101 0x0102 0x0103}
set dat2 {0x0200 0x0201 0x0202 0x0203}
if {[iswide]} {
lappend dat0 0x0004 0x0005 0x0006 0x0007
lappend dat1 0x0104 0x0105 0x0106 0x0107
lappend dat2 0x0204 0x0205 0x0206 0x0207
}
write 0x0000 $dat0
write 0x0010 $dat1
write 0x8020 $dat2
readck 0x0000 $dat0
readck 0x0010 $dat1
readck 0x8020 $dat2
#
#-------------------------------------------------------------------------
rlc log " test 3: masked write and read back"
set datr {0x0200 0x0201 0x0202 0x0203}
set datw {0xf0e0 0xf1e1 0xf2e2 0xf3e3}
if {[iswide]} {
lappend datr 0x0204 0x0205 0x0206 0x0207
lappend datw 0xf4e4 0xf5e5 0xf6e6 0xf7e7
}
write 0x8020 $datw 0xffff; # mask = ffff (all disabled)
readck 0x8020 $datr
set mask 0xfffe; # first byte enabled, others masked off
for {set iw 0} {$iw < $mwidth/2} {incr iw} {
set wold [lindex $datr $iw]
set wmod [lindex $datw $iw]
lset datr $iw [expr {($wold & 0xff00) | ($wmod & 0x00ff)}]
write 0x8020 $datw $mask; # overwrite low byte
readck 0x8020 $datr
lset datr $iw $wmod
set mask [expr {($mask<<1) & 0xffff}]
write 0x8020 $datw $mask; # overwrite high byte
readck 0x8020 $datr
set mask [expr {($mask<<1) & 0xffff}]
}
#
#-------------------------------------------------------------------------
rlc log " test 4: REF and CAL functions; show latencies"
rlc exec \
-rreg mt.rwait rwait \
-wreg mt.cntl [regbld tst_mig::CNTL {func "REF"}]
rlc exec \
-rreg mt.stat -edata 0x0 [regbld tst_mig::STAT zqpend refpend] \
-rreg mt.xwait refwait \
-wreg mt.cntl [regbld tst_mig::CNTL {func "CAL"}]
rlc exec \
-rreg mt.stat -edata 0x0 [regbld tst_mig::STAT zqpend refpend] \
-rreg mt.xwait calwait
rlc log [format " # rwait: %2d refwait: %2d calwait: %2d" \
$rwait $refwait $calwait]
#
#-------------------------------------------------------------------------
incr errcnt [rlc errcnt -clear]
return $errcnt
}
}

View File

@@ -0,0 +1,129 @@
# $Id: test_regs.tcl 1095 2018-12-28 11:53:13Z mueller $
#
# Copyright 2018- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
# This program is free software; you may redistribute and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3, 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 complete details.
#
# Revision History:
# Date Rev Version Comment
# 2018-12-28 1095 1.0 Initial version
#
package provide tst_mig 1.0
package require rutiltpp
package require rutil
package require rlink
namespace eval tst_mig {
#
# test_regs: Test register access
#
proc test_regs {} {
#
set errcnt 0
rlc errcnt -clear
#
rlc log "tst_mig::test_regs ---------------------------------------------"
rlc log " test 1a: test stat,..,initime readable"
rlc exec \
-rreg mt.stat \
-rreg mt.conf \
-rreg mt.mask \
-rreg mt.addrl \
-rreg mt.addrh \
-rreg mt.temp \
-rreg mt.dvalcnt \
-rreg mt.crpat \
-rreg mt.wrpat \
-rreg mt.cwait \
-rreg mt.rwait \
-rreg mt.xwait \
-rreg mt.ircnt \
-rreg mt.rsttime \
-rreg mt.initime
#
#-------------------------------------------------------------------------
rlc log " test 1b: test stat,conf,temp,initime not writable"
rlc exec \
-wreg mt.stat 0x0 -estaterr \
-wreg mt.conf 0x0 -estaterr \
-wreg mt.temp 0x0 -estaterr \
-wreg mt.dvalcnt 0x0 -estaterr \
-wreg mt.crpat 0x0 -estaterr \
-wreg mt.wrpat 0x0 -estaterr \
-wreg mt.cwait 0x0 -estaterr \
-wreg mt.rwait 0x0 -estaterr \
-wreg mt.xwait 0x0 -estaterr \
-wreg mt.ircnt 0x0 -estaterr \
-wreg mt.rsttime 0x0 -estaterr \
-wreg mt.initime 0x0 -estaterr
#
#-------------------------------------------------------------------------
rlc log " test 2: test mask,addrl,addrh write and read back"
rlc exec \
-wreg mt.mask 0x00ff \
-wreg mt.addrl 0xdead \
-wreg mt.addrh 0xbeaf \
-rreg mt.mask -edata 0x00ff \
-rreg mt.addrl -edata 0xdead \
-rreg mt.addrh -edata 0xbeaf \
-wreg mt.mask 0xff00 \
-wreg mt.addrl 0xf0f0 \
-wreg mt.addrh 0x0f0f \
-rreg mt.mask -edata 0xff00 \
-rreg mt.addrl -edata 0xf0f0 \
-rreg mt.addrh -edata 0x0f0f
#
#-------------------------------------------------------------------------
rlc log " test 3a: test datrd readable and not writable"
rlc exec \
-rreg mt.datrd0 \
-rreg mt.datrd1 \
-rreg mt.datrd2 \
-rreg mt.datrd3 \
-rreg mt.datrd4 \
-rreg mt.datrd5 \
-rreg mt.datrd6 \
-rreg mt.datrd7 \
-rreg mt.datrd0 \
-wreg mt.datrd1 0x0 -estaterr \
-wreg mt.datrd2 0x0 -estaterr \
-wreg mt.datrd3 0x0 -estaterr \
-wreg mt.datrd4 0x0 -estaterr \
-wreg mt.datrd5 0x0 -estaterr \
-wreg mt.datrd6 0x0 -estaterr \
-wreg mt.datrd7 0x0 -estaterr
#
#-------------------------------------------------------------------------
rlc log " test 3b: test datwr write and read back"
rlc exec \
-wreg mt.datwr0 0x0100 \
-wreg mt.datwr1 0x0302 \
-wreg mt.datwr2 0x0504 \
-wreg mt.datwr3 0x0706 \
-wreg mt.datwr4 0x0908 \
-wreg mt.datwr5 0x0b0a \
-wreg mt.datwr6 0x0d0c \
-wreg mt.datwr7 0x0f0e \
-rreg mt.datwr0 -edata 0x0100 \
-rreg mt.datwr1 -edata 0x0302 \
-rreg mt.datwr2 -edata 0x0504 \
-rreg mt.datwr3 -edata 0x0706 \
-rreg mt.datwr4 -edata 0x0908 \
-rreg mt.datwr5 -edata 0x0b0a \
-rreg mt.datwr6 -edata 0x0d0c \
-rreg mt.datwr7 -edata 0x0f0e
#
#-------------------------------------------------------------------------
incr errcnt [rlc errcnt -clear]
return $errcnt
}
}

508
tools/tcl/tst_mig/util.tcl Normal file
View File

@@ -0,0 +1,508 @@
# $Id: util.tcl 1096 2018-12-29 07:54:17Z mueller $
#
# Copyright 2018- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
# This program is free software; you may redistribute and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3, 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 complete details.
#
# Revision History:
# Date Rev Version Comment
# 2018-12-28 1096 1.0 Initial version
# 2018-12-24 1093 0.1 First draft
#
package provide tst_mig 1.0
package require rutiltpp
package require rutil
package require rlink
namespace eval tst_mig {
# name space variables
#
variable mawidth -1; # memory address width
variable mwidth -1; # memory mask width (8 or 16 for 64 or 128 bit)
variable iswide -1; # 128 bit interface
variable initime -1; # initial initime
#
# setup register descriptions for tst_mig core design ----------------------
#
regdsc CNTL {cmd 15 3} {wren 12} {dwend 11} \
{func 3 4 \
"s:NOOP:RD:WR:PAT:REF:CAL:CMD:WREN:F8:F9:F10:F11:F12:F13:F14:F15"}
regdsc STAT {zqpend 6} {refpend 5} {rdend 4} \
{uirst 3} {caco 2} {wrdy 1} {crdy 0}
regdsc CONF {mawidth 9 5} {mwidth 4 5}
regdsc IRCNT {rstcnt 15 8} {inicnt 7 8}
#
# setup: amap definitions for tst_mig core design --------------------------
#
proc setup {{base 0x0000}} {
if {[rlc amap -testname mt.cntl $base]} {return}
rlc amap -insert mt.cntl [expr {$base + 0x00}]
rlc amap -insert mt.stat [expr {$base + 0x01}]
rlc amap -insert mt.conf [expr {$base + 0x02}]
rlc amap -insert mt.mask [expr {$base + 0x03}]
rlc amap -insert mt.addrl [expr {$base + 0x04}]
rlc amap -insert mt.addrh [expr {$base + 0x05}]
rlc amap -insert mt.temp [expr {$base + 0x06}]
rlc amap -insert mt.dvalcnt [expr {$base + 0x07}]
rlc amap -insert mt.crpat [expr {$base + 0x08}]
rlc amap -insert mt.wrpat [expr {$base + 0x09}]
rlc amap -insert mt.cwait [expr {$base + 0x0a}]
rlc amap -insert mt.rwait [expr {$base + 0x0b}]
rlc amap -insert mt.xwait [expr {$base + 0x0c}]
rlc amap -insert mt.ircnt [expr {$base + 0x0d}]
rlc amap -insert mt.rsttime [expr {$base + 0x0e}]
rlc amap -insert mt.initime [expr {$base + 0x0f}]
rlc amap -insert mt.datrd0 [expr {$base + 0x10}]
rlc amap -insert mt.datrd1 [expr {$base + 0x11}]
rlc amap -insert mt.datrd2 [expr {$base + 0x12}]
rlc amap -insert mt.datrd3 [expr {$base + 0x13}]
rlc amap -insert mt.datrd4 [expr {$base + 0x14}]
rlc amap -insert mt.datrd5 [expr {$base + 0x15}]
rlc amap -insert mt.datrd6 [expr {$base + 0x16}]
rlc amap -insert mt.datrd7 [expr {$base + 0x17}]
rlc amap -insert mt.datwr0 [expr {$base + 0x18}]
rlc amap -insert mt.datwr1 [expr {$base + 0x19}]
rlc amap -insert mt.datwr2 [expr {$base + 0x1a}]
rlc amap -insert mt.datwr3 [expr {$base + 0x1b}]
rlc amap -insert mt.datwr4 [expr {$base + 0x1c}]
rlc amap -insert mt.datwr5 [expr {$base + 0x1d}]
rlc amap -insert mt.datwr6 [expr {$base + 0x1e}]
rlc amap -insert mt.datwr7 [expr {$base + 0x1f}]
}
#
# checkconf: inspect conf and initime register -----------------------------
#
proc checkconf {} {
variable mawidth
variable mwidth
variable iswide
variable initime
if {$mwidth > 0} return ""
rlc exec -rreg mt.conf lconf \
-rreg mt.initime linitime
set mawidth [regget tst_mig::CONF(mawidth) $lconf]
set mwidth [regget tst_mig::CONF(mwidth) $lconf]
set initime linitime
set iswide [expr {$mwidth == 16}]
return ""
}
#
# iswide: 1 if 128 bit interface -------------------------------------------
#
proc iswide {} {
variable iswide
if {$iswide < 0} { checkconf }
return $iswide
}
#
# getmwidth: return mask width ---------------------------------------------
#
proc getmwidth {} {
variable mwidth
if {$mwidth < 0} { checkconf }
return $mwidth
}
#
# print: print registers ---------------------------------------------------
#
proc print {} {
set clist {}
lappend clist -rreg mt.stat stat
lappend clist -rreg mt.mask mask
lappend clist -rreg mt.addrl addrl
lappend clist -rreg mt.addrh addrh
lappend clist -rreg mt.temp temp
lappend clist -rreg mt.dvalcnt dvalcnt
lappend clist -rreg mt.crpat crpat
lappend clist -rreg mt.wrpat wrpat
lappend clist -rreg mt.cwait cwait
lappend clist -rreg mt.rwait rwait
lappend clist -rreg mt.xwait xwait
lappend clist -rreg mt.ircnt ircnt
lappend clist -rreg mt.rsttime rsttime
lappend clist -rreg mt.initime initime
lappend clist -rreg mt.datrd0 drd0
lappend clist -rreg mt.datrd1 drd1
lappend clist -rreg mt.datrd2 drd2
lappend clist -rreg mt.datrd3 drd3
lappend clist -rreg mt.datwr0 dwr0
lappend clist -rreg mt.datwr1 dwr1
lappend clist -rreg mt.datwr2 dwr2
lappend clist -rreg mt.datwr3 dwr3
if {[iswide]} {
lappend clist -rreg mt.datrd4 drd4
lappend clist -rreg mt.datrd5 drd5
lappend clist -rreg mt.datrd6 drd6
lappend clist -rreg mt.datrd7 drd7
lappend clist -rreg mt.datwr4 dwr4
lappend clist -rreg mt.datwr5 dwr5
lappend clist -rreg mt.datwr6 dwr6
lappend clist -rreg mt.datwr7 dwr7
}
rlc exec {*}$clist
set rval [format "\nstat: %4.4x" $stat]
append rval [format " zq:%d" [regget tst_mig::STAT(zqpend) $stat]]
append rval [format " rp:%d" [regget tst_mig::STAT(refpend) $stat]]
append rval [format " rd:%d" [regget tst_mig::STAT(rdend) $stat]]
append rval [format " rst:%d" [regget tst_mig::STAT(uirst) $stat]]
append rval [format " cac:%d" [regget tst_mig::STAT(caco) $stat]]
append rval [format " wrd:%d" [regget tst_mig::STAT(wrdy) $stat]]
append rval [format " crd:%d" [regget tst_mig::STAT(crdy) $stat]]
append rval [format "\naddr: %4.4x %4.4x" $addrh $addrl]
append rval [format "\nmask: %4.4x %s" $mask [pbvi b16 $mask]]
append rval [format "\ndatwr: "]
if {[iswide]} {
append rval [format "%4.4x %4.4x %4.4x %4.4x" $dwr7 $dwr6 $dwr5 $dwr4]
}
append rval [format " %4.4x %4.4x %4.4x %4.4x" $dwr3 $dwr2 $dwr1 $dwr0]
append rval [format "\ndatrd: "]
if {[iswide]} {
append rval [format "%4.4x %4.4x %4.4x %4.4x" $drd7 $drd6 $drd5 $drd4]
}
append rval [format " %4.4x %4.4x %4.4x %4.4x" $drd3 $drd2 $drd1 $drd0]
append rval [format "\ncrpat: %4.4x %s" $crpat [pbvi b16 $crpat]]
append rval [format "\nwrpat: %4.4x %s" $wrpat [pbvi b16 $wrpat]]
append rval [format "\ncwait: %4.4x %6d" $cwait $cwait]
append rval [format "\nrwait: %4.4x %6d" $rwait $rwait]
append rval [format "\nxwait: %4.4x %6d" $xwait $xwait]
set rstcnt [regget tst_mig::IRCNT(rstcnt) $ircnt]
set inicnt [regget tst_mig::IRCNT(inicnt) $ircnt]
append rval [format "\nrstcnt: %4.4x %6d" $rstcnt $rstcnt]
append rval [format " rsttime: %4.4x %6d" $rsttime $rsttime]
append rval [format "\ninicnt: %4.4x %6d" $inicnt $inicnt]
append rval [format " initime: %4.4x %6d" $initime $initime]
append rval [format "\ndvalcnt: %4.4x %6d" $dvalcnt $dvalcnt]
append rval [format "\ntemp: %4.4x %6.1f deg" $temp [conv_raw2t $temp]]
return $rval
}
#
# conv_raw2t: convert xadc temp value to degree celsius --------------------
#
proc conv_raw2t {val} {
return [expr {(($val / 4096.) * 503.975) - 273.14}]
}
#
# write: memory write ------------------------------------------------------
#
proc write {addr data {mask 0x0000}} {
set clist {}
lappend clist -wreg mt.mask $mask
lappend clist -wreg mt.addrl [expr { $addr & 0xffff}]
lappend clist -wreg mt.addrh [expr {($addr>>16) & 0xffff}]
lappend clist -wreg mt.datwr0 [lindex $data 0]
lappend clist -wreg mt.datwr1 [lindex $data 1]
lappend clist -wreg mt.datwr2 [lindex $data 2]
lappend clist -wreg mt.datwr3 [lindex $data 3]
if {[iswide]} {
lappend clist -wreg mt.datwr4 [lindex $data 4]
lappend clist -wreg mt.datwr5 [lindex $data 5]
lappend clist -wreg mt.datwr6 [lindex $data 6]
lappend clist -wreg mt.datwr7 [lindex $data 7]
}
lappend clist -wreg mt.cntl [regbld tst_mig::CNTL {func "WR"}]
rlc exec {*}$clist
return ""
}
#
# read: read ---------------------------------------------------------------
#
proc read {addr} {
set clist {}
lappend clist -wreg mt.addrl [expr { $addr & 0xffff}]
lappend clist -wreg mt.addrh [expr {($addr>>16) & 0xffff}]
lappend clist -wreg mt.cntl [regbld tst_mig::CNTL {func "RD"}]
lappend clist -rreg mt.datrd0 datrd0
lappend clist -rreg mt.datrd1 datrd1
lappend clist -rreg mt.datrd2 datrd2
lappend clist -rreg mt.datrd3 datrd3
if {[iswide]} {
lappend clist -rreg mt.datrd4 datrd4
lappend clist -rreg mt.datrd5 datrd5
lappend clist -rreg mt.datrd6 datrd6
lappend clist -rreg mt.datrd7 datrd7
}
rlc exec {*}$clist
set rval [list $datrd0 $datrd1 $datrd2 $datrd3]
if {[iswide]} {
lappend rval $datrd4 $datrd5 $datrd6 $datrd7
}
return $rval
}
#
# readck: read and check ---------------------------------------------------
#
proc readck {addr data} {
set clist {}
lappend clist -wreg mt.addrl [expr { $addr & 0xffff}]
lappend clist -wreg mt.addrh [expr {($addr>>16) & 0xffff}]
lappend clist -wreg mt.cntl [regbld tst_mig::CNTL {func "RD"}]
lappend clist -rreg mt.datrd0 -edata [lindex $data 0]
lappend clist -rreg mt.datrd1 -edata [lindex $data 1]
lappend clist -rreg mt.datrd2 -edata [lindex $data 2]
lappend clist -rreg mt.datrd3 -edata [lindex $data 3]
if {[iswide]} {
lappend clist -rreg mt.datrd4 -edata [lindex $data 4]
lappend clist -rreg mt.datrd5 -edata [lindex $data 5]
lappend clist -rreg mt.datrd6 -edata [lindex $data 6]
lappend clist -rreg mt.datrd7 -edata [lindex $data 7]
}
rlc exec {*}$clist
return ""
}
#
# readpr: read and print ---------------------------------------------------
#
proc readpr {addr {cnt 1} {inc 0}} {
set rval ""
if {$inc == 0} { set inc [getmwidth]}
for {set i 0} {$i < $cnt} {incr i} {
set data [read $addr]
if {$i != 0} { append rval "\n"}
append rval [format "%4.4x %4.4x: %4.4x %4.4x %4.4x %4.4x" \
[expr {($addr>>16) & 0xffff}] \
[expr { $addr & 0xffff}] \
[lindex $data 0] [lindex $data 1] \
[lindex $data 2] [lindex $data 3]]
if {[iswide]} {
append rval [format " %4.4x %4.4x %4.4x %4.4x" \
[lindex $data 4] [lindex $data 5] \
[lindex $data 6] [lindex $data 7]]
}
set addr [expr {$addr + $inc}]
}
return $rval
}
#
# getpat: get test pattern based on address --------------------------------
# byte by byte signature; design to look nice in readpr
# a(7)0 a(6)1 a(5)2 ... a(7)7 ... a(7)8 a(6)9 ... a(0)f
#
proc getpat {addr} {
set a7 [expr {($addr >> 28) & 0x0f}]
set a6 [expr {($addr >> 24) & 0x0f}]
set a5 [expr {($addr >> 20) & 0x0f}]
set a4 [expr {($addr >> 16) & 0x0f}]
set a3 [expr {($addr >> 12) & 0x0f}]
set a2 [expr {($addr >> 8) & 0x0f}]
set a1 [expr {($addr >> 4) & 0x0f}]
set a0 [expr { $addr & 0x0f}]
set rval [list [expr {($a7 << 12) | ($a6 << 4) | 0x0001}] \
[expr {($a5 << 12) | ($a4 << 4) | 0x0203}] \
[expr {($a3 << 12) | ($a2 << 4) | 0x0405}] \
[expr {($a1 << 12) | ($a0 << 4) | 0x0607}]
]
if {[iswide]} {
lappend rval [expr {($a7 << 12) | ($a6 << 4) | 0x0809}] \
[expr {($a5 << 12) | ($a4 << 4) | 0x0a0b}] \
[expr {($a3 << 12) | ($a2 << 4) | 0x0c0d}] \
[expr {($a1 << 12) | ($a0 << 4) | 0x0e0f}]
}
return $rval
}
#
# writepat: write test pattern ---------------------------------------------
#
proc writepat {addr {cnt 1} {inc 0}} {
if {$inc == 0} { set inc [getmwidth]}
for {set i 0} {$i < $cnt} {incr i} {
write $addr [getpat $addr]
set addr [expr {$addr + $inc}]
}
return ""
}
#
# readckpat: read and check test pattern -----------------------------------
#
proc readckpat {addr {cnt 1} {inc 0}} {
if {$inc == 0} { set inc [getmwidth]}
for {set i 0} {$i < $cnt} {incr i} {
readck $addr [getpat $addr]
set addr [expr {$addr + $inc}]
}
return ""
}
#
# test_pat: test PAT function, analyse ready patterns ----------------------
#
proc test_pat {{gcnt 16} {pcnt 4}} {
set crdyzero 0
set wrdyzero 0
set rval "cmd rdy patterns after PAT function:"
for {set i 0} { $i < $gcnt } {incr i} {
rlc exec \
-wreg mt.cntl [regbld tst_mig::CNTL {func "PAT"}] \
-rreg mt.crpat crpat0 \
-rreg mt.wrpat wrpat0 \
-wreg mt.cntl [regbld tst_mig::CNTL {func "PAT"}] \
-rreg mt.crpat crpat1 \
-rreg mt.wrpat wrpat1 \
-wreg mt.cntl [regbld tst_mig::CNTL {func "PAT"}] \
-rreg mt.crpat crpat2 \
-rreg mt.wrpat wrpat2 \
-wreg mt.cntl [regbld tst_mig::CNTL {func "PAT"}] \
-rreg mt.crpat crpat3 \
-rreg mt.wrpat wrpat3
if { $i < $pcnt } {
append rval [format "\n %s %s %s %s" \
[pbvi b16 $crpat0] [pbvi b16 $crpat1] \
[pbvi b16 $crpat2] [pbvi b16 $crpat3] ]
}
incr crdyzero [zerocount $crpat0]
incr crdyzero [zerocount $crpat1]
incr crdyzero [zerocount $crpat2]
incr crdyzero [zerocount $crpat3]
incr wrdyzero [zerocount $wrpat0]
incr wrdyzero [zerocount $wrpat1]
incr wrdyzero [zerocount $wrpat2]
incr wrdyzero [zerocount $wrpat3]
}
set tcnt [expr {4*16*$gcnt}]
append rval [format "\n crdy: bits: %4d zero: %4d frac: %6.1f%%" \
$tcnt $crdyzero [expr {100.*$crdyzero/$tcnt}]]
append rval [format "\n wrdy: bits: %4d zero: %4d frac: %6.1f%%" \
$tcnt $wrdyzero [expr {100.*$wrdyzero/$tcnt}]]
return $rval
}
#
# test_rwait: determine read latency with read commands --------------------
#
proc test_rwait {addr {cnt 16} {inc 0x0}} {
set cwaitlist {}
set rwaitlist {}
set addr0 $addr
set addr1 [expr {$addr + 1*$inc}]
set addr2 [expr {$addr + 2*$inc}]
set addr3 [expr {$addr + 3*$inc}]
for {set i 0} { $i < $cnt } {incr i} {
rlc exec \
-wreg mt.addrl [expr { $addr0 & 0xffff}] \
-wreg mt.addrh [expr {($addr0>>16) & 0xffff}] \
-wreg mt.cntl [regbld tst_mig::CNTL {func "RD"}] \
-rreg mt.cwait cwait0 \
-rreg mt.rwait rwait0 \
-wreg mt.addrl [expr { $addr1 & 0xffff}] \
-wreg mt.addrh [expr {($addr1>>16) & 0xffff}] \
-wreg mt.cntl [regbld tst_mig::CNTL {func "RD"}] \
-rreg mt.cwait cwait1 \
-rreg mt.rwait rwait1 \
-wreg mt.addrl [expr { $addr2 & 0xffff}] \
-wreg mt.addrh [expr {($addr0>>16) & 0xffff}] \
-wreg mt.cntl [regbld tst_mig::CNTL {func "RD"}] \
-rreg mt.cwait cwait2 \
-rreg mt.rwait rwait2 \
-wreg mt.addrl [expr { $addr3 & 0xffff}] \
-wreg mt.addrh [expr {($addr3>>16) & 0xffff}] \
-wreg mt.cntl [regbld tst_mig::CNTL {func "RD"}] \
-rreg mt.cwait cwait3 \
-rreg mt.rwait rwait3
lappend cwaitlist $cwait0 $cwait1 $cwait2 $cwait3
lappend rwaitlist $rwait0 $rwait1 $rwait2 $rwait3
}
set cwaitlist [lsort -integer $cwaitlist]
set rwaitlist [lsort -integer $rwaitlist]
set cwaitmin [lindex $cwaitlist 0]
set cwaitmax [lindex $cwaitlist end]
set rwaitmin [lindex $rwaitlist 0]
set rwaitmax [lindex $rwaitlist end]
set waitmax [expr {max($cwaitmax,$rwaitmax)}]
set cwaithist [lrepeat [expr {$waitmax+1}] 0]
set rwaithist [lrepeat [expr {$waitmax+1}] 0]
foreach cwait $cwaitlist {
incr cwaitsum $cwait
lset cwaithist $cwait [expr {1+[lindex $cwaithist $cwait]}]
}
foreach rwait $rwaitlist {
incr rwaitsum $rwait
lset rwaithist $rwait [expr {1+[lindex $rwaithist $rwait]}]
}
set rval ""
append rval [format "cwait: min: %3d max: %3d avr: %6.1f" \
$cwaitmin $cwaitmax [expr {$cwaitsum/(4.*$cnt)}]]
append rval [format "\nrwait: min: %3d max: %3d avr: %6.1f" \
$rwaitmin $rwaitmax [expr {$rwaitsum/(4.*$cnt)}]]
append rval "\ndistribution histogram:"
append rval "\n time: cwait rwait"
for {set i 0} { $i <= $waitmax } {incr i} {
append rval [format "\n %3d: %6d %6d" \
$i [lindex $cwaithist $i] [lindex $rwaithist $i] ]
}
return $rval
}
#
# test_reqwait: determine REF and CAL latencies ----------------------------
#
proc test_reqwait {{cnt 16} {pcnt 0}} {
set refmin 1.e6
set refmax 0
set refsum 0
set calmin 1.e6
set calmax 0
set calsum 0
set rval ""
for {set i 0} { $i < $cnt} {incr i} {
rlc exec -wreg mt.cntl [regbld tst_mig::CNTL {func "REF"}]
rlc exec \
-rreg mt.xwait xwait \
-rreg mt.crpat crpat \
-rreg mt.wrpat wrpat
set refmin [expr {min($refmin,$xwait)}]
set refmax [expr {max($refmax,$xwait)}]
incr refsum $xwait
if {$i < $pcnt} {
append rval [format "\nREF wait: %3d crdy %s wrdy %s" \
$xwait [pbvi b16 $crpat] [pbvi b16 $wrpat] ]
}
rlc exec -wreg mt.cntl [regbld tst_mig::CNTL {func "CAL"}]
rlc exec \
-rreg mt.xwait xwait \
-rreg mt.crpat crpat \
-rreg mt.wrpat wrpat
set calmin [expr {min($calmin,$xwait)}]
set calmax [expr {max($calmax,$xwait)}]
incr calsum $xwait
if {$i < $pcnt} {
append rval [format "\nZQ wait: %3d crdy %s wrdy %s" \
$xwait [pbvi b16 $crpat] [pbvi b16 $wrpat] ]
}
}
append rval [format "\nREF_REQ: min: %3d max: %3d avr: %6.1f" \
$refmin $refmax [expr {$refsum/(1.*$cnt)}]]
append rval [format "\nZQ_REQ: min: %3d max: %3d avr: %6.1f" \
$calmin $calmax [expr {$calsum/(1.*$cnt)}]]
return $rval
}
#
# zerocount ----------------------------------------------------------------
#
proc zerocount {pat} {
set cnt 0
set mask 1
for {set i 0} { $i < 16 } {incr i} {
if { ($pat & $mask) == 0 } { incr cnt }
set mask [expr { $mask << 1 } ]
}
return $cnt
}
}