From f50a85e6463c1737918371ddbfa40c226751051f Mon Sep 17 00:00:00 2001 From: wfjm Date: Tue, 1 Jan 2019 22:41:44 +0100 Subject: [PATCH] add sys_tst_mig_arty system: a MIG tester --- .travis.yml | 8 +- Makefile | 4 +- doc/CHANGELOG.md | 17 +- rtl/bplib/arty/mig_arty.tcl | 4 +- rtl/sys_gen/README.md | 1 + rtl/sys_gen/tst_mig/arty/Makefile | 25 + rtl/sys_gen/tst_mig/arty/sys_conf.vhd | 60 ++ .../tst_mig/arty/sys_tst_mig_arty.vbom | 28 + rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vhd | 454 ++++++++++++ .../tst_mig/arty/sys_tst_mig_arty.vmfset | 56 ++ rtl/sys_gen/tst_mig/arty/tb/.gitignore | 2 + rtl/sys_gen/tst_mig/arty/tb/Makefile | 39 + rtl/sys_gen/tst_mig/arty/tb/sys_conf_sim.vhd | 57 ++ .../tst_mig/arty/tb/tb_tst_mig_arty.vbom | 9 + .../tst_mig/arty/tb/tb_tst_mig_arty.vhd | 35 + rtl/sys_gen/tst_mig/arty/tb/tbrun.yml | 13 + rtl/sys_gen/tst_mig/arty/tb/tbw.dat | 7 + rtl/sys_gen/tst_mig/tbrun.yml | 7 + rtl/sys_gen/tst_mig/tst_mig.vbom | 8 + rtl/sys_gen/tst_mig/tst_mig.vhd | 683 ++++++++++++++++++ rtl/sys_gen/tst_sram/tst_sram.vhd | 6 +- tbrun.yml | 4 +- tools/tcl/setup_packages | 3 +- tools/tcl/tst_mig/test_all.tcl | 40 + tools/tcl/tst_mig/test_mem.tcl | 103 +++ tools/tcl/tst_mig/test_regs.tcl | 129 ++++ tools/tcl/tst_mig/util.tcl | 508 +++++++++++++ 27 files changed, 2294 insertions(+), 16 deletions(-) create mode 100644 rtl/sys_gen/tst_mig/arty/Makefile create mode 100644 rtl/sys_gen/tst_mig/arty/sys_conf.vhd create mode 100644 rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vbom create mode 100644 rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vhd create mode 100644 rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vmfset create mode 100644 rtl/sys_gen/tst_mig/arty/tb/.gitignore create mode 100644 rtl/sys_gen/tst_mig/arty/tb/Makefile create mode 100644 rtl/sys_gen/tst_mig/arty/tb/sys_conf_sim.vhd create mode 100644 rtl/sys_gen/tst_mig/arty/tb/tb_tst_mig_arty.vbom create mode 100644 rtl/sys_gen/tst_mig/arty/tb/tb_tst_mig_arty.vhd create mode 100644 rtl/sys_gen/tst_mig/arty/tb/tbrun.yml create mode 100644 rtl/sys_gen/tst_mig/arty/tb/tbw.dat create mode 100644 rtl/sys_gen/tst_mig/tbrun.yml create mode 100644 rtl/sys_gen/tst_mig/tst_mig.vbom create mode 100644 rtl/sys_gen/tst_mig/tst_mig.vhd create mode 100644 tools/tcl/tst_mig/test_all.tcl create mode 100644 tools/tcl/tst_mig/test_mem.tcl create mode 100644 tools/tcl/tst_mig/test_regs.tcl create mode 100644 tools/tcl/tst_mig/util.tcl diff --git a/.travis.yml b/.travis.yml index 22cec2f5..9d933f62 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/Makefile b/Makefile index d84a8879..8ec41fe4 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 8b7495b4..101f9c70 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -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 diff --git a/rtl/bplib/arty/mig_arty.tcl b/rtl/bplib/arty/mig_arty.tcl index e981eed3..4997704c 100644 --- a/rtl/bplib/arty/mig_arty.tcl +++ b/rtl/bplib/arty/mig_arty.tcl @@ -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 # 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 diff --git a/rtl/sys_gen/README.md b/rtl/sys_gen/README.md index 87efa800..53e4780d 100644 --- a/rtl/sys_gen/README.md +++ b/rtl/sys_gen/README.md @@ -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 | diff --git a/rtl/sys_gen/tst_mig/arty/Makefile b/rtl/sys_gen/tst_mig/arty/Makefile new file mode 100644 index 00000000..6adea1eb --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/Makefile @@ -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 +# diff --git a/rtl/sys_gen/tst_mig/arty/sys_conf.vhd b/rtl/sys_gen/tst_mig/arty/sys_conf.vhd new file mode 100644 index 00000000..309ffa10 --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/sys_conf.vhd @@ -0,0 +1,60 @@ +-- $Id: sys_conf.vhd 1092 2018-12-24 08:01:50Z mueller $ +-- +-- Copyright 2018- by Walter F.J. Mueller +-- +-- 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; diff --git a/rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vbom b/rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vbom new file mode 100644 index 00000000..f9f8d4dc --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vbom @@ -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 diff --git a/rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vhd b/rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vhd new file mode 100644 index 00000000..d2b4ffad --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vhd @@ -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 +-- +-- 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; diff --git a/rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vmfset b/rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vmfset new file mode 100644 index 00000000..d83c7d2c --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/sys_tst_mig_arty.vmfset @@ -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 diff --git a/rtl/sys_gen/tst_mig/arty/tb/.gitignore b/rtl/sys_gen/tst_mig/arty/tb/.gitignore new file mode 100644 index 00000000..cdbb4522 --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/tb/.gitignore @@ -0,0 +1,2 @@ +tb_tst_mig_arty +sysmon_stim diff --git a/rtl/sys_gen/tst_mig/arty/tb/Makefile b/rtl/sys_gen/tst_mig/arty/tb/Makefile new file mode 100644 index 00000000..e1b58c90 --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/tb/Makefile @@ -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 +# diff --git a/rtl/sys_gen/tst_mig/arty/tb/sys_conf_sim.vhd b/rtl/sys_gen/tst_mig/arty/tb/sys_conf_sim.vhd new file mode 100644 index 00000000..12cc1396 --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/tb/sys_conf_sim.vhd @@ -0,0 +1,57 @@ +-- $Id: sys_conf_sim.vhd 1092 2018-12-24 08:01:50Z mueller $ +-- +-- Copyright 2018- by Walter F.J. Mueller +-- +-- 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; diff --git a/rtl/sys_gen/tst_mig/arty/tb/tb_tst_mig_arty.vbom b/rtl/sys_gen/tst_mig/arty/tb/tb_tst_mig_arty.vbom new file mode 100644 index 00000000..ccefed54 --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/tb/tb_tst_mig_arty.vbom @@ -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 diff --git a/rtl/sys_gen/tst_mig/arty/tb/tb_tst_mig_arty.vhd b/rtl/sys_gen/tst_mig/arty/tb/tb_tst_mig_arty.vhd new file mode 100644 index 00000000..0b03539a --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/tb/tb_tst_mig_arty.vhd @@ -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 +-- +-- 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; diff --git a/rtl/sys_gen/tst_mig/arty/tb/tbrun.yml b/rtl/sys_gen/tst_mig/arty/tb/tbrun.yml new file mode 100644 index 00000000..250afa48 --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/tb/tbrun.yml @@ -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 diff --git a/rtl/sys_gen/tst_mig/arty/tb/tbw.dat b/rtl/sys_gen/tst_mig/arty/tb/tbw.dat new file mode 100644 index 00000000..4a19b13e --- /dev/null +++ b/rtl/sys_gen/tst_mig/arty/tb/tbw.dat @@ -0,0 +1,7 @@ +# $Id: tbw.dat 1092 2018-12-24 08:01:50Z mueller $ +# +[tb_tst_mig_arty] +rlink_cext_fifo_rx = +rlink_cext_fifo_tx = +rlink_cext_conf = +sysmon_stim = ../../../../bplib/sysmon/tb/sysmon_stim_arty.dat diff --git a/rtl/sys_gen/tst_mig/tbrun.yml b/rtl/sys_gen/tst_mig/tbrun.yml new file mode 100644 index 00000000..dbdbed46 --- /dev/null +++ b/rtl/sys_gen/tst_mig/tbrun.yml @@ -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 diff --git a/rtl/sys_gen/tst_mig/tst_mig.vbom b/rtl/sys_gen/tst_mig/tst_mig.vbom new file mode 100644 index 00000000..d457700b --- /dev/null +++ b/rtl/sys_gen/tst_mig/tst_mig.vbom @@ -0,0 +1,8 @@ +# libs +../../vlib/slvtypes.vhd +../../vlib/rutil.vhd +../../vlib/rbus/rblib.vhd +${sys_conf} +# components +# design +tst_mig.vhd diff --git a/rtl/sys_gen/tst_mig/tst_mig.vhd b/rtl/sys_gen/tst_mig/tst_mig.vhd new file mode 100644 index 00000000..40596852 --- /dev/null +++ b/rtl/sys_gen/tst_mig/tst_mig.vhd @@ -0,0 +1,683 @@ +-- $Id: tst_mig.vhd 1096 2018-12-29 07:54:17Z mueller $ +-- +-- Copyright 2018- by Walter F.J. Mueller +-- +-- 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; diff --git a/rtl/sys_gen/tst_sram/tst_sram.vhd b/rtl/sys_gen/tst_sram/tst_sram.vhd index 5da06d27..e8431582 100644 --- a/rtl/sys_gen/tst_sram/tst_sram.vhd +++ b/rtl/sys_gen/tst_sram/tst_sram.vhd @@ -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 -- @@ -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) diff --git a/tbrun.yml b/tbrun.yml index de33b71c..ffb9dff0 100644 --- a/tbrun.yml +++ b/tbrun.yml @@ -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 diff --git a/tools/tcl/setup_packages b/tools/tcl/setup_packages index 446e5b3e..940842d5 100755 --- a/tools/tcl/setup_packages +++ b/tools/tcl/setup_packages @@ -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 diff --git a/tools/tcl/tst_mig/test_all.tcl b/tools/tcl/tst_mig/test_all.tcl new file mode 100644 index 00000000..3bca340a --- /dev/null +++ b/tools/tcl/tst_mig/test_all.tcl @@ -0,0 +1,40 @@ +# $Id: test_all.tcl 1094 2018-12-27 15:18:27Z mueller $ +# +# Copyright 2018- by Walter F.J. Mueller +# +# 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 + } + +} diff --git a/tools/tcl/tst_mig/test_mem.tcl b/tools/tcl/tst_mig/test_mem.tcl new file mode 100644 index 00000000..a6fe9127 --- /dev/null +++ b/tools/tcl/tst_mig/test_mem.tcl @@ -0,0 +1,103 @@ +# $Id: test_mem.tcl 1096 2018-12-29 07:54:17Z mueller $ +# +# Copyright 2018- by Walter F.J. Mueller +# +# 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 + } +} diff --git a/tools/tcl/tst_mig/test_regs.tcl b/tools/tcl/tst_mig/test_regs.tcl new file mode 100644 index 00000000..35aefb0e --- /dev/null +++ b/tools/tcl/tst_mig/test_regs.tcl @@ -0,0 +1,129 @@ +# $Id: test_regs.tcl 1095 2018-12-28 11:53:13Z mueller $ +# +# Copyright 2018- by Walter F.J. Mueller +# +# 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 + } +} diff --git a/tools/tcl/tst_mig/util.tcl b/tools/tcl/tst_mig/util.tcl new file mode 100644 index 00000000..9c7f319d --- /dev/null +++ b/tools/tcl/tst_mig/util.tcl @@ -0,0 +1,508 @@ +# $Id: util.tcl 1096 2018-12-29 07:54:17Z mueller $ +# +# Copyright 2018- by Walter F.J. Mueller +# +# 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 + } +}