1
0
mirror of https://github.com/wfjm/w11.git synced 2026-05-04 23:26:38 +00:00

- upgraded CRAM controller, now with 'page mode' support

- new test bench driver tbrun, give automatized test bench execution
This commit is contained in:
Walter F.J. Mueller
2016-10-15 07:42:21 +00:00
parent 2b5cfb7d96
commit 5983b0bb2a
402 changed files with 18795 additions and 1204 deletions

View File

@@ -1,29 +0,0 @@
#!/usr/bin/perl -w
# $Id: ghdl_assert_filter 620 2014-12-25 10:48:35Z mueller $
#
# Copyright 2014- 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 2, 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
# 2014-12-23 620 1.0 Initial version
use 5.10.0; # require Perl 5.10 or higher
use strict; # require strict checking
autoflush STDOUT 1 if (-p STDOUT); # autoflush if output into pipe
autoflush STDOUT 1 if (-t STDOUT); # autoflush if output into term
while (<>) {
next if /:\@0ms:\(assertion warning\): NUMERIC_STD.*metavalue detected/;
next if /:\@0ms:\(assertion warning\): CONV_INTEGER: There is an 'U'/;
print;
}

119
tools/bin/njobihtm Executable file
View File

@@ -0,0 +1,119 @@
#!/usr/bin/perl -w
# $Id: njobihtm 810 2016-10-02 16:51:12Z mueller $
#
# Copyright 2016- 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 2, 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
# 2016-10-01 810 1.0 Initial version
#
use 5.14.0; # require Perl 5.14 or higher
use strict; # require strict checking
use Getopt::Long;
my %opts = ();
GetOptions(\%opts, "verbose", "mem=s"
)
or die "bad options";
sub get_cpuinfo;
sub get_meminfo;
my $ncpu;
my $ntpc;
my $nkb;
my $njob = 1;
get_cpuinfo();
get_meminfo();
if (defined $ncpu && defined $ntpc && defined $nkb) {
} else {
print STDERR "njobihtm-F: failed to obtain cpu or mem size\n";
exit 1;
}
my $ncore = $ncpu / $ntpc; # number of cores
my $nht = $ncpu - $ncore;
$njob = $ncore + int($nht/4);
if ($opts{verbose}) {
printf STDERR "#cpus: %d\n", $ncpu;
printf STDERR "#thread/cpu: %d\n", $ntpc;
printf STDERR "#cores: %d\n", $ncore;
printf STDERR "mem(MB): %d\n", int($nkb/1024);
printf STDERR "#job (cpus): %d\n", $njob;
}
if (defined $opts{mem}) {
my $mem;
if ($opts{mem} =~ m/^(\d+)([MG])$/) {
$mem = 1024 * $1 if $2 eq 'M';
$mem = 1024* 1024 * $1 if $2 eq 'G';
my $njobm = int(($nkb - 1024*1024) / $mem);
$njobm = 1 unless $njobm > 0;
printf STDERR "#job (mem): %d\n", $njobm if $opts{verbose};
if ($njobm < $njob) {
$njob = $njobm;
}
} else {
print STDERR "njobihtm-F: bad -mem option '$opts{mem}', must be nnn[MG]\n";
exit 1;
}
}
print "$njob\n";
exit 0;
#-------------------------------------------------------------------------------
sub get_cpuinfo {
open (LSCPU, "lscpu|")
or die "failed to open 'lscpu|': $!";
while (<LSCPU>) {
chomp;
if (m/^(.*?)\s*:\s*(.*)$/) {
my $tag = $1;
my $val = $2;
# print "+++1 '$tag' : '$val' \n";
$ncpu = $val if $tag eq 'CPU(s)';
$ntpc = $val if $tag eq 'Thread(s) per core';
}
}
close LSCPU;
return;
}
#-------------------------------------------------------------------------------
sub get_meminfo {
open (MEMINFO, "/proc/meminfo")
or die "failed to open '/proc/meminfo': $!";
while (<MEMINFO>) {
chomp;
if (m/^(.*?)\s*:\s*(\d+)\s*kB/) {
my $tag = $1;
my $val = $2;
# print "+++1 '$tag' : '$val' \n";
$nkb = $val if $tag eq 'MemTotal';
}
}
close MEMINFO;
return;
}

403
tools/bin/tbfilt Executable file
View File

@@ -0,0 +1,403 @@
#!/usr/bin/perl -w
# $Id: tbfilt 807 2016-09-17 07:49:26Z mueller $
#
# Copyright 2016- 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 2, 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
# 2016-09-10 806 1.0 Initial version
# 2016-08-05 795 0.1 First draft
#
use 5.14.0; # require Perl 5.14 or higher
use strict; # require strict checking
use Getopt::Long;
use FileHandle;
use POSIX qw(strftime);
my %opts = ();
GetOptions(\%opts, "tee=s", "pcom",
"find=s", "all",
"summary", "wide", "compact", "format=s", "nohead"
)
or die "bad options";
sub do_file;
sub conv_fd;
sub conv_ft;
sub conv_fs;
sub conv_fa;
sub conv_tr;
sub conv_tu;
sub conv_ts;
sub conv_tc;
sub conv_tg;
sub conv_st;
sub conv_ss;
sub conv_sc;
sub conv_sg;
sub conv_sp;
sub conv_sm;
sub conv_ec;
sub conv_pf;
sub conv_nf;
sub conv_ns;
my %fmttbl = (fd => {conv => \&conv_fd, head=>' file-date'},
ft => {conv => \&conv_ft, head=>' time'},
fs => {conv => \&conv_fs, head=>' time'},
fa => {conv => \&conv_fa, head=>'age'},
tr => {conv => \&conv_tr, head=>' time-real'},
tu => {conv => \&conv_tu, head=>' time-user'},
ts => {conv => \&conv_ts, head=>' time-sys'},
tc => {conv => \&conv_tc, head=>' time-cpu'},
tg => {conv => \&conv_tg, head=>' time t'},
st => {conv => \&conv_st, head=>'stime(ns)'},
ss => {conv => \&conv_ss, head=>'stime'},
sc => {conv => \&conv_sc, head=>' cycles'},
sg => {conv => \&conv_sg, head=>' cyc|tim'},
sp => {conv => \&conv_sp, head=>'sperf'},
sm => {conv => \&conv_sm, head=>'MHz'},
ec => {conv => \&conv_ec, head=>'err'},
pf => {conv => \&conv_pf, head=>'stat'},
nf => {conv => \&conv_nf, head=>'filename'},
ns => {conv => \&conv_ns, head=>'filename'});
my @fmtlst;
my $format = $ENV{TBFILT_FORMAT};
$format = '%fd %fs %tr %tc %sc %ec %pf %nf' if $opts{wide};
$format = '%fa %tg %sg %ec %pf %ns' if $opts{compact};
$format = $opts{format} if defined $opts{format};
$format = '%ec %pf %nf' unless defined $format;
while (length($format)) {
if ($format =~ m/^([^%]*)%([a-z][a-z])/) {
my $pref = $1;
my $code = $2;
if (exists $fmttbl{$code}) {
push @fmtlst, {pref => $pref,
conv => $fmttbl{$code}{conv},
head => $fmttbl{$code}{head}};
} else { last; };
$format = $';
} else { last; };
}
if (length($format)) {
print STDERR "tbfilt-f: bad format '$format'\n";
exit 2;
}
autoflush STDOUT 1 if (-p STDOUT);
my $fh_tee;
if (defined $opts{tee} && $opts{tee} ne '') {
$fh_tee = new FileHandle;
$fh_tee->open($opts{tee},'>') or die "failed to open for write '$opts{tee}'";
}
my @flist = @ARGV;
# if find pattern has no '*', expand it
if (defined $opts{find}) {
unless ($opts{find} =~ m/\*/) {
$opts{find} = '.*/tb_.*_' . $opts{find} . '.*\.log';
}
}
if (defined $opts{all}) {
if (defined $opts{find}) {
print STDERR "tbfilt-I: -find ignored because -all given\n";
}
$opts{find} = '.*/tb_.*_[bfsorept]sim(_.*)?\.log';
}
if (defined $opts{find}) {
if (scalar (@flist)) {
print STDERR "tbfilt-I: file names ignored because -all or -find given\n";
@flist = ();
}
open FIND,'-|',"find -regextype egrep -regex '$opts{find}'"
or die "failed to open find pipe";
while (<FIND>) {
chomp;
s|^\./||; # drop leading ./
push @flist, $_;
}
close FIND;
@flist = sort @flist;
if (scalar (@flist) == 0) {
print STDERR "tbfilt-E: no files found by -find or -all\n";
exit 2;
}
} else {
push @flist, '-' if (scalar(@flist) == 0);
}
my $manyfile = scalar(@flist) > 1;
my $notsumm = not $opts{summary};
my %vals;
my $exitcode = 0;
if ($opts{summary} && (not $opts{nohead})) {
foreach my $item (@fmtlst) {
print $item->{pref};
print $item->{head};
}
print "\n";
}
foreach my $fnam (@flist) {
my $nfail = do_file($fnam);
$exitcode = 1 if $nfail;
}
exit $exitcode;
#-------------------------------------------------------------------------------
sub do_file {
my ($fnam) = @_;
%vals = ();
$vals{fnam} = $fnam;
$vals{nfail} = 0;
my $fh;
if ($fnam eq '-') {
$fh = *STDIN;
} else {
$fh = new FileHandle;
$fh->open($fnam,'<') or die "failed to open for read '$fnam'";
}
if ($manyfile && $notsumm) {
print "-- $fnam";
my $npad = 74-length($fnam);
print ' '.('-' x $npad) if $npad > 0;
print "\n";
}
while (<$fh>) {
print $fh_tee $_ if defined $fh_tee;
chomp;
my $show;
my $fail;
$fail = 1 if m/-[EF]:/;
$fail = 1 if m/(ERROR|FAIL)/;
$show = 1 if m/-W:/;
$show = 1 if m/(PASS)/;
$show = 1 if $opts{pcom} && m/^C/; # show lines starting with C
# ghdl reports or assertions (warning and higher)
if (m/:\((report|assertion) (warning|error|failure)\):/) {
# ignore ieee lib warnings at t=0
next if /:\@0ms:\(assertion warning\): NUMERIC_STD.*metavalue detected/;
next if /:\@0ms:\(assertion warning\): CONV_INTEGER: There is an 'U'/;
next if /std_logic_arith.*:\@0ms:\(assertion warning\): There is an 'U'/;
# ignore ' Simulation Finished' report failure (used to end ghdl sim)
next if /:\(report failure\): Simulation Finished/;
$fail = 1;
}
# check for DONE line accept
# 920 ns: DONE -- tb'swithout clock
# 7798080.0 ns 389893: DONE -- single clock tb's
# 56075.0 ns 2094: DONE-w -- multiclock tb's (max taken)
#
if (m/^\s*(\d+\.?\d*)\s+ns\s*(\d*):\s+DONE(-\S+)?\s*$/) {
$show = 1;
$vals{done_ns} = $1;
if ($2 ne '') {
if (defined $vals{done_cyc}) {
$vals{done_cyc} = $2 if $2 > $vals{done_cyc};
} else {
$vals{done_cyc} = $2;
}
}
}
# check for time line
# Note: don't root the pattern with /^ --> allow arbitary text before
# the 'time' output. In practice 'time' output (to stderr by bash)
# and ghdl 'report' (also to stderr) get mixed and one might get
# tb_w11a_b3real 0m49.179s user 0m0.993s sys 0m0.293s
#
if (m/real\s+(\d*)m(\d+\.\d*)s\s+
user\s+(\d*)m(\d+\.\d*)s\s+
sys\s+(\d*)m(\d+\.\d*)s/x) {
$show = 1;
$vals{treal} = [$1,$2];
$vals{tuser} = [$3,$4];
$vals{tsys} = [$5,$6];
}
print "$_\n" if ($show || $fail) && $notsumm;
$vals{nfail} += 1 if $fail;
}
if (not defined $vals{done_ns}) {
print "tbfilt-I: no DONE seen; FAIL\n" if $notsumm;
$vals{nfail} += 1;
}
$vals{mtime} = ($fnam eq '-') ? time : (stat($fh))[9];
if ($opts{summary}) {
foreach my $item (@fmtlst) {
print $item->{pref};
print &{$item->{conv}};
}
print "\n";
}
return $vals{nfail};
}
#-------------------------------------------------------------------------------
sub time_val {
my ($tdsc) = @_;
return undef unless defined $tdsc;
return 60.*$tdsc->[0] + $tdsc->[1];
}
sub time_str {
my ($tdsc) = @_;
return ' -' unless defined $tdsc;
return sprintf '%3dm%06.3fs', $tdsc->[0],$tdsc->[1];
}
sub time_sum {
my ($tdsc1,$tdsc2) = @_;
return undef unless defined $tdsc1 && defined $tdsc2;
return time_val($tdsc1) + time_val($tdsc2);
}
sub gconv {
my ($val) = @_;
my $str = sprintf '%4.2f', $val;
return substr($str,0,4);
}
#-------------------------------------------------------------------------------
sub conv_fd {
return strftime "%F", localtime($vals{mtime});
}
sub conv_ft {
return strftime "%T", localtime($vals{mtime});
}
sub conv_fs {
return strftime "%H:%M", localtime($vals{mtime});
}
sub conv_fa {
my $dt = time - $vals{mtime};
return sprintf '%2ds', $dt if $dt < 99;
$dt /= 60; return sprintf '%2dm', $dt if $dt < 99;
$dt /= 60; return sprintf '%2dh', $dt if $dt < 60;
$dt /= 24; return sprintf '%2dd', $dt if $dt < 99;
return 'old';
}
sub conv_tr {
return time_str($vals{treal});
}
sub conv_tu {
return time_str($vals{tuser});
}
sub conv_ts {
return time_str($vals{tsys});
}
sub conv_tc {
my $tsum = time_sum($vals{tuser}, $vals{tsys});
return ' -' unless defined $tsum;
my $min = int($tsum/60.);
my $sec = $tsum - 60. * $min;
return sprintf '%3dm%06.3fs', $min, $sec;
}
sub conv_tg {
my $treal = time_val($vals{treal});
my $tcpu = time_sum($vals{tuser}, $vals{tsys});
if (defined $treal && defined $tcpu && $tcpu > 0.4 * $treal) {
return conv_tc() . ' c' ;
} else {
return conv_tr() . ((defined $treal) ? ' r': ' -');
}
}
sub conv_st {
return ' -' unless defined $vals{done_ns};
return sprintf '%9d', $vals{done_ns};
}
sub conv_ss {
return ' -' unless defined $vals{done_ns};
my $stim = 0.001 * $vals{done_ns};
return gconv($stim) . 'u' if $stim < 999;
$stim *= 0.001; return gconv($stim) . 'm' if $stim < 999;
$stim *= 0.001; return gconv($stim) . 's';
}
sub conv_sc {
return ' -' unless defined $vals{done_cyc};
return sprintf '%8d', $vals{done_cyc};
}
sub conv_sg {
return conv_sc() if defined $vals{done_cyc};
return ' ' . conv_ss();
}
sub conv_sp {
my $nc = $vals{done_cyc};
my $tsum = time_sum($vals{tuser}, $vals{tsys});
return ' -' unless defined $nc && defined $tsum;
my $sperf = 1000000. * $tsum / $nc;
return gconv($sperf) . 'u' if $sperf < 999;
$sperf *= 0.001; return gconv($sperf) . 'm';
}
sub conv_sm {
return ' -' unless defined $vals{done_ns} && $vals{done_ns} > 200 &&
defined $vals{done_cyc};
my $mhz = (1000. * $vals{done_cyc}) / ($vals{done_ns} - 200);
return sprintf '%3d', int($mhz+0.5);
}
sub conv_ec {
return sprintf '%3d', $vals{nfail};
}
sub conv_pf {
return $vals{nfail} ? 'FAIL' : 'PASS';
}
sub conv_nf {
return $vals{fnam};
}
sub conv_ns {
my $val = $vals{fnam};
$val =~ s|^.*/||;
return $val;
}

830
tools/bin/tbrun Executable file
View File

@@ -0,0 +1,830 @@
#!/usr/bin/perl -w
# $Id: tbrun 808 2016-09-17 13:02:46Z mueller $
#
# Copyright 2016- 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 2, 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
# 2016-09-17 808 1.0 Initial version
# 2016-08-09 796 0.1 First draft
#
use 5.14.0; # require Perl 5.14 or higher
use strict; # require strict checking
use Getopt::Long;
use FileHandle;
use YAML::XS;
use Cwd;
use IO::Select;
use Time::HiRes qw(gettimeofday);
my %opts = ();
GetOptions(\%opts, "tag=s@", "exclude=s@", "mode=s",
"jobs=i", "tee=s", "tmax=i", "dry", "trace",
"nomake", "norun",
"rlmon", "rbmon", "bwait=i", "swait=i"
)
or die "bad options";
sub setup_tagfilter;
sub check_tagfilter;
sub check_modefilter;
sub include_file;
sub read_file;
sub load_yaml;
sub check_keys;
sub expand_vars;
sub merge_lines;
sub merge_expand;
sub key_or_def;
sub handle_include;
sub handle_default;
sub handle_itest;
sub tpr;
sub tpre;
sub print_trace;
sub run_tests_single;
sub run_tests_multi;
my @tlist;
my @olist;
my @wlist;
my %keys_include = ( include => { mode => 'm', ref => ''},
tag => { mode => 'o', ref => 'ARRAY'}
);
my %keys_default = ( default => { mode => 'm', ref => 'HASH'}
);
my %keys_defhash = ( tag => { mode => 'o', ref => 'ARRAY'},
mode => { mode => 'o', ref => ''}
);
my %keys_itest = ( test => { mode => 'm', ref => ''},
tag => { mode => 'o', ref => 'ARRAY'},
mode => { mode => 'o', ref => ''}
);
my $nseen = 0;
my $ntest = 0;
my $ndone = 0;
my $nfail = 0;
my $inicwd = getcwd();
my %gblvars;
$gblvars{ise_modes} = '[bsft]sim,ISim_[bsft]sim';
$gblvars{ise_modes_noisim} = '[bsft]sim'; # when ISim not possible
$gblvars{ise_modes_nossim} = 'bsim,ISim_bsim'; # when ssim not available
#
$gblvars{viv_modes} = '[bsor]sim,XSim_[bsorept]sim';
$gblvars{viv_modes_nossim} = 'bsim,XSim_bsim'; # when ssim not available
autoflush STDOUT 1 if -p STDOUT || -t STDOUT;
my $ticker_on = -t STDOUT;
my $fh_tee;
if (defined $opts{tee} && $opts{tee} ne '') {
$fh_tee = new FileHandle;
$fh_tee->open($opts{tee},'>') or die "failed to open for write '$opts{tee}'";
}
$opts{tag} = ['default'] unless defined $opts{tag};
$opts{mode} = 'bsim' unless defined $opts{mode};
my %modecache;
my @modelist;
foreach (split /,/,$opts{mode}) {
$_ .= '_bsim' if m/^[IX]Sim$/;
push @modelist, $_;
}
push @ARGV, 'tbrun.yml' unless scalar( @ARGV);
my @tagincl = setup_tagfilter($opts{tag});
my @tagexcl = setup_tagfilter($opts{exclude});
foreach my $fnam (@ARGV) {
include_file($fnam);
}
$ntest = scalar(@tlist);
unless ($ntest) {
tpre(sprintf "tbrun-E: %d tests found, none selected\n", $nseen);
exit 2;
}
if (defined $opts{jobs}) {
run_tests_multi();
} else {
run_tests_single();
}
if (defined $opts{dry}) {
tpr(sprintf "#tbrun-I: %d tests found, %d selected\n", $nseen,$ntest);
}
if ($nfail) {
tpr(sprintf "tbrun-I: %d tests failed of %d tests executed\n",$nfail,$ndone);
}
exit $nfail ? 1 : 0;
#-------------------------------------------------------------------------------
sub setup_tagfilter {
my ($targlist) = @_;
return () unless defined $targlist;
my @tagfiltlist;
foreach my $targ (@$targlist) {
my @tagfilt = map { "^($_)\$" } split /,/, $targ;
push @tagfiltlist, \@tagfilt;
}
return @tagfiltlist;
}
#-------------------------------------------------------------------------------
sub check_tagfilter {
my ($tfiltlist,$tlist) = @_;
foreach my $tfilt (@$tfiltlist) { # loop over filters
my $fok = 1;
foreach my $tfele (@$tfilt) { # loop over filter elements
my $match = 0;
foreach my $tag (@$tlist) { # loop over tags
$match = $tag =~ m/$tfele/; # tag matchs filter element
last if $match;
}
$fok = 0 unless $match; # filter missed if one element missed
}
return 1 if $fok; # return ok of one filter matched
}
return 0; # here if no filter matched
}
#-------------------------------------------------------------------------------
sub check_modefilter {
my ($mode,$mlist) = @_;
unless (exists $modecache{$mlist}) {
my %mh;
foreach my $mi (split /,/,$mlist) {
if ($mi =~ m/^(.*)\[([a-z]+)\](.*)$/) {
foreach (split //,$2) {
$mh{$1.$_.$3} = 1;
}
} else {
$mh{$mi} = 1;
}
}
$modecache{$mlist} = \%mh;
}
my $rmh = $modecache{$mlist};
return exists $$rmh{$mode};
}
#-------------------------------------------------------------------------------
sub include_file {
my ($fnam) = @_;
my $fdat = read_file($fnam);
exit 2 unless defined $fdat;
my $ylst = load_yaml($fdat, $fnam);
exit 2 unless defined $ylst;
my $oldcwd = getcwd();
if ($fnam =~ m|^(.*)/(.*)$|) {
chdir $1 or die "chdir to '$1' failed with '$!'";
}
my %defhash;
foreach my $yele (@$ylst) {
if (exists $yele->{include}) {
handle_include($yele);
} elsif (exists $yele->{default}) {
handle_default($yele, \%defhash);
} elsif (exists $yele->{test}) {
handle_itest($yele, \%defhash);
} else {
tpr(sprintf "tbrun-E: unknown list element in '%s'\n found keys: %s\n",
$fnam, join(',',sort keys %$yele));
exit 2;
}
}
chdir $oldcwd or die "chdir to '$oldcwd' failed with '$!'";
return;
}
#-------------------------------------------------------------------------------
sub read_file {
my ($fnam) = @_;
my $fh = new FileHandle;
if (not open $fh, '<', $fnam) {
my $err = $!;
tpre(sprintf "tbrun-E: failed to open '%s'\n cwd: %s\n error: %s\n",
$fnam, getcwd(), $err);
return undef;
}
# nice trick to slurp the whole file into a variable
my $fdat = do {
local $/ = undef;
<$fh>;
};
close $fh;
return $fdat;
}
#-------------------------------------------------------------------------------
sub load_yaml {
my ($fdat,$fnam) = @_;
my $ylst;
eval { $ylst = YAML::XS::Load($fdat); };
if ($@ ne '') {
my $err = $@;
tpre(sprintf "tbrun-E: failed to yaml load '%s'\n cwd: %s\n error: %s\n",
$fnam, getcwd(), $err);
return undef;
}
if (ref $ylst ne 'ARRAY') {
tpre(sprintf "tbrun-E: top level yaml is not a list but '%s'\n", ref $ylst);
return undef;
}
foreach my $yele (@$ylst) {
if (ref $yele ne 'HASH') {
tpre(sprintf "tbrun-E: second level yaml is not a hash '%s'\n", ref $yele);
return undef;
}
}
return $ylst;
}
#-------------------------------------------------------------------------------
sub check_keys {
my ($yele, $href) = @_;
foreach my $keyele ( keys %$yele ) {
if (not exists $href->{$keyele}) {
tpre(sprintf "tbrun-E: unexpected key '%s'\n", $keyele);
return 0;
}
my $ref = ref $yele->{$keyele};
if ($ref ne $href->{$keyele}->{ref}) {
tpre(sprintf "tbrun-E: key '%s' is type'%s', expected '%s'\n",
$keyele, $ref, $href->{$keyele}->{ref});
return 0;
}
}
foreach my $keyref ( keys %$href ) {
next if $href->{$keyref}->{mode} eq 'o';
if (not exists $yele->{$keyref}) {
tpre(sprintf "tbrun-E: key '%s' missing\n", $keyref);
return 0;
}
}
return 1;
}
#-------------------------------------------------------------------------------
sub lookup_var {
my ($vnam,$hrefs) = @_;
return $gblvars{$vnam} if exists $gblvars{$vnam};
if ($vnam =~ m/[A-Z][A-Z0-9_]*/) {
return $ENV{$vnam} if exists $ENV{$vnam};
}
tpre(sprintf "tbrun-E: can't replace '$vnam'\n");
exit 2;
}
#-------------------------------------------------------------------------------
sub expand_vars {
my ($txt,$hrefs) = @_;
my $res = '';
while ($txt ne '') {
if ($txt =~ m/\$\{([a-zA-Z][a-zA-Z0-9_]*)\}/) {
my $vnam = $1;
my $vrep = lookup_var($vnam, $hrefs);
$res .= $`;
$res .= $vrep;
$txt = $';
} else {
$res .= $txt;
last;
}
}
return $res;
}
#-------------------------------------------------------------------------------
sub merge_lines {
my ($txt) = @_;
$txt =~ s|\s*\\\n\s*| |mg;
chomp $txt;
return $txt;
}
#-------------------------------------------------------------------------------
sub merge_expand {
my ($txt,$hrefs) = @_;
return expand_vars(merge_lines($txt), $hrefs);
}
#-------------------------------------------------------------------------------
sub key_or_def {
my ($tag,$yele,$defhash) = @_;
return $yele->{$tag} if exists $yele->{$tag};
return $defhash->{$tag} if exists $defhash->{$tag};
return undef;
}
#-------------------------------------------------------------------------------
sub handle_include {
my ($yele) = @_;
check_keys($yele, \%keys_include) or exit 2;
my $fnam = merge_expand($yele->{include}, undef);
include_file($fnam);
return;
}
#-------------------------------------------------------------------------------
sub handle_default {
my ($yele, $defhash) = @_;
check_keys($yele, \%keys_default) or exit 2;
check_keys($yele->{default}, \%keys_defhash) or exit 2;
foreach my $key (keys %{$yele->{default}}) {
$$defhash{$key} = $$yele{default}{$key};
}
return;
}
#-------------------------------------------------------------------------------
sub handle_itest {
my ($yele, $defhash) = @_;
check_keys($yele, \%keys_itest) or exit 2;
$nseen += 1;
my $tlist = key_or_def('tag', $yele, $defhash);
if (defined $tlist) {
return unless check_tagfilter(\@tagincl, $tlist);
return if check_tagfilter(\@tagexcl, $tlist);
}
my $mlist = merge_expand(key_or_def('mode', $yele, $defhash), undef);
foreach my $mode (@modelist) {
next unless check_modefilter($mode, $mlist);
my $ms = '_' . $mode;
$ms =~ s/_bsim$//;
$gblvars{ms} = $ms;
my $test = merge_expand($yele->{test}, undef);
# forward options for tbrun_tbw or tbrun_tbwrri commands
if ($test =~ m/^\s*(tbrun_tbw|tbrun_tbwrri)\s+(.*)$/) {
my $cmd = $1;
my $rest = $2;
$test = $cmd;
$test .= ' --nomake' if $opts{nomake};
$test .= ' --norun' if $opts{norun};
if ($cmd eq 'tbrun_tbwrri') {
$test .= ' --rlmon' if $opts{rlmon};
$test .= ' --rbmon' if $opts{rbmon};
$test .= ' --bwait '.$opts{bwait} if $opts{bwait};
$test .= ' --swait '.$opts{swait} if $opts{swait};
}
$test .= ' ' . $rest;
}
my $tid = scalar(@tlist);
my $tmsg = sprintf "t%03d - tags: ", $tid;
$tmsg .= join ',',@$tlist if defined $tlist;
my %titem;
$titem{id} = $tid;
$titem{cd} = getcwd();
$titem{test} = $test;
$titem{tag} = $tlist;
$titem{tmsg} = $tmsg;
push @{$titem{locks}}, $titem{cd};
push @tlist, \%titem;
delete $gblvars{ms};
}
return;
}
#-------------------------------------------------------------------------------
sub tpr {
my ($txt) = @_;
print $txt;
print $fh_tee $txt if defined $fh_tee;
return;
}
#-------------------------------------------------------------------------------
sub tpre {
my ($txt) = @_;
print STDERR $txt;
print $fh_tee $txt if defined $fh_tee;
return;
}
#-------------------------------------------------------------------------------
sub max {
my ($a,$b) = @_;
return ($a > $b) ? $a : $b;
}
#-------------------------------------------------------------------------------
sub open_job_fh {
my ($cmd) = @_;
my $fh = new FileHandle;
# add STDERR->STDOUT redirect (create sub shell of needed)
$cmd = '(' . $cmd . ')' if $cmd =~ m/\n/g;
$cmd .= ' 2>&1';
# open returns pid of created process in case an in or out pipe is created
my $pid = open $fh, '-|', $cmd;
# print "+++1 $pid\n";
if (not $pid) {
my $err = $!;
my $msg = sprintf "tbrun-E: failed to start '%s'\n cwd: %s\n error: %s\n",
$cmd, getcwd(), $err;
return (undef, undef, $msg);
}
return ($fh, $pid, undef);
}
#-------------------------------------------------------------------------------
sub run_tests_single {
my $drycd = '';
foreach my $titem (@tlist) {
my $cdir = $titem->{cd};
my $test = $titem->{test};
chdir $inicwd or die "chdir to '$inicwd' failed with '$!'";
if ($opts{dry}) {
if ($cdir ne $drycd) {
tpr("#------------------------------------------------------------\n");
tpr("cd $cdir\n");
$drycd = $cdir;
}
tpr("#----------------------------------------\n");
tpr("# $titem->{tmsg}\n");
tpr("$test\n");
} else {
tpr("#----------------------------------------\n");
tpr("# $titem->{tmsg}\n");
$ndone += 1;
my $cmd = '';
$cmd .= "cd $cdir";
$cmd .= "\n";
$cmd .= "$test";
my ($fh,$pid,$msg) = open_job_fh($cmd);
if (not defined $fh) {
tpre($msg);
} else {
while (<$fh>) {
print $_;
}
if (not close $fh) {
my $err = $?;
tpr(sprintf "tbrun-I: test FAILed with exit status %d,%d\n",
($err>>8), ($err&0xff));
$nfail += 1;
}
}
}
}
if ($opts{dry}) {
tpr("#------------------------------------------------------------\n");
tpr(sprintf "cd %s\n", $inicwd);
}
return;
}
#-------------------------------------------------------------------------------
sub print_ticker {
return unless $ticker_on;
my ($rwlist) = @_;
my $msg = '';
state $lastlength = 0;
if (defined $rwlist) {
my $time_now = gettimeofday();
$msg = '#-I: ' . join '; ', map {
sprintf('t%03d: %dl %3.1fs',
$_->{id}, $_->{nlines}, $time_now-$_->{tstart})
} @$rwlist;
$msg = substr($msg,0,75) . ' ...' if length($msg) >79;
unless (defined $opts{trace}) {
my $suff = sprintf '(%dt,%dw,%do)',
scalar(@tlist), scalar(@wlist), scalar(@olist);
if (length($suff) + length($msg) + 1 <= 79) {
$msg .= ' ' . $suff;
} else {
$msg = substr($msg,0,79-6-length($suff)) . ' ... ' . $suff;
}
}
}
my $newlength = length($msg);
$msg .= ' ' x ($lastlength - $newlength) if $lastlength > $newlength;
print $msg . "\r";
$lastlength = $newlength;
return;
}
#-------------------------------------------------------------------------------
sub print_jobs {
while (defined $olist[0]->{exitcode}) {
print_ticker();
my $titem = shift @olist;
tpr("#----------------------------------------\n");
tpr("# $titem->{tmsg}\n");
tpr($titem->{out});
}
return;
}
#-------------------------------------------------------------------------------
sub print_trace {
my ($titem) = @_;
my $pref = '';
my $suff = sprintf '(%dt,%dw,%do)',
scalar(@tlist), scalar(@wlist), scalar(@olist);
if (defined $titem->{exitcode}) {
$pref = ($titem->{exitcode}==0) ? 'pass ' : 'FAIL ';
} else {
$pref = 'start';
}
my $txt = '#-I: ' . $pref . ' ' . $titem->{tmsg};
$txt .= ' ' . $suff;
$txt .= "\n";
print_ticker();
tpr($txt);
return;
}
#-------------------------------------------------------------------------------
sub start_jobs {
# initialize lock hash
my %locks;
foreach my $titem (@wlist) {
foreach my $lock (@{$titem->{locks}}) {
$locks{$lock} = 1;
}
}
# look for suitable tasks
for (my $i=0; $i < scalar(@tlist) && scalar(@wlist) < $opts{jobs}; ) {
my $titem = $tlist[$i];
my $nlock = 0;
foreach my $lock (@{$titem->{locks}}) {
if ($locks{$lock}) {
$nlock += 1;
last;
}
}
# suitable task found
if ($nlock == 0) {
my $cdir = $titem->{cd};
my $test = $titem->{test};
$ndone += 1;
my $cmd = '';
if ($opts{dry}) {
$cmd .= "cd $cdir";
$cmd .= "\n";
$cmd .= "perl -e 'select(undef, undef, undef, 0.2+1.6*rand( 1.))'";
$cmd .= "\n";
$cmd .= "echo \"cd $cdir\"";
$cmd .= "\n";
$cmd .= "echo \"$test\"";
} else {
$cmd .= "cd $cdir";
$cmd .= "\n";
$cmd .= "$test";
}
# start job
my ($fh,$pid,$msg) = open_job_fh($cmd);
if (not defined $fh) {
$titem->{out} = $msg;
$titem->{exitcode} = 1;
print_trace($titem) if $opts{trace};
print_jobs();
} else {
$titem->{fh} = $fh;
$titem->{fd} = fileno($fh);
$titem->{pid} = $pid;
$titem->{out} = '';
$titem->{tstart} = gettimeofday();
$titem->{nlines} = 0;
push @wlist, $titem;
foreach my $lock (@{$titem->{locks}}) {
$locks{$lock} = 1;
}
print_trace($titem) if $opts{trace};
}
splice @tlist, $i, 1; # remove from tlist
next; # and re-test i'th list element
} # if ($nlock == 0)
$i += 1; # inspect nexyt list element
} # for (my $i=0; ...
return;
}
#-------------------------------------------------------------------------------
sub kill_job {
my ($titem, $trun) = @_;
my $pid = $titem->{pid};
my $pgid = getpgrp(0);
my %phash;
$titem->{killed} = $trun;
# get process tree data (for whole user, no pgid filtering possible
my $rank = 0;
open PS,"ps -H -o pid,ppid,pgid,comm --user $ENV{USER}|";
while (<PS>) {
chomp;
next unless m/^\s*(\d+)\s+(\d+)\s+(\d+)\s(.*)$/;
my $cpid = $1;
my $cppid = $2;
my $cpgid = $3;
my $cargs = $4;
next unless $cpgid == $pgid; # only current process group
next if $cargs =~ m/^\s*ps\s*$/; # skip the 'ps' process itself
$phash{$cpid}->{ppid} = $cppid;
$phash{$cpid}->{pgid} = $cpgid;
$phash{$cpid}->{args} = $cargs;
$phash{$cpid}->{rank} = $rank++;
push @{$phash{$cppid}->{childs}}, $cpid;
}
close PS;
# sanity check 1: own tbrun process should be included
unless (exists $phash{$$}) {
print_ticker();
printf "-E: tmax kill logic error: tbrun master pid not in phash\n";
return;
}
# sanity check 2: job to be killed should be child of master tbrun
unless ($phash{$pid}->{ppid} == $$) {
print_ticker();
printf "-E: tmax kill logic error: job not child of tbrun\n";
return;
}
# determine number of leading blanks in master tbrun line
my $nstrip = 0;
$nstrip = length($1) if ($phash{$$}->{args} =~ m/^(\s*)/);
# recursively mark all childs of job master
my @pids = ($pid);
while (scalar(@pids)) {
my $cpid = shift @pids;
if (not exists $phash{$cpid}) {
print_ticker();
printf "-E: tmax kill logic error: child pid not in phash\n";
return;
}
$phash{$cpid}->{kill} = 1;
if (exists $phash{$cpid}->{childs}) {
push @pids, @{$phash{$cpid}->{childs}};
}
}
# build list of pid to be killed, and trace message
my @kpids;
my @ktext;
foreach my $cpid (sort {$phash{$a}->{rank} <=> $phash{$b}->{rank} }
grep {$phash{$_}->{kill}}
keys %phash) {
push @kpids, $cpid;
push @ktext, sprintf "# %6d %6d %6d %s",
$cpid, $phash{$cpid}->{ppid},
$phash{$cpid}->{pgid},
substr($phash{$cpid}->{args}, $nstrip);
}
# print trace message, if selected
if ($opts{trace}) {
print_ticker();
printf "#-I: kill t%03d after %3.1fs, kill proccesses:\n",
$titem->{id}, $trun, join("\n");
print "# pid ppid pgid command\n";
print join("\n",@ktext) . "\n";
}
# and finally kill all processes of the job
kill 'TERM', @kpids;
return;
}
#-------------------------------------------------------------------------------
sub run_tests_multi {
@olist = @tlist;
while (scalar(@tlist) || scalar(@wlist)) { # while something to do
# start new jobs, if available and job slots free
start_jobs();
my @fhlist = map { $_->{fh} } @wlist;
my %fdhash;
foreach my $titem (@wlist) {
$fdhash{$titem->{fd}} = $titem;
}
my $sel = IO::Select->new(@fhlist);
my $neof = 0;
my $time_ticker = gettimeofday() + 0.1;
while ($neof == 0) {
my $wait_ticker = max(0.1, $time_ticker - gettimeofday() + 0.1);
my @fhlist = $sel->can_read($wait_ticker);
my $time_now = gettimeofday();
if ($time_now >= $time_ticker) {
print_ticker(\@wlist);
$time_ticker = $time_now + 0.9;
}
foreach my $fh (@fhlist) {
my $fd = fileno($fh);
my $titem = $fdhash{$fd};
my $buf = '';
my $nb = sysread $fh, $buf, 1024;
# data read
if ($nb) {
$titem->{out} .= $buf;
$titem->{nlines} += ($buf =~ tr/\n/\n/); # count \n in $buf
# eof or error
} else {
if (defined $titem->{killed}) {
$titem->{out} .= sprintf
"tbrun-I: test killed after %3.1fs\n", $titem->{killed};
}
if (not close $fh) {
my $err = $?;
$titem->{out} .= sprintf
"tbrun-I: test FAILed with exit status %d,%d\n",
($err>>8), ($err&0xff);
$nfail += 1;
$titem->{exitcode} = $err;
} else {
$titem->{exitcode} = 0;
}
$neof += 1;
for (my $i=0; $i < scalar(@wlist); $i++) {
next unless $wlist[$i]->{fd} == $fd;
splice @wlist, $i, 1;
last;
}
print_trace($titem) if $opts{trace};
}
} # foreach my $fh ...
# handle tmax
if (defined $opts{tmax}) {
foreach my $titem (@wlist) {
my $trun = $time_now - $titem->{tstart};
if ($trun > $opts{tmax}) {
kill_job($titem, $trun) unless defined $titem->{killed};
}
}
}
} # while ($neof == 0)
# here if at least one job finished
print_jobs();
}
return;
}

View File

@@ -1,11 +1,15 @@
#!/bin/bash
# $Id: tbrun_tbw 779 2016-06-26 15:37:16Z mueller $
# $Id: tbrun_tbw 807 2016-09-17 07:49:26Z mueller $
#
# Copyright 2014-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Version Comment
# 2016-09-03 805 1.2.2 add TIMEFORMAT and time for make commands
# 2016-08-21 800 1.2.1 add -norun, -nomake
# 2016-08-06 795 1.2 use tbfilt; fixup -lsuf logic
# 2016-07-03 782 1.1.4 drop ghdl_assert_filter (use --ieee=... at ghdl lvl)
# 2016-06-25 778 1.1.3 drop make ghdl_tmp_clean logic
# 2016-06-05 773 1.1.2 use _bsim.log for behavioral sim log
# 2016-04-17 762 1.1.1 don't create '-run' for [IX]Sim anymore (now default)
@@ -16,13 +20,17 @@
docmd ()
{
echo "$1"
if [[ -z "$optdry" ]] ; then
echo "$2"
eval "$1"
else
echo "$1"
fi
}
optdry=""
optnomake=""
optnorun=""
optlsuf=""
optstack=""
optghw=""
@@ -32,12 +40,14 @@ optpcom=""
# handle options
while (( $# > 0 )) ; do
case $1 in
-dry|--dry) optdry=$1 ; shift 1 ;;
-lsuf|--lsuf) optlsuf=$2 ; shift 2 ;;
-stack|--stack) optstack=$2 ; shift 2 ;;
-ghw|--ghw) optghw=$2 ; shift 2 ;;
-tbw|--tbw) opttbw=$2 ; shift 2 ;;
-pcom|--pcom) optpcom=$1 ; shift 1 ;;
-dry|--dry) optdry=$1 ; shift 1 ;;
-nomake|--nomake) optnomake=$1 ; shift 1 ;;
-norun|--norun) optnorun=$1 ; shift 1 ;;
-lsuf|--lsuf) optlsuf=$2 ; shift 2 ;;
-stack|--stack) optstack=$2 ; shift 2 ;;
-ghw|--ghw) optghw=$2 ; shift 2 ;;
-tbw|--tbw) opttbw=$2 ; shift 2 ;;
-pcom|--pcom) optpcom=$1 ; shift 1 ;;
-*) echo "tbrun_tbw-E: invalid option '$1'"; exit 1 ;;
*) break;;
esac
@@ -51,10 +61,13 @@ if (( $# == 0 )) ; then
echo "Usage: tbrun_tbw [opts] testbench [stimfile]"
echo " Options:"
echo " --dry dry run, print commands, don't execute"
echo " --nomake don't execute make step"
echo " --norun don't execute run step"
echo " --lsuf suff use '_<suff>.log' as suffix for log file"
echo " --stack nnn use <nnn> as ghdl stack size"
echo " --ghw fname write ghw file with name '<fname>.ghw"
echo " --tbw opts append <opts> to tbw command"
echo " --pcom print test comments"
exit 1
fi
@@ -80,30 +93,44 @@ if [[ $tbench =~ _XSim ]] ; then
fi
# issue makes
docmd "make $makeopts $tbench"
exitstat=$?
if [[ -z "$optnomake" ]] ; then
cmd="TIMEFORMAT=$'real %3lR user %3lU sys %3lS'"
cmd+=$'\n'
cmd+="time make $makeopts $tbench"
docmd "$cmd"
exitstat=$?
if (( $exitstat > 0 )) ; then exit $exitstat; fi
echo ""
fi
if (( $exitstat > 0 )) ; then exit $exitstat; fi
# check for test bench
if [[ ! -x $tbench ]] ; then
echo "tbrun_tbw-E: $tbench not existing or not executable"
exit 1
fi
# determine logfile name
logsuff="_bsim"
if [[ $tbench =~ _[fsorept]sim$ ]] ; then logsuff=""; fi
if [[ -n "$optlsuf" ]] ; then logsuff="_$optlsuf"; fi
if [[ -n "$optlsuf" ]] ; then logsuff+="_$optlsuf"; fi
logfile="${tbench}${logsuff}.log"
# now build actual test command (a tbw|filter|tee|egrep pipe)
cmd="time tbw $tbench"
if [[ -n "$stimfile" ]] ; then cmd+=" $stimfile"; fi
if [[ -n "$opttbw" ]] ; then cmd+=" $opttbw"; fi
if [[ -n "$optstack" ]] ; then cmd+=" --stack-max-size=$optstack"; fi
if [[ -n "$optghw" ]] ; then cmd+=" --wave=$optghw.ghw"; fi
cmd+=" 2>&1"
if [[ -n "$isghdl" ]] ; then cmd+=" | ghdl_assert_filter"; fi
cmd+=" | tee $logfile"
# now build actual test command (a tbw | tbfilt pipe)
cmdtb="tbw $tbench"
if [[ -n "$stimfile" ]] ; then cmdtb+=" $stimfile"; fi
if [[ -n "$opttbw" ]] ; then cmdtb+=" $opttbw"; fi
if [[ -n "$optstack" ]] ; then cmdtb+=" --stack-max-size=$optstack"; fi
if [[ -n "$optghw" ]] ; then cmdtb+=" --wave=$optghw.ghw"; fi
cmdtb+=" 2>&1"
pcomtag=""
if [[ -n "$optpcom" ]] ; then pcomtag="^C|"; fi
# FAIL, PASS, DONE come from tbs; ERROR comes from ISim
cmd+=" | egrep \"(${pcomtag}-[EFW]:|ERROR|FAIL|PASS|DONE)\""
docmd "$cmd"
cmdtf="tbfilt -tee $logfile"
if [[ -n "$optpcom" ]] ; then cmdtf+=" -pcom"; fi
cmd="(export TIMEFORMAT=$'real %3lR user %3lU sys %3lS'; time $cmdtb) 2>&1"
cmd+=" | $cmdtf"
txt="$cmdtb | $cmdtf"
if [[ -z "$optnorun" ]] ; then
docmd "$cmd" "$txt"
fi

View File

@@ -1,14 +1,19 @@
#!/bin/bash
# $Id: tbrun_tbwrri 778 2016-06-25 15:18:01Z mueller $
# $Id: tbrun_tbwrri 808 2016-09-17 13:02:46Z mueller $
#
# Copyright 2014-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Version Comment
# 2016-09-17 808 1.3.3 add --r(l|b)mon,(b|s)wait; configure now via _conf=
# 2016-09-03 805 1.3.2 add TIMEFORMAT and time for make commands
# 2016-08-21 800 1.3.1 add -norun, -nomake
# 2016-08-06 795 1.3 use tbfilt; fixup -lsuf logic
# 2016-07-03 783 1.2.5 drop ghdl_assert_filter (use --ieee=... at ghdl lvl)
# 2016-06-25 778 1.2.4 drop make ghdl_tmp_clean logic
# 2016-06-18 776 1.2.3 use ti_rri --tout to set connection timeout
# 2016-06-05 773 1.2.2 use _bsim.log for behavioural sim log
# 2016-06-05 773 1.2.2 use _bsim.log for behavioral sim log
# 2016-03-20 748 1.2.1 BUGFIX: add portsel oob for -hxon
# use 120 sec timeout for simulation
# 2016-03-18 745 1.2 use --sxon and --hxon instead of --xon
@@ -26,13 +31,17 @@ chkval ()
docmd ()
{
echo "$1"
if [[ -z "$optdry" ]] ; then
echo "$2"
eval "$1"
else
echo "$1"
fi
}
optdry=""
optnomake=""
optnorun=""
optlsuf=""
optstack=""
optghw=""
@@ -44,23 +53,33 @@ optcuff=""
optfusp=""
optsxon=""
opthxon=""
optrlmon=""
optrbmon=""
optbwait=0
optswait=0
# handle options
while (( $# > 0 )) ; do
case $1 in
-dry|--dry) optdry=$1 ; shift 1 ;;
-lsuf|--lsuf) optlsuf=$2 ; chkval $2 ; shift 2 ;;
-stack|--stack) optstack=$2 ; chkval $2 ; shift 2 ;;
-ghw|--ghw) optghw=$2 ; chkval $2 ; shift 2 ;;
-tbw|--tbw) opttbw=$2 ; chkval $2 ; shift 2 ;;
-pack|--pack) optpack=$2 ; chkval $2 ; shift 2 ;;
-rri|--rri) optrri=$2 ; chkval $2 ; shift 2 ;;
-cuff|--cuff) optcuff=$1 ; shift 1 ;;
-fusp|--fusp) optfusp=$1 ; shift 1 ;;
-sxon|--sxon) optsxon=$1 ; shift 1 ;;
-hxon|--hxon) opthxon=$1 ; shift 1 ;;
-pcom|--pcom) optpcom=$1 ; shift 1 ;;
-\?|-h*|--h*) opthelp=$1 ; shift 1 ;;
-dry|--dry) optdry=$1 ; shift 1 ;;
-nomake|--nomake) optnomake=$1 ; shift 1 ;;
-norun|--norun) optnorun=$1 ; shift 1 ;;
-lsuf|--lsuf) optlsuf=$2 ; chkval $2 ; shift 2 ;;
-stack|--stack) optstack=$2 ; chkval $2 ; shift 2 ;;
-ghw|--ghw) optghw=$2 ; chkval $2 ; shift 2 ;;
-tbw|--tbw) opttbw=$2 ; chkval $2 ; shift 2 ;;
-pack|--pack) optpack=$2 ; chkval $2 ; shift 2 ;;
-rri|--rri) optrri=$2 ; chkval $2 ; shift 2 ;;
-cuff|--cuff) optcuff=$1 ; shift 1 ;;
-fusp|--fusp) optfusp=$1 ; shift 1 ;;
-sxon|--sxon) optsxon=$1 ; shift 1 ;;
-hxon|--hxon) opthxon=$1 ; shift 1 ;;
-pcom|--pcom) optpcom=$1 ; shift 1 ;;
-rlmon|--rlmon) optrlmon=$1 ; shift 1 ;;
-rbmon|--rbmon) optrlmon=$1 ; shift 1 ;;
-bwait|--bwait) optbwait=$2 ; chkval $2 ; shift 2 ;;
-swait|--swait) optswait=$2 ; chkval $2 ; shift 2 ;;
-\?|-h*|--h*) opthelp=$1 ; shift 1 ;;
-*) echo "tbrun_tbwrri-E: invalid option '$1'"; exit 1 ;;
*) break;;
esac
@@ -71,6 +90,8 @@ if [[ -n "$opthelp" || $# -eq 0 ]] ; then
echo "Usage: tbrun_tbwrri [opts] testbench rricmds..."
echo " Options:"
echo " --dry dry run, print commands, don't execute"
echo " --nomake don't execute make step"
echo " --norun don't execute run step"
echo " --lsuf suff use '_<suff>.log' as suffix for log file"
echo " --stack nnn use <nnn> as ghdl stack size"
echo " --ghw fname write ghw file with name '<fname>.ghw'"
@@ -82,6 +103,10 @@ if [[ -n "$opthelp" || $# -eq 0 ]] ; then
echo " --sxon use xon with 1st serport (via SWI(1))"
echo " --hxon use xon with 1st serport (hardwired)"
echo " --pcom print test comments"
echo " --rlmon enable rlmon"
echo " --rbmon enable rbmon"
echo " --bwait ns start-up wait in ns for behavioral simulations"
echo " --swait ns start-up wait in ns for post-syn simulations"
exit 1
fi
@@ -99,86 +124,116 @@ fi
tbench=$1
shift 1
makeopts=""
tbenchname=$(basename $tbench)
tbenchpath=$(dirname $tbench)
# issue makes
docmd "make -C $tbenchpath $tbenchname"
exitstat=$?
# add -C $tbenchpath only if not '.' to avoid 'Entering/Leaving' messages
makeopts=""
if [[ "$tbenchpath" != "." ]] ; then
makeopts="-C $tbenchpath"
fi
if [[ -z "$optnomake" ]] ; then
cmd="TIMEFORMAT=$'real %3lR user %3lU sys %3lS'"
cmd+=$'\n'
cmd+="time make $makeopts $tbench"
docmd "$cmd"
exitstat=$?
if (( $exitstat > 0 )) ; then exit $exitstat; fi
echo ""
fi
if (( $exitstat > 0 )) ; then exit $exitstat; fi
# check for test bench
if [[ ! -x $tbench ]] ; then
echo "tbrun_tbwrri-E: $tbench not existing or not executable"
exit 1
fi
# determine logfile name
# determine logfile name and determine startup wait (bwait or swait)
logsuff="_bsim"
if [[ $tbenchname =~ _[sft]sim$ ]] ; then logsuff=""; fi
if [[ -n "$optlsuf" ]] ; then logsuff="_$optlsuf"; fi
waitns=$optbwait
if [[ $tbenchname =~ _[fsorept]sim$ ]] ; then
logsuff=""
waitns=$optswait
fi
if [[ -n "$optlsuf" ]] ; then logsuff+="_$optlsuf"; fi
logfile="${tbenchname}${logsuff}.log"
# determine simbus configure (done with inline mode _conf={l1;l2;l3})
# Note: .sdata expects hex in full signal size (addr 8 bit, data 16 bit)
conf=""
if [[ -n "$optcuff" ]] ; then
conf+=".sdata 08 0004;" # portsel = 0100 -> fx2
conf+=".sdata 10 0004;" # swi = 0100 -> fx2
fi
if [[ -n "$optfusp" ]] ; then
conf+=".sdata 08 0001;" # portsel = 0001 -> 2nd ser
conf+=".sdata 10 0001;" # swi = 0001 -> 2nd ser
fi
if [[ -n "$optsxon" ]] ; then
conf+=".sdata 08 0002;" # portsel = 0010 -> 1st ser XON
conf+=".sdata 10 0002;" # swi = 0010 -> 1st ser XON
fi
if [[ -n "$opthxon" ]] ; then
conf+=".sdata 08 0002;" # portsel = 0010 -> 1st ser XON
fi
if (( $waitns > 0 )) ; then
conf+=".wait $waitns ns;"
fi
# now build actual test command
cmd="time ti_rri --run=\"tbw $tbench -fifo"
if [[ -n "$opttbw" ]] ; then cmd+=" $opttbw"; fi
if [[ -n "$optstack" ]] ; then cmd+=" --stack-max-size=$optstack"; fi
cmdtb+="ti_rri --run=\"tbw $tbench -fifo"
if [[ -n "$conf" ]] ; then cmdtb+=" '_conf={$conf}'"; fi
if [[ -n "$opttbw" ]] ; then cmdtb+=" $opttbw"; fi
if [[ -n "$optstack" ]] ; then cmdtb+=" --stack-max-size=$optstack"; fi
if [[ -n "$optghw" ]] ; then
if [[ "$optghw" != *.ghw ]]; then optghw="$optghw.ghw"; fi
cmd+=" --wave=$optghw";
cmdtb+=" --wave=$optghw";
fi
cmd+=" 2>&1 | ghdl_assert_filter\""
cmdtb+=" 2>&1 \""
# Note: the following ensurs that we always have 'fifo=,<options>' with an
# empty first field (the default fifo name)
fifoopts=""
if [[ -n "$opthxon" ]] ; then fifoopts+=",xon"; fi
if [[ -n "$optsxon" ]] ; then fifoopts+=",xon"; fi
if (( $ncfxcount > 0 )) ; then fifoopts+=",noinit"; fi
if [[ -n "$fifoopts" ]] ; then
cmd+=" --fifo=$fifoopts"
cmdtb+=" --fifo=$fifoopts"
else
cmd+=" --fifo"
cmdtb+=" --fifo"
fi
cmd+=" --logl=3"
cmd+=" --tout=120." # 120 sec timeout for simulation
cmdtb+=" --logl=3"
cmdtb+=" --tout=120." # 120 sec timeout for simulation
if [[ -n "$optpack" ]] ; then cmd+=" --pack=$optpack"; fi
if [[ -n "$optrri" ]] ; then cmd+=" $optrri"; fi
if [[ -n "$optpack" ]] ; then cmdtb+=" --pack=$optpack"; fi
if [[ -n "$optrri" ]] ; then cmdtb+=" $optrri"; fi
cmd+=" --"
if [[ -n "$optcuff" ]] ; then
cmd+=" \"rlc oob -sbdata 8 0x4\"" # portsel = 0100 -> fx2
cmd+=" \"rlc oob -sbdata 16 0x4\"" # swi = 0100 -> fx2
fi
if [[ -n "$optfusp" ]] ; then
cmd+=" \"rlc oob -sbdata 8 0x1\"" # portsel = 0001 -> 2nd ser
cmd+=" \"rlc oob -sbdata 16 0x1\"" # swi = 0001 -> 2nd ser
fi
if [[ -n "$optsxon" ]] ; then
cmd+=" \"rlc oob -sbdata 8 0x2\"" # portsel = 0010 -> 1st ser XON
cmd+=" \"rlc oob -sbdata 16 0x2\"" # swi = 0010 -> 1st ser XON
fi
if [[ -n "$opthxon" ]] ; then
cmd+=" \"rlc oob -sbdata 8 0x2\"" # portsel = 0010 -> 1st ser XON
fi
if (( $ncfxcount > 0 )) ; then cmd+=" \"rlc init\""; fi
cmdtb+=" --"
while (( $# > 0 )) ; do
cmd+=" "
if [[ $1 =~ " " ]] ; then cmd+="\""; fi
cmd+="$1"
if [[ $1 =~ " " ]] ; then cmd+="\""; fi
cmdtb+=" "
if [[ $1 =~ " " ]] ; then cmdtb+="\""; fi
cmdtb+="$1"
if [[ $1 =~ " " ]] ; then cmdtb+="\""; fi
shift 1
done
cmd+=" | tee $logfile"
pcomtag=""
if [[ -n "$optpcom" ]] ; then pcomtag="^\#|"; fi
# FAIL, PASS, DONE come from tbs
cmd+=" | egrep \"(${pcomtag}-[EFW]:|FAIL|PASS|DONE)\""
docmd "$cmd"
cmdtf="tbfilt -tee $logfile"
if [[ -n "$optpcom" ]] ; then cmdtf+=" -pcom"; fi
cmd="(export TIMEFORMAT=$'real %3lR user %3lU sys %3lS'; time $cmdtb) 2>&1"
cmd+=" | $cmdtf"
txt="$cmdtb | $cmdtf"
if [[ -z "$optnorun" ]] ; then
docmd "$cmd" "$txt"
fi

View File

@@ -1,5 +1,5 @@
#!/usr/bin/perl -w
# $Id: tbw 778 2016-06-25 15:18:01Z mueller $
# $Id: tbw 808 2016-09-17 13:02:46Z mueller $
#
# Copyright 2007-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
@@ -14,6 +14,9 @@
#
# Revision History:
# Date Rev Version Comment
# 2016-09-03 805 1.5.4 use {} as delimiter for immediate mode data
# 2016-08-28 804 1.5.3 BUGFIX: xsim: append -R to ARGV (was prepended...)
# 2016-07-02 782 1.5.2 add TBW_GHDL_OPTS
# 2016-06-25 778 1.5.1 support all sim modes
# 2016-04-17 762 1.5 make '-run' default for [IX]Sim, add '-norun'
# 2016-03-20 748 1.4 recode OPTIONS handling and -fifo handling
@@ -50,9 +53,10 @@ use File::Spec;
use Cwd 'abs_path';
my $tb_code;
my $is_isim;
my $is_ghdl; # uses ghdl simulator
my $is_isim; # uses ISE simulator
my $is_isim_run;
my $is_xsim;
my $is_xsim; # uses vivado simulator
my $opt_run;
my $opt_norun;
my $opt_fifo;
@@ -62,6 +66,8 @@ my @args_pos; # list of positional args
my @args_nam; # list of named args
my @file_dsc; # file descriptors from tbw.dat
my $ghdl_opts = $ENV{TBW_GHDL_OPTS}; # ghdl extra options
sub print_usage;
autoflush STDOUT 1; # autoflush, so nothing lost on exec later
@@ -87,7 +93,7 @@ if ($tb_code =~ m|^(.*)/(.*)$|) {
$tb_code_name = $2;
}
# process -run, -fifo and -verbose options (can be in any order now)
# process -norun, -fifo and -verbose options (can be in any order now)
while (scalar(@ARGV)) {
my $opt = $ARGV[0];
@@ -113,9 +119,11 @@ if ($tb_code_stem =~ /_ISim$/) { # is it an ISim executable ?
if ($tb_code_stem =~ /_XSim$/) { # is it an XSim executable ?
$tb_code_stem =~ s/_XSim$//; # drop _XSim
$is_xsim = 1;
unshift @ARGV,'-R' unless $opt_norun; # run all unless '-norun' given
push @ARGV,'-R' unless $opt_norun; # run all unless '-norun' given
}
$is_ghdl = not ($is_isim or $is_xsim);
if (not -e $tb_code) {
print "tbw-E: $tb_code not existing or not executable\n";
print_usage;
@@ -151,7 +159,7 @@ if (-r $tbwdat_file) {
}
}
} else {
print "tbw-W: failed to find $tbwdat_file\n";
print "tbw-I: didn't find ${tbwdat_file}, using defaults\n";
}
#
@@ -228,7 +236,7 @@ foreach my $dsc (@file_dsc) {
} else { # handle link to file cases
if ($val =~ /^\[(.*)\]$/) { # immediate data case: "[line1;line2;...]"
if ($val =~ /^\{(.*)\}$/) { # immediate data case: "{line1;line2;...}"
my @lines = split /;/, $1;
my $fname = "$tag\_tmp.tmp";
open TFILE,">$fname" or die "can't create temporary file $fname: $!";
@@ -256,7 +264,7 @@ foreach my $dsc (@file_dsc) {
}
if (not -r $val) {
print "tbw-F: file for $tag not existing or not readable: $val\n";
print "tbw-F: file for '$tag' not existing or not readable: $val\n";
exit 1;
}
@@ -282,6 +290,13 @@ foreach my $dsc (@file_dsc) {
}
}
#
# additional ghdl options
#
if ($is_ghdl && defined $ghdl_opts) {
push @ARGV, split /\s+/,$ghdl_opts;
}
#
# here all ok, finally exec test bench
#
@@ -296,6 +311,7 @@ if ($is_isim_run) { # handle for isim 'run all'
or die "failed to close process pipe to isim: $!";
} else { # otherwise just exec
# print ($tb_code . " " . join(" ",@ARGV) . "\n");
exec $tb_code,@ARGV
or die "failed to exec: $!";
}
@@ -304,13 +320,13 @@ if ($is_isim_run) { # handle for isim 'run all'
sub print_usage {
print "usage: tbw <tb_code> [opts] [filedefs] [ghdl-opts]\n";
print " opts\n";
print " -run for _ISim tb's, runs the tb with a 'run all' command\n";
print " -norun for _ISim tb's, runs the tb without 'run all' command\n";
print " -fifo use rlink_cext fifo, ignore tbw.dat\n";
print " -verbose show the used tag,value settings before execution\n";
print " filedefs define tb input, either filename in tbw.dat order or\n";
print " tag=name or tag=[<content>] pairs with tag matching one in in\n";
print " tbw.dat. The [<content>] form allows to give data inline, e.g.\n";
print " like \"_conf=[.rpmon 1]\"\n";
print " like \"_conf={.rpmon 1}\"\n";
print " ghdl-opts are all other options starting with a '-', they are\n";
print " passed to the testbench. Some useful ghdl options are:\n";
print " --wave=x.ghw\n";

View File

@@ -1,6 +1,6 @@
#! /usr/bin/env tclshcpp
# -*- tcl -*-
# $Id: ti_rri 776 2016-06-18 17:22:51Z mueller $
# $Id: ti_rri 799 2016-08-21 09:20:19Z mueller $
#
# Copyright 2011-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
@@ -230,7 +230,7 @@ rlc set timeout $opts(tout_)
if { $opts(run_) ne "" } {
if { [catch {exec sh -c $opts(run_) &} runpid] } {
puts "-E: failed to execute \"$opts(run_)\" with error message\n $runpid"
puts "aborting..."
puts "-E: aborting..."
return 1
}
}
@@ -314,13 +314,13 @@ foreach cmd $clist {
if { [catch {source $filename} errmsg] } {
puts "-E: failed to source file \"$filename\" with error message:"
if {[info exists errorInfo]} {puts $errorInfo} else {puts $errmsg}
puts "aborting..."
puts "-E: aborting..."
break
}
# handle @file.dat ect --> not yet supported
} else {
puts "-E: only tcl supported but $filename found"
puts "aborting..."
puts "-E: aborting..."
break
}
@@ -329,7 +329,7 @@ foreach cmd $clist {
if { [catch {eval $cmd} errmsg] } {
puts "-E: eval of \"$cmd\" failed with error message:"
if {[info exists errorInfo]} {puts $errorInfo} else {puts $errmsg}
puts "aborting..."
puts "-E: aborting..."
break
}
}

View File

@@ -1,7 +1,7 @@
#!/usr/bin/perl -w
# $Id: ticonv_pdpcp 675 2015-05-08 21:05:08Z mueller $
# $Id: ticonv_pdpcp 795 2016-08-09 12:45:58Z mueller $
#
# Copyright 2013-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# Copyright 2013-2016 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
@@ -14,6 +14,7 @@
#
# Revision History:
# Date Rev Version Comment
# 2016-08-07 795 1.3.2 avoid GetOptions =f (bug in perl v5.22.1)
# 2015-05-08 675 1.3.1 start/stop/suspend overhaul
# 2015-04-03 661 1.3 adopt to new stat checking and mask polarity
# 2014-12-27 622 1.2.1 use wmembe now
@@ -34,7 +35,7 @@ use Getopt::Long;
my %opts = ();
GetOptions(\%opts, "tout=f", "cmax=i"
GetOptions(\%opts, "tout=s", "cmax=i"
)
or die "bad options";

546
tools/bin/ticonv_rri Executable file
View File

@@ -0,0 +1,546 @@
#!/usr/bin/perl -w
# $Id: ticonv_rri 795 2016-08-09 12:45:58Z mueller $
#
# Copyright 2014-2016 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 2, 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
# 2016-08-07 795 1.2.1 avoid GetOptions =f (bug in perl v5.22.1)
# 2015-04-03 661 1.2 adopt to new stat checking and mask polarity
# 2015-01-31 640 1.1.2 use 'rlc get|set' instead of 'rlc config'
# 2014-12-21 616 1.1.1 add .ndef and n= for BlockDone expects
# 2014-12-06 609 1.1 use .cmax and .eop; drop .cclst; (for rlink v4)
# 2014-08-09 580 1.0 Initial version
#
#-------------------------------------------------------------------------------
# handles the command:
#
# .mode rri
# .dbaso n
# .rlmon 0|1
# .rbmon 0|1
# .scntl n 0|1
#! .sinit g8 g16 !! NOT YET !!
# .sdef [s=g8]
# .ndef 0|1
# .amclr
# .amdef name g8
# .reset
# .wait n
# .wtlam n
# .cmax n
# .eop
# rreg <addr> [d=g16] [s=g8]
# wreg <addr> g16 [s=g8]
# rblk <addr> n [n=dd] [s=g8]
# followed by n d=g16 data check values
# wblk <addr> n [n=dd] [s=g8]
# followed by n g16 data values
# stat [d=g16] [s=d8]
# attn [d=g16] [s=d8]
# init <addr> g16 [s=g8]
#
use 5.005; # require Perl 5.005 or higher
use strict; # require strict checking
use Getopt::Long;
use FileHandle;
my %opts = ();
GetOptions(\%opts, "tout=s", "cmax=i"
)
or die "bad options";
sub cmdlist_do;
sub add_addr;
sub add_data;
sub add_edata;
sub add_edata;
sub cget_chkblank; # check for unused chars in cmd line
sub cget_tagval2_gdat; # get tag=v1[,v2], generic base
sub cget_tagval_gdat; # get tag=val, generic base
sub cget_gdat; # get generic base value
sub sget_bdat; # convert 01 string -> binary value
sub get_line;
my $cmd_line;
my $cmd_rest;
my $dbase = 2; # use binary as default data radix
my @cmdfh;
my @cmdlist;
if (scalar(@ARGV) != 1) {
print STDERR "ticonv_rri-E: usage: ticonv_rri <filename>\n";
exit 1;
}
my $fnam = $ARGV[0];
my $tout = $opts{tout} || 10.;
my $cmax = $opts{cmax} || 6;
my $ref_sdef = 0x00; # by default check for 'hard' errors
my $msk_sdef = 0xf8; # ignore the status bits + attn flag
my $chk_ndef = 1; # dcnt default check on by default
my $fh = new FileHandle;
$fh->open("<$fnam") or die "failed to open '$fnam'";
push @cmdfh, $fh;
print "set save_config_basedata [rlc get basedata]\n";
print "set save_config_basestat [rlc get basestat]\n";
print "rlc set basedata 8\n";
print "rlc set basestat 2\n";
while (1) {
my $cmd = get_line();
last unless defined $cmd;
$cmd_line = $cmd;
$cmd_rest = "";
# .mode mode -> accept only 'rri', quit otherwise ------------------
if ($cmd =~ /^\.mode\s+(.*)$/) {
if ($1 ne "rri") {
print "# FAIL: $cmd not supported\n";
exit 1;
}
next;
# .dbaso n ---------------------------------------------------------
} elsif ($cmd =~ /^\.dbaso\s+(\d+)$/) {
my $dbaso = $1;
cmdlist_do();
print "rlc set basedata $dbaso\n";
# .cmax n ----------------------------------------------------------
} elsif ($cmd =~ /^\.cmax\s+(\d+)$/) {
$cmax = $1;
next;
# .eop -------------------------------------------------------------
} elsif ($cmd =~ /^\.eop/) {
cmdlist_do();
next;
# .sdef s=ref[,msk] ------------------------------------------------
} elsif ($cmd =~ /^\.sdef\s+s=([01]+),?([01]*)/) {
$cmd_rest = $';
cmdlist_do();
$ref_sdef = oct("0b$1");
$msk_sdef = oct("0b$2");
# .ndef ------------------------------------------------------------
} elsif ($cmd =~ /^\.ndef\s+([01])/) {
$cmd_rest = $';
cmdlist_do();
$chk_ndef = $1;
# .rlmon,.rbmon ----------------------------------------------------
} elsif ($cmd =~ /^\.(r[lb]mon)\s+(\d)/) {
$cmd_rest = $';
cmdlist_do();
print "rlc oob -$1 $2\n";
# .scntl -----------------------------------------------------------
} elsif ($cmd =~ /^\.scntl\s+(\d+)\s+(\d)/) {
$cmd_rest = $';
cmdlist_do();
print "rlc oob -sbcntl $1 $2\n";
# .reset -----------------------------------------------------------
} elsif ($cmd =~ /^\.reset/) {
$cmd_rest = $';
cmdlist_do();
print "rlc exec -init 0 1\n";
# .amclr -----------------------------------------------------------
} elsif ($cmd =~ /^\.amclr/) {
$cmd_rest = $';
cmdlist_do();
print "rlc amap -clear\n";
# .amdef -----------------------------------------------------------
} elsif ($cmd =~ /^\.amdef\s+([0-9a-z]+)\s+([01]+)/) {
$cmd_rest = $';
cmdlist_do();
my $anam = $1;
my $aval = sprintf ('0%3.3o', oct("0b$2"));
print "rlc amap -insert $anam $aval\n";
# .wait n ----------------------------------------------------------
# Note: simply send zeros rather true idles. both are discarded anyway
} elsif ($cmd =~ /^(\.wait)/) {
$cmd_rest = $';
my $delay = cget_gdat(16,10,1,256);
cmdlist_do();
print "rlc log \".wait $delay\"\n";
print "rlc rawio -wblk {";
for (my $i = 0; $i < $delay; $i++) {
printf " 0%3.3o", 0x00;
}
print "}\n";
# .wtlam n ---------------------------------------------------------
# Note: ignore n, use tout here !
} elsif ($cmd =~ /^(\.wtlam)/) {
$cmd_rest = $';
my $delay = cget_gdat(16,10,1); # currently ignores
cmdlist_do();
printf "rlc wtlam %d\n", $tout;
# rreg <addr> [d=g16] [s=b8] ---------------------------------------
} elsif ($cmd =~ /^rreg/) {
$cmd_rest = $';
my $act = "-rreg";
$act .= add_addr();
$act .= add_edata($dbase);
$act .= add_estat();
push @cmdlist, $act;
# wreg|init <addr> g16 [s=b8] --------------------------------------
} elsif ($cmd =~ /^(wreg|init)/) {
$cmd_rest = $';
my $act = "-$1";
$act .= add_addr();
$act .= add_data($dbase);
$act .= add_estat();
push @cmdlist, $act;
# rblk <addr> n [n=dd] [s=b8] --------------------------------------
} elsif ($cmd =~ /^rblk/) {
$cmd_rest = $';
my $act = "-rblk";
$act .= add_addr();
my $nblk = cget_gdat(16,10,1,256);
$act .= " $nblk";
$act .= add_edone($nblk);
$act .= add_estat();
cget_chkblank();
my @ref_rblk;
my @msk_rblk;
my $do_msk = 0;
for (my $i = 0; $i < $nblk; $i++) {
$cmd_rest = get_line() if ($cmd_rest eq "");
$cmd_rest =~ s/^\s*//;
my ($ref,$msk) = cget_tagval2_gdat("d",16,$dbase);
if (not defined $ref) {
$ref = 0;
$msk = 0xffff;
}
$msk = 0 unless defined $msk;
$do_msk = 1 if $msk != 0;
push @ref_rblk, sprintf("0%6.6o", $ref);
push @msk_rblk, sprintf("0%6.6o", (0xffff & ~$msk));
}
$act .= ' -edata {' . join(' ',@ref_rblk) . '}';
$act .= ' {' . join(' ',@msk_rblk) . '}' if $do_msk;
push @cmdlist, $act;
cmdlist_do();
# wblk <addr> n [n=dd] [s=b8] --------------------------------------
} elsif ($cmd =~ /^wblk/) {
$cmd_rest = $';
my $act = "-wblk";
$act .= add_addr();
my $nblk = cget_gdat(16,10,1,256);
my $edone = add_edone($nblk);
my $estat = add_estat();
cget_chkblank();
my @dat_wblk;
for (my $i = 0; $i < $nblk; $i++) {
$cmd_rest = get_line() if ($cmd_rest eq "");
$cmd_rest =~ s/^\s*//;
push @dat_wblk, sprintf('0%6.6o', cget_gdat(16,$dbase));
}
$act .= ' {' . join(' ',@dat_wblk) . '}';
$act .= $edone;
$act .= $estat;
push @cmdlist, $act;
cmdlist_do();
# stat|attn [d=g16] [s=b8] -----------------------------------------
} elsif ($cmd =~ /^(stat|attn)\s+/) {
$cmd_rest = $';
my $act = "-$1";
$act .= add_edata($dbase);
$act .= add_estat();
push @cmdlist, $act;
# unknown commands -------------------------------------------------
} else {
print "# FAIL: no match for '$cmd'\n";
exit 1;
}
cget_chkblank();
cmdlist_do() if scalar(@cmdlist) >= $cmax;
}
cmdlist_do();
print "rlc set basedata \$save_config_basedata\n";
print "rlc set basestat \$save_config_basestat\n";
exit 0;
#-------------------------------------------------------------------------------
sub add_addr {
my $addr;
$cmd_rest =~ s/^\s*//;
if ($cmd_rest =~ /^\.([[0-9a-z.]+)/) {
$addr = $1;
$cmd_rest = $';
} else {
$addr =sprintf('0x%4.4x', cget_gdat(16,2));
}
return " $addr";
}
#-------------------------------------------------------------------------------
sub add_data {
my ($dbase) = @_;
my $data = cget_gdat(16,$dbase);
return sprintf(" 0%6.6o", $data);
}
#-------------------------------------------------------------------------------
# Note: input has ignore mask, output has check mask now
sub add_edata {
my ($dbase) = @_;
my ($ref,$msk) = cget_tagval2_gdat("d",16,$dbase);
return "" unless defined $ref;
my $str = sprintf(" -edata 0%6.6o", $ref);
$str .= sprintf(" 0%6.6o", (0xffff & ~$msk)) if defined $msk && $msk;
return $str;
}
#-------------------------------------------------------------------------------
# Note: input has ignore mask, output has check mask now
# -estat always added, either from s= tag or from .sdef directive
sub add_estat {
my ($dat, $msk) = cget_tagval2_gdat("s",8,2);
unless (defined $dat) {
$dat = $ref_sdef;
$msk = $msk_sdef;
}
my $str = sprintf(" -estat 0x%2.2x", $dat);
$str .= sprintf(" 0x%2.2x", (0xff & ~$msk)) if defined $msk && $msk;
return $str;
}
#-------------------------------------------------------------------------------
sub add_edone {
my ($bsize) = @_;
my ($nblk) = cget_tagval_gdat("n",16,10);
$nblk = $bsize if (not defined $nblk && $chk_ndef);
return "" unless defined $nblk;
my $str = sprintf(" -edone %d", $nblk);
return $str;
}
#-------------------------------------------------------------------------------
sub cmdlist_do {
return unless scalar(@cmdlist);
print "rlc exec \\\n";
while (scalar(@cmdlist)) {
print " ";
print shift @cmdlist;
print " \\\n" if scalar(@cmdlist);
}
print "\n";
@cmdlist = ();
return;
}
#-------------------------------------------------------------------------------
sub cget_chkblank { # check for unused chars in cmd line
$cmd_rest =~ s/^\s*//;
if ($cmd_rest ne "") {
print "ticonv_rri-E: extra data ignored: \"$cmd_rest\"\n";
print " for command: \"$cmd_line\"\n";
exit 1;
}
}
#-------------------------------------------------------------------------------
sub cget_tagval2_gdat { # get tag=v1[,v2], generic base
my ($tag,$nbit,$dbase) = @_;
my $dat;
my $msk = undef;
$cmd_rest =~ s/^\s*//;
if ($cmd_rest =~ /^$tag=/) {
$cmd_rest = $';
if ($cmd_rest =~ /^-/) {
$cmd_rest = $';
my $msk = (1 << $nbit) -1;
return (0,$msk);
} else {
$dat = cget_gdat($nbit, $dbase);
if ($cmd_rest =~ /^,/) {
$cmd_rest = $';
$msk = cget_gdat($nbit, $dbase);
}
return ($dat, $msk);
}
}
return (undef, undef);
}
#-------------------------------------------------------------------------------
sub cget_tagval_gdat { # get tag=val, generic base
my ($tag,$nbit,$dbase,$min,$max) = @_;
$cmd_rest =~ s/^\s*//;
if ($cmd_rest =~ /^$tag=/) {
$cmd_rest = $';
return cget_gdat($nbit, $dbase,$min,$max);
}
return undef;
}
#-------------------------------------------------------------------------------
sub cget_gdat { # get generic base value
my ($nbit,$dbase,$min,$max) = @_;
my $dat;
$cmd_rest =~ s/^\s*//;
if ($cmd_rest =~ /^[xXoObBdD]"/) {
if ($cmd_rest =~ /^[xX]"([0-9a-fA-F]+)"/) {
$cmd_rest = $';
$dat = hex $1;
} elsif ($cmd_rest =~ /^[oO]"([0-7]+)"/) {
$cmd_rest = $';
$dat = oct $1;
} elsif ($cmd_rest =~ /^[bB]"([01]+)"/) {
$cmd_rest = $';
my $odat = sget_bdat($nbit, $1);
$dat = $odat if defined $odat;
} elsif ($cmd_rest =~ /^[dD]"([+-]?[0-9]+)"/) {
$cmd_rest = $';
my $odat = (int $1) & ((1<<$nbit)-1);
$dat = $odat;
}
} else {
if ($cmd_rest =~ /^([+-]?[0-9]+)\./) {
$cmd_rest = $';
my $odat = (int $1) & ((1<<$nbit)-1);
$dat = $odat;
} elsif ($dbase == 16 && $cmd_rest =~ /^([0-9a-fA-F]+)/) {
$cmd_rest = $';
$dat = hex $1;
} elsif ($dbase == 8 && $cmd_rest =~ /^([0-7]+)/) {
$cmd_rest = $';
$dat = oct $1;
} elsif ($dbase == 2 && $cmd_rest =~ /^([01]+)/) {
$cmd_rest = $';
my $odat = sget_bdat($nbit, $1);
$dat = $odat if defined $odat;
} elsif ($dbase == 10 && $cmd_rest =~ /^([0-9]+)/) {
$cmd_rest = $';
$dat = int $1;
}
}
if (not defined $dat) {
print "ticonv_rri-E: cget_gdat error in \"$cmd_rest\" (base=$dbase)\n";
exit 1;
}
if (defined $min && $dat < $min) {
print "ticonv_rri-E: cget_gdat range error, $dat < $min\n";
exit 1;
}
if (defined $max && $dat > $max) {
print "ticonv_rri-E: cget_gdat range error, $dat > $max\n";
exit 1;
}
return $dat;
}
#-------------------------------------------------------------------------------
sub sget_bdat { # convert 01 string -> binary value
my ($nbit,$str) = @_;
my $nchar = length($str);
my $odat = 0;
if ($nchar != $nbit) {
print "ticonv_rri-E: sget_bdat error \'$str\' has not length $nbit\n";
exit 1;
}
for (my $i = 0; $i < $nchar; $i++) {
$odat *= 2;
$odat += 1 if substr($str, $i, 1) eq "1";
}
return $odat;
}
#-------------------------------------------------------------------------------
sub get_line {
while (1) {
return undef unless scalar(@cmdfh);
my $fh = $cmdfh[$#cmdfh];
my $cmd = <$fh>;
if (not defined $cmd) {
$fh->close();
pop @cmdfh;
next;
}
# detect @<fname> lines
if ($cmd =~ /^@(.+)/) {
my $fnam = $1;
my $fh = new FileHandle;
$fh->open("<$fnam") or die "failed to open '$fnam'";
push @cmdfh, $fh;
next;
}
# write C... comment lines to rlc log
if ($cmd =~ /^C(.*)/) {
cmdlist_do();
my $msg = $1;
$msg =~ s/"/'/g;
$msg =~ s/\[/\{/g;
$msg =~ s/\]/\}/g;
print "rlc log \"C $msg\"\n";
next;
}
$cmd =~ s{^\s*}{}; # remove leading blanks
next if $cmd =~ m/^#/; # ignore "# ...." lines
next if $cmd =~ m/^;/; # ignore "; ...." lines
$cmd =~ s{--.*}{}; # remove comments after --
$cmd =~ s{\s*$}{}; # remove trailing blanks
next if $cmd eq ""; # ignore empty lines
return $cmd;
}
}

View File

@@ -1,5 +1,5 @@
#!/usr/bin/perl -w
# $Id: vbomconv 778 2016-06-25 15:18:01Z mueller $
# $Id: vbomconv 804 2016-08-28 17:33:50Z mueller $
#
# Copyright 2007-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
@@ -14,6 +14,8 @@
#
# Revision History:
# Date Rev Version Comment
# 2016-08-28 804 1.17.3 xsim work dir now xsim.<mode>.<stem>
# 2016-07-02 782 1.17.2 add VBOMCONV_GHDL_OPTS and VBOMCONV_GHDL_GCOV
# 2016-06-24 778 1.17.1 -vsyn_prj: add [rep]sim models & VBOMCONV_XSIM_LANG
# -ghdl_(i|m|a): use --workdir
# 2016-06-19 777 1.17 -vsyn_prj: sim and syn source sets based on -UUT
@@ -144,15 +146,24 @@ my $level = 0; # vbom nesting level
my $xst_writevhdl = 1;
my $xlpath=$opts{xlpath};
my $no_xlpath = ! defined $xlpath || $xlpath eq "";
my $xsim_lang = 'verilog'; # xsim model language
my $ghdl_opts = $ENV{VBOMCONV_GHDL_OPTS}; # ghdl extra options
my $ghdl_gcov = $ENV{VBOMCONV_GHDL_GCOV}; # ghdl gcov enable
my $xsim_lang = $ENV{VBOMCONV_XSIM_LANG}; # xsim model language
$xsim_lang = $ENV{VBOMCONV_XSIM_LANG} if defined $ENV{VBOMCONV_XSIM_LANG};
if ($ghdl_gcov) {
$ghdl_opts = '' unless defined $ghdl_opts;
$ghdl_opts .= ' ' unless $ghdl_opts eq '';
$ghdl_opts .= '-Wc,-ftest-coverage -Wc,-fprofile-arcs -Wl,-lgcov';
} else {
$ghdl_opts = '-O2 -g' unless defined $ghdl_opts;
}
$xsim_lang = 'verilog' unless defined $xsim_lang;
if ($xsim_lang ne 'verilog' && $xsim_lang ne 'vhdl') {
print STDERR "vbomconv-E: VBOMCONV_XSIM_LANG is '$xsim_lang'\n";
print STDERR "vbomconv-E: VBOMCONV_XSIM_LANG must be 'verilog' or 'vhdl'\n";
exit 1;
}
$is_veri = $xsim_lang eq 'verilog';
autoflush STDOUT 1; # autoflush, so nothing lost on exec later
@@ -327,7 +338,7 @@ if ($do_trace) {
print STDERR " \-UUT: $uut\n" if defined $uut;
}
# --ghdh_a -- ghdl analysis command ----------------------------------
# --ghdl_a -- ghdl analysis command ----------------------------------
if (exists $opts{ghdl_a} || exists $opts{ghdl_a_cmd}) {
if ($no_xlpath && ($has_unisim || $has_unimacro || $has_simprim) ) {
@@ -343,6 +354,7 @@ if (exists $opts{ghdl_a} || exists $opts{ghdl_a_cmd}) {
$cmd .= " -P$xlpath/unimacro" if $has_unimacro;
$cmd .= " -P$xlpath/simprim" if $has_simprim;
$cmd .= " --ieee=synopsys";
$cmd .= " ${ghdl_opts}";
$cmd .= " $file";
print "$cmd\n";
if (exists $opts{ghdl_a}) {
@@ -362,7 +374,7 @@ if (exists $opts{ghdl_a} || exists $opts{ghdl_a_cmd}) {
}
}
# --ghdh_i -- ghdl inspection command --------------------------------
# --ghdl_i -- ghdl inspection command --------------------------------
if (exists $opts{ghdl_i} || exists $opts{ghdl_i_cmd}) {
my $workdir = "ghdl.${sim_mode}";
@@ -408,7 +420,7 @@ if (exists $opts{ghdl_i} || exists $opts{ghdl_i_cmd}) {
}
}
# --ghdh_m -- ghdl make command --------------------------------------
# --ghdl_m -- ghdl make command --------------------------------------
# Note: the 'buildin' make used by the -m option of ghdl does not
# check for object files linked with -Wl, e.g. vhpi objects.
# To force a re-elaboration the old executable is deleted first.
@@ -436,6 +448,7 @@ if (exists $opts{ghdl_m} || exists $opts{ghdl_m_cmd} ) {
$cmd .= " -P$xlpath/unimacro" if $has_unimacro;
$cmd .= " -P$xlpath/simprim" if $has_simprim;
$cmd .= " --ieee=synopsys";
$cmd .= " ${ghdl_opts}";
$cmd .= " --no-vital-checks" if $sim_mode ne 'bsim';
foreach (@srcfile_list) {
@@ -551,7 +564,10 @@ if (exists $opts{vsyn_prj}) {
# --vsim_prj ---------------------------------------------------------
if (exists $opts{vsim_prj}) {
my $workdir = "xsim.${sim_mode}";
# Note: use a separate workdir for each sim_mode and each model (given
# by stem). This allows to have all co-existant, and to delete the workdir
# each time one of them is re-build.
my $workdir = "xsim.${sim_mode}.${stem}";
my $fname_forwarder = "${stem}_XSim";
$fname_forwarder =~ s/_([sorept]sim)_XSim/_XSim_$1/;

View File

@@ -1,17 +1,19 @@
#!/bin/bash
# $Id: xise_ghdl_simprim 642 2015-02-06 18:53:12Z mueller $
# $Id: xise_ghdl_simprim 782 2016-07-03 08:09:36Z mueller $
#
# Copyright 2007-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# Copyright 2007-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Vers Comment
# 2016-07-02 782 1.3.1 add ghdlopts as 1st option; default is -O2
# 2015-02-03 642 1.3 remove ISE 10 legacy support
# 2015-01-29 639 1.2 rename from xilinx_*; use XTWI_PATH rather XILINX
# 2009-11-08 248 1.1 adopt to ISE 11.1, use VITAL models from ./primitive
# 2007-10-26 92 1.0 Initial version
#
ghdlopts=${1:--O2 -g}
#
if [ -z "$XTWI_PATH" ]
then
echo "XTWI_PATH not defined"
@@ -57,15 +59,17 @@ xilinx_vhdl_memcolltype_fix
popd
#
echo "# ghdl ... simprim_Vcomponents.vhd"
ghdl -a --ieee=synopsys --work=simprim --no-vital-checks simprim_Vcomponents.vhd
ghdl -a --ieee=synopsys --work=simprim --no-vital-checks $ghdlopts \
simprim_Vcomponents.vhd
echo "# ghdl ... simprim_Vpackage.vhd"
ghdl -a --ieee=synopsys --work=simprim --no-vital-checks simprim_Vpackage.vhd
ghdl -a --ieee=synopsys --work=simprim --no-vital-checks $ghdlopts \
simprim_Vpackage.vhd
for file in `cat primitive/vhdl_analyze_order`
do
echo "# ghdl ... primitive/$file"
ghdl -a -fexplicit --ieee=synopsys --work=simprim \
--no-vital-checks primitive/$file 2>&1 |\
--no-vital-checks $ghdlopts primitive/$file 2>&1 |\
tee primitive/$file.ghdl.log
done
#

View File

@@ -1,17 +1,19 @@
#!/bin/bash
# $Id: xise_ghdl_unisim 642 2015-02-06 18:53:12Z mueller $
# $Id: xise_ghdl_unisim 782 2016-07-03 08:09:36Z mueller $
#
# Copyright 2007-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# Copyright 2007-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Vers Comment
# 2016-07-02 782 1.3.1 add ghdlopts as 1st option; default is -O2
# 2015-02-03 642 1.3 remove ISE 10 legacy support; add unimacro support
# 2015-01-29 639 1.2 rename from xilinx_*; use XTWI_PATH rather XILINX
# 2009-11-08 248 1.1 adopt to ISE 11.1, use VITAL models from ./primitive
# 2007-10-26 92 1.0 Initial version
#
ghdlopts=${1:--O2 -g}
#
if [ -z "$XTWI_PATH" ]
then
echo "XTWI_PATH not defined"
@@ -58,14 +60,14 @@ xilinx_vhdl_memcolltype_fix
popd
echo "# ghdl ... unisim_VCOMP.vhd"
ghdl -a --ieee=synopsys --work=unisim unisim_VCOMP.vhd
ghdl -a --ieee=synopsys --work=unisim $ghdlopts unisim_VCOMP.vhd
echo "# ghdl ... unisim_VPKG.vhd"
ghdl -a --ieee=synopsys --work=unisim unisim_VPKG.vhd
ghdl -a --ieee=synopsys --work=unisim $ghdlopts unisim_VPKG.vhd
for file in `cat primitive/vhdl_analyze_order`
do
echo "# ghdl ... primitive/$file"
ghdl -a -fexplicit --ieee=synopsys --work=unisim \
ghdl -a -fexplicit --ieee=synopsys --work=unisim $ghdlopts \
--no-vital-checks primitive/$file 2>&1 |\
tee primitive/$file.ghdl.log
done
@@ -89,7 +91,7 @@ cp $ise_path/vhdl/src/unimacro/*.vhd .
for file in *.vhd
do
echo "# ghdl ... $file"
ghdl -a -P../unisim -fexplicit --ieee=synopsys --work=unimacro \
ghdl -a -P../unisim -fexplicit --ieee=synopsys --work=unimacro $ghdlopts \
--no-vital-checks $file 2>&1 | tee $file.ghdl.log
done
#

View File

@@ -1,5 +1,5 @@
#!/bin/bash
# $Id: xtwi 735 2016-02-26 22:17:42Z mueller $
# $Id: xtwi 804 2016-08-28 17:33:50Z mueller $
#
# Copyright 2013-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
@@ -10,6 +10,7 @@
#
# Revision History:
# Date Rev Version Comment
# 2016-08-28 804 1.2 BUGFIX: add ":." to PATH even under BARE_PATH
# 2016-02-21 735 1.1 use BARE_PATH ect to provide clean environment
# 2013-10-12 539 1.0 Initial version
#
@@ -33,10 +34,11 @@ then
fi
# provide clean environment when BARE_PATH ect defined
# add only $RETROBASE/tools/bin to path
# add only $RETROBASE/tools/bin and '.' to path
# '.' is needed to start ISim tb's, which usually are in cwd
if [ -n "$BARE_PATH" ]
then
export PATH=$BARE_PATH:$RETROBASE/tools/bin
export PATH=$BARE_PATH:$RETROBASE/tools/bin:.
unset LD_LIBRARY_PATH
if [ -n "$BARE_LD_LIBRARY_PATH" ]
then

View File

@@ -1,15 +1,17 @@
#!/bin/bash
# $Id: xviv_ghdl_unisim 762 2016-04-17 21:33:42Z mueller $
# $Id: xviv_ghdl_unisim 782 2016-07-03 08:09:36Z mueller $
#
# Copyright 2015-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Vers Comment
# 2016-07-02 782 1.1.1 add ghdlopts as 1st option; default is -O2
# 2016-04-17 762 1.1 update for viv 2016.1
# 2015-02-02 642 1.0 Initial version
#
ghdlopts=${1:--O2 -g}
#
if [ -z "$XTWV_PATH" ]
then
echo "XTWV_PATH not defined"
@@ -79,14 +81,14 @@ popd
# now compile all --------------------------------
#
echo "# ghdl ... unisim_retarget_VCOMP.vhd"
ghdl -a --ieee=synopsys --work=unisim unisim_retarget_VCOMP.vhd
ghdl -a --ieee=synopsys --work=unisim $ghdlopts unisim_retarget_VCOMP.vhd
echo "# ghdl ... unisim_VPKG.vhd"
ghdl -a --ieee=synopsys --work=unisim unisim_VPKG.vhd
ghdl -a --ieee=synopsys --work=unisim $ghdlopts unisim_VPKG.vhd
for file in `cat primitive/vhdl_analyze_order`
do
echo "# ghdl ... primitive/$file"
ghdl -a -fexplicit --ieee=synopsys --work=unisim \
ghdl -a -fexplicit --ieee=synopsys --work=unisim $ghdlopts \
--no-vital-checks primitive/$file 2>&1 |\
tee primitive/$file.ghdl.log
done
@@ -94,7 +96,7 @@ done
for file in `cat retarget/vhdl_analyze_order`
do
echo "# ghdl ... retarget/$file"
ghdl -a -fexplicit --ieee=synopsys --work=unisim \
ghdl -a -fexplicit --ieee=synopsys --work=unisim $ghdlopts \
--no-vital-checks retarget/$file 2>&1 |\
tee retarget/$file.ghdl.log
done
@@ -126,7 +128,7 @@ fi
for file in `cat vhdl_analyze_order`
do
echo "# ghdl ... $file"
ghdl -a -P../unisim -fexplicit --ieee=synopsys --work=unimacro \
ghdl -a -P../unisim -fexplicit --ieee=synopsys --work=unimacro $ghdlopts \
--no-vital-checks $file 2>&1 | tee $file.ghdl.log
done
#

View File

@@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "w11 - cpp"
PROJECT_NUMBER = 0.73
PROJECT_NUMBER = 0.74
PROJECT_BRIEF = "Backend server for Rlink and w11"
PROJECT_LOGO =
OUTPUT_DIRECTORY = $(RETRODOXY)/w11/cpp

View File

@@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "w11 - tcl"
PROJECT_NUMBER = 0.73
PROJECT_NUMBER = 0.74
PROJECT_BRIEF = "Backend server for Rlink and w11"
PROJECT_LOGO =
OUTPUT_DIRECTORY = $(RETRODOXY)/w11/tcl

View File

@@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "w11 - vhd"
PROJECT_NUMBER = 0.73
PROJECT_NUMBER = 0.74
PROJECT_BRIEF = "W11 CPU core and support modules"
PROJECT_LOGO =
OUTPUT_DIRECTORY = $(RETRODOXY)/w11/vhd

View File

@@ -29,3 +29,4 @@ pkg_mkIndex -verbose ibd_rl11 *.tcl
pkg_mkIndex -verbose ibd_tm11 *.tcl
#
pkg_mkIndex -verbose tst_rlink *.tcl
pkg_mkIndex -verbose tst_sram *.tcl

View File

@@ -0,0 +1 @@
pkgIndex.tcl

View File

@@ -0,0 +1,120 @@
# $Id: test_all.tcl 785 2016-07-10 12:22:41Z mueller $
#
# Copyright 2014-2016 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 2, 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
# 2016-07-09 784 2.1 add test_all test driver
# 2014-11-23 606 2.0 use new rlink v4 iface
# 2014-08-14 582 1.0 Initial version
#
package provide tst_sram 1.0
package require rutiltpp
package require rutil
package require rlink
namespace eval tst_sram {
#
# test_all: Driver for all tst_sram tests
#
proc test_all {{tout 10.}} {
#
set errcnt 0
tst_sram::init
incr errcnt [test_regs]
incr errcnt [test_seq $tout]
puts "tst_sram::test_all errcnt = $errcnt --> [rutil::errcnt2txt $errcnt]"
return $errcnt
}
#
# test_sim: test suite for sim tests ---------------------------------------
# port of cmd_tst_sram_stress_sim.dat
#
proc test_sim {} {
rlink::anena 1; # enable attn notify
rlc exec -attn; # harvest spurious attn
init
scmd_write [test_scmdlist]
set lmdi {0x0000 0x0000 \
0xffff 0xffff \
0x0000 0xffff \
0xffff 0x0000 \
0xaaaa 0xaaaa \
0x5555 0x5555 }
set lmaddr {0x0000 0x0000 \
0x0003 0xffff \
0x0000 0xffff \
0x000f 0x0000 \
0x000a 0xaaaa \
0x0005 0x5555 }
set lmaddr_ran {}
for {set i 0} { $i < 3 } {incr i} {
lappend lmaddr_ran [expr {int(65536*rand()) & 0x000f}]
lappend lmaddr_ran [expr {int(65536*rand()) & 0xffff}]
}
srun_lists $lmdi $lmaddr
srun_lists $lmdi $lmaddr_ran
return ""
}
#
# test_fpga: test suite for fpga tests -------------------------------------
# port of cmd_tst_sram_stress_fpga.dat
#
proc test_fpga {{wide -1} {tout 1000.}} {
rlink::anena 1; # enable attn notify
rlc exec -attn; # harvest spurious attn
init
scmd_write [test_scmdlist]
set lmdi {0x0000 0x0000 \
0xffff 0xffff \
0x0000 0xffff \
0xffff 0x0000 \
0xaaaa 0xaaaa \
0x5555 0x5555 \
0x1e25 0x4e58 \
0xa9d8 0xd6d4 \
0xbcbd 0x0815 \
0x7424 0x7466 }
set lmdi_ran {}
for {set i 0} { $i < 3 } {incr i} {
lappend lmdi_ran [expr {int(65536*rand()) & 0xffff}]
lappend lmdi_ran [expr {int(65536*rand()) & 0xffff}]
}
if {$wide < 0} { set wide [iswide] }
set maddrh 0x0000
set maddrl 0x0000
if {[rlink::issim]} {
set maddrh [expr {$wide ? 0x003f : 0x0003}]
set maddrl 0xfffc
}
foreach {mdih mdil} $lmdi {
srun_loop $mdih $mdil $maddrh $maddrl $wide $tout
}
foreach {mdih mdil} $lmdi_ran {
srun_loop $mdih $mdil $maddrh $maddrl $wide $tout
}
return ""
}
}

View File

@@ -0,0 +1,346 @@
# $Id: test_regs.tcl 785 2016-07-10 12:22:41Z mueller $
#
# Copyright 2016- 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 2, 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
# 2016-07-10 785 1.1 add memory test (touch evenly distributed addr)
# 2016-07-09 784 1.0 Initial version (ported from tb_tst_sram_stim.dat)
#
package provide tst_sram 1.0
package require rutiltpp
package require rutil
package require rlink
namespace eval tst_sram {
#
# test_regs: Test registers: mdi*,mdo*,maddr*,mcmd,mblk,sblk*
# and saddr,slim,sblk*
#
proc test_regs {} {
#
set errcnt 0
rlc errcnt -clear
#
rlc log "tst_sram::test_regs ---------------------------------------------"
rlc log " init: reset via init, clear sfail ect"
rlc exec -init sr.mdih 0x0003; # reset MEM,SEQ
#
#-------------------------------------------------------------------------
rlc log " test 1a: test mdi* ,maddr*"
rlc exec \
-wreg sr.mdih 0x5555 \
-wreg sr.mdil 0xaaaa \
-wreg sr.maddrh 0x0001 \
-wreg sr.maddrl 0xcccc \
-rreg sr.mdih -edata 0x5555 \
-rreg sr.mdil -edata 0xaaaa \
-rreg sr.maddrh -edata 0x0001 \
-rreg sr.maddrl -edata 0xcccc
#
#-------------------------------------------------------------------------
rlc log " test 1b: test maddrh range"
set maddrh_max [expr {[iswide] ? 0x3f : 0x03}]
rlc exec \
-wreg sr.maddrh 0xffff \
-rreg sr.maddrh -edata $maddrh_max
#
#-------------------------------------------------------------------------
rlc log " test 2: test direct memory write/read via mcmd"
# write mem(0) = 0xdeadbeaf; mem(1)=a5a55a5a
rlc exec \
-wreg sr.maddrh 0x0000 \
-wreg sr.maddrl 0x0000 \
-wreg sr.mdih 0xdead \
-wreg sr.mdil 0xbeaf \
-wreg sr.mcmd [regbld tst_sram::MCMD we {be 0xf}] \
-wreg sr.maddrl 0x0001 \
-wreg sr.mdih 0xa5a5 \
-wreg sr.mdil 0x5a5a \
-wreg sr.mcmd [regbld tst_sram::MCMD we {be 0xf}]
# read back
rlc exec \
-wreg sr.maddrl 0x0000 \
-wreg sr.mcmd [regbld tst_sram::MCMD {be 0xf}] \
-rreg sr.mdoh -edata 0xdead \
-rreg sr.mdol -edata 0xbeaf \
-wreg sr.maddrl 0x0001 \
-wreg sr.mcmd [regbld tst_sram::MCMD {be 0xf}] \
-rreg sr.mdoh -edata 0xa5a5 \
-rreg sr.mdol -edata 0x5a5a
# check that mdi* unchanged (value from last write)
rlc exec \
-rreg sr.mdih -edata 0xa5a5 \
-rreg sr.mdil -edata 0x5a5a
# verify that mcmd write only
rlc exec -rreg sr.mcmd -estaterr; # expect err on read
#
#-------------------------------------------------------------------------
rlc log " test 3: test block write/read via mblk"
# write 8 longwords, check maddrl incremented
rlc exec \
-wreg sr.maddrh 0x0000 \
-wreg sr.maddrl 0x0010 \
-wblk sr.mblk {0x3020 0x1000 \
0x3121 0x1101 \
0x3222 0x1202 \
0x3323 0x1303 \
0x3424 0x1404 \
0x3525 0x1505 \
0x3626 0x1606 \
0x3727 0x1707} \
-rreg sr.maddrh -edata 0x0000 \
-rreg sr.maddrl -edata 0x0018
# read 8 longwords, check maddrl incremented
rlc exec \
-wreg sr.maddrh 0x0000 \
-wreg sr.maddrl 0x0010 \
-rblk sr.mblk 16 -edata {0x3020 0x1000 \
0x3121 0x1101 \
0x3222 0x1202 \
0x3323 0x1303 \
0x3424 0x1404 \
0x3525 0x1505 \
0x3626 0x1606 \
0x3727 0x1707} \
-rreg sr.maddrh -edata 0x0000 \
-rreg sr.maddrl -edata 0x0018
#
#-------------------------------------------------------------------------
rlc log " test 4: mcmd: ld,inc and be functionality"
# use memory as setup by previous test
# overwrite bytes 12(0001)=42, 13(0010)=53, 14(0100)=64, 15(1000)=75
rlc exec \
-wreg sr.maddrh 0x0003 \
-wreg sr.maddrl 0x0012 \
-wreg sr.mdih 0xffff \
-wreg sr.mdil 0xff42 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc we {be 0x1} {addrh 0x0}] \
-wreg sr.mdil 0x53ff \
-wreg sr.mcmd [regbld tst_sram::MCMD inc we {be 0x2} ] \
-wreg sr.mdih 0xff64 \
-wreg sr.mdil 0xffff \
-wreg sr.mcmd [regbld tst_sram::MCMD inc we {be 0x4} ] \
-wreg sr.mdih 0x75ff \
-wreg sr.mcmd [regbld tst_sram::MCMD inc we {be 0x8} ]
# check load maddrh and increment of maddrl; read back and check
rlc exec \
-rreg sr.maddrh -edata 0x0000 \
-rreg sr.maddrl -edata 0x0016 \
-wreg sr.maddrl 0x0010 \
-rblk sr.mblk 16 -edata {0x3020 0x1000 \
0x3121 0x1101 \
0x3222 0x1242 \
0x3323 0x5303 \
0x3464 0x1404 \
0x7525 0x1505 \
0x3626 0x1606 \
0x3727 0x1707}
#
#-------------------------------------------------------------------------
rlc log " test 5: test saddr,slim,sblk,sblkc,sblkd"
# write/read saddr/slim
rlc exec \
-wreg sr.slim 0x0123 \
-wreg sr.saddr 0x0345 \
-rreg sr.slim -edata 0x0123 \
-rreg sr.saddr -edata 0x0345
# sblk write of 8 lines, check saddr incremented
rlc exec \
-wreg sr.saddr 0x0000 \
-wblk sr.sblk {0x0300 0x0200 0x0100 0x0000 \
0x0301 0x0201 0x0101 0x0001 \
0x0302 0x0202 0x0102 0x0002 \
0x0303 0x0203 0x0103 0x0003 \
0x0304 0x0204 0x0104 0x0004 \
0x0305 0x0205 0x0105 0x0005 \
0x0306 0x0206 0x0106 0x0006 \
0x0307 0x0207 0x0107 0x0007 } \
-rreg sr.saddr -edata 0x0008
# sblk read back
rlc exec \
-wreg sr.saddr 0x0000 \
-rblk sr.sblk 32 -edata {0x0300 0x0200 0x0100 0x0000 \
0x0301 0x0201 0x0101 0x0001 \
0x0302 0x0202 0x0102 0x0002 \
0x0303 0x0203 0x0103 0x0003 \
0x0304 0x0204 0x0104 0x0004 \
0x0305 0x0205 0x0105 0x0005 \
0x0306 0x0206 0x0106 0x0006 \
0x0307 0x0207 0x0107 0x0007 } \
-rreg sr.saddr -edata 0x0008
# sblkc (over-)write of 4 lines (1-4)
rlc exec \
-wreg sr.saddr 0x0001 \
-wblk sr.sblkc {0x1301 0x1201 \
0x1302 0x1202 \
0x1303 0x1203 \
0x1304 0x1204 } \
-rreg sr.saddr -edata 0x0005
# sblkd (over-)write of 4 lines (3-6)
rlc exec \
-wreg sr.saddr 0x0003 \
-wblk sr.sblkd {0x2103 0x2003 \
0x2104 0x2004 \
0x2105 0x2005 \
0x2106 0x2006 } \
-rreg sr.saddr -edata 0x0007
# sblk read back of all 8 lines, verify c and d updates
rlc exec \
-wreg sr.saddr 0x0000 \
-rblk sr.sblk 32 -edata {0x0300 0x0200 0x0100 0x0000 \
0x1301 0x1201 0x0101 0x0001 \
0x1302 0x1202 0x0102 0x0002 \
0x1303 0x1203 0x2103 0x2003 \
0x1304 0x1204 0x2104 0x2004 \
0x0305 0x0205 0x2105 0x2005 \
0x0306 0x0206 0x2106 0x2006 \
0x0307 0x0207 0x0107 0x0007} \
-rreg sr.saddr -edata 0x0008
# sblkc read back of all 8 lines
rlc exec \
-wreg sr.saddr 0x0000 \
-rblk sr.sblkc 16 -edata {0x0300 0x0200 \
0x1301 0x1201 \
0x1302 0x1202 \
0x1303 0x1203 \
0x1304 0x1204 \
0x0305 0x0205 \
0x0306 0x0206 \
0x0307 0x0207} \
-rreg sr.saddr -edata 0x0008
# sblkd read back of all 8 lines
rlc exec \
-wreg sr.saddr 0x0000 \
-rblk sr.sblkd 16 -edata {0x0100 0x0000 \
0x0101 0x0001 \
0x0102 0x0002 \
0x2103 0x2003 \
0x2104 0x2004 \
0x2105 0x2005 \
0x2106 0x2006 \
0x0107 0x0007} \
-rreg sr.saddr -edata 0x0008
#
#-------------------------------------------------------------------------
rlc log " test 5: test sstat bits"
set sm [rutil::com16 [regbld tst_sram::SSTAT wide]]
rlc exec \
-wreg sr.sstat 0 \
-rreg sr.sstat -edata 0 $sm \
-wreg sr.sstat [regbld tst_sram::SSTAT veri ] \
-rreg sr.sstat -edata [regbld tst_sram::SSTAT veri ] $sm \
-wreg sr.sstat [regbld tst_sram::SSTAT xora ] \
-rreg sr.sstat -edata [regbld tst_sram::SSTAT xora ] $sm \
-wreg sr.sstat [regbld tst_sram::SSTAT xord ] \
-rreg sr.sstat -edata [regbld tst_sram::SSTAT xord ] $sm \
-wreg sr.sstat [regbld tst_sram::SSTAT loop ] \
-rreg sr.sstat -edata [regbld tst_sram::SSTAT loop ] $sm \
-wreg sr.sstat [regbld tst_sram::SSTAT wloop] \
-rreg sr.sstat -edata [regbld tst_sram::SSTAT wloop] $sm \
-wreg sr.sstat [regbld tst_sram::SSTAT wswap] \
-rreg sr.sstat -edata [regbld tst_sram::SSTAT wswap] $sm
#
#-------------------------------------------------------------------------
rlc log " test 6: test memory (touch 5(+5) evenly spaced addresses)"
# writes
# 18bit: 0x000000 0x010001 0x020002 0x030003 0x03ffff
rlc exec \
-wreg sr.mdih 0x5500 \
-wreg sr.mdil 0xaa00 \
-wreg sr.maddrl 0x0000 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc we {be 0xf} {addrh 0x00}] \
-wreg sr.mdih 0x5501 \
-wreg sr.mdil 0xaa01 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc we {be 0xf} {addrh 0x01}] \
-wreg sr.mdih 0x5502 \
-wreg sr.mdil 0xaa02 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc we {be 0xf} {addrh 0x02}] \
-wreg sr.mdih 0x5503 \
-wreg sr.mdil 0xaa03 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc we {be 0xf} {addrh 0x03}] \
-rreg sr.maddrl -edata 0x0004 \
-wreg sr.mdih 0x5504 \
-wreg sr.mdil 0xaa04 \
-wreg sr.maddrl 0xffff \
-wreg sr.mcmd [regbld tst_sram::MCMD ld we {be 0xf} {addrh 0x03}]
# 22bit: 0x040000 0x100001 0x200002 0x300003 0x3fffff
if {[iswide]} {
rlc exec \
-wreg sr.mdih 0xa500 \
-wreg sr.mdil 0x5a00 \
-wreg sr.maddrl 0x0000 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc we {be 0xf} {addrh 0x04}] \
-wreg sr.mdih 0x5a01 \
-wreg sr.mdil 0x5a01 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc we {be 0xf} {addrh 0x10}] \
-wreg sr.mdih 0x5a02 \
-wreg sr.mdil 0x5a02 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc we {be 0xf} {addrh 0x20}] \
-wreg sr.mdih 0x5a03 \
-wreg sr.mdil 0x5a03 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc we {be 0xf} {addrh 0x30}] \
-rreg sr.maddrl -edata 0x0004 \
-wreg sr.mdih 0x5a04 \
-wreg sr.mdil 0x5a04 \
-wreg sr.maddrl 0xffff \
-wreg sr.mcmd [regbld tst_sram::MCMD ld we {be 0xf} {addrh 0x3f}]
}
# reads
rlc exec \
-wreg sr.maddrl 0x0000 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc {be 0xf} {addrh 0x00}] \
-rreg sr.mdoh -edata 0x5500 \
-rreg sr.mdol -edata 0xaa00 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc {be 0xf} {addrh 0x01}] \
-rreg sr.mdoh -edata 0x5501 \
-rreg sr.mdol -edata 0xaa01 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc {be 0xf} {addrh 0x02}] \
-rreg sr.mdoh -edata 0x5502 \
-rreg sr.mdol -edata 0xaa02 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc {be 0xf} {addrh 0x03}] \
-rreg sr.mdoh -edata 0x5503 \
-rreg sr.mdol -edata 0xaa03 \
-rreg sr.maddrl -edata 0x0004 \
-wreg sr.maddrl 0xffff \
-wreg sr.mcmd [regbld tst_sram::MCMD ld {be 0xf} {addrh 0x03}] \
-rreg sr.mdoh -edata 0x5504 \
-rreg sr.mdol -edata 0xaa04
if {[iswide]} {
rlc exec \
-wreg sr.maddrl 0x0000 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc {be 0xf} {addrh 0x04}] \
-rreg sr.mdoh -edata 0xa500 \
-rreg sr.mdol -edata 0x5a00 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc {be 0xf} {addrh 0x10}] \
-rreg sr.mdoh -edata 0x5a01 \
-rreg sr.mdol -edata 0x5a01 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc {be 0xf} {addrh 0x20}] \
-rreg sr.mdoh -edata 0x5a02 \
-rreg sr.mdol -edata 0x5a02 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld inc {be 0xf} {addrh 0x30}] \
-rreg sr.mdoh -edata 0x5a03 \
-rreg sr.mdol -edata 0x5a03 \
-rreg sr.maddrl -edata 0x0004 \
-wreg sr.maddrl 0xffff \
-wreg sr.mcmd [regbld tst_sram::MCMD ld {be 0xf} {addrh 0x3f}] \
-rreg sr.mdoh -edata 0x5a04 \
-rreg sr.mdol -edata 0x5a04
}
#
#-------------------------------------------------------------------------
incr errcnt [rlc errcnt -clear]
return $errcnt
}
}

View File

@@ -0,0 +1,690 @@
# $Id: test_scmdlist.tcl 784 2016-07-09 22:17:01Z mueller $
#
# Copyright 2014- 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 2, 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
# 2014-08-14 582 1.0 Initial version
#
package provide tst_sram 1.0
namespace eval tst_sram {
#
# test_scmdlist: default scmd list -----------------------------------------
# was converted with conv_sblk from cmd_tst_sram_stress_sblk.dat
#
proc test_scmdlist {} {
set clist {}
## C Setup Memory stress test
## C write 16 unique byte patterns (and verify)
lappend clist { 0 w 1111 0x000000 0x30201000};
lappend clist { 0 w 1111 0x000001 0x31211101};
lappend clist { 0 w 1111 0x000002 0x32221202};
lappend clist { 0 w 1111 0x000003 0x33231303};
lappend clist { 0 w 1111 0x000004 0x34241404};
lappend clist { 0 w 1111 0x000005 0x35251505};
lappend clist { 0 w 1111 0x000006 0x36261606};
lappend clist { 0 w 1111 0x000007 0x37271707};
lappend clist { 0 w 1111 0x000008 0x38281808};
lappend clist { 0 w 1111 0x000009 0x39291909};
lappend clist { 0 w 1111 0x00000a 0x3a2a1a0a};
lappend clist { 0 w 1111 0x00000b 0x3b2b1b0b};
lappend clist { 0 w 1111 0x00000c 0x3c2c1c0c};
lappend clist { 0 w 1111 0x00000d 0x3d2d1d0d};
lappend clist { 0 w 1111 0x00000e 0x3e2e1e0e};
lappend clist { 0 w 1111 0x00000f 0x3f2f1f0f};
lappend clist { 0 r 1111 0x000000 0x30201000};
lappend clist { 0 r 1111 0x000001 0x31211101};
lappend clist { 0 r 1111 0x000002 0x32221202};
lappend clist { 0 r 1111 0x000003 0x33231303};
lappend clist { 0 r 1111 0x000004 0x34241404};
lappend clist { 0 r 1111 0x000005 0x35251505};
lappend clist { 0 r 1111 0x000006 0x36261606};
lappend clist { 0 r 1111 0x000007 0x37271707};
lappend clist { 0 r 1111 0x000008 0x38281808};
lappend clist { 0 r 1111 0x000009 0x39291909};
lappend clist { 0 r 1111 0x00000a 0x3a2a1a0a};
lappend clist { 0 r 1111 0x00000b 0x3b2b1b0b};
lappend clist { 0 r 1111 0x00000c 0x3c2c1c0c};
lappend clist { 0 r 1111 0x00000d 0x3d2d1d0d};
lappend clist { 0 r 1111 0x00000e 0x3e2e1e0e};
lappend clist { 0 r 1111 0x00000f 0x3f2f1f0f};
## C single byte writes, all 16 pattern (and verify)
lappend clist { 0 w 0000 0x000000 0x70605040};
lappend clist { 0 w 0001 0x000001 0x71615141};
lappend clist { 0 w 0010 0x000002 0x72625242};
lappend clist { 0 w 0011 0x000003 0x73635343};
lappend clist { 0 w 0100 0x000004 0x74645444};
lappend clist { 0 w 0101 0x000005 0x75655545};
lappend clist { 0 w 0110 0x000006 0x76665646};
lappend clist { 0 w 0111 0x000007 0x77675747};
lappend clist { 0 w 1000 0x000008 0x78685848};
lappend clist { 0 w 1001 0x000009 0x79695949};
lappend clist { 0 w 1010 0x00000a 0x7a6a5a4a};
lappend clist { 0 w 1011 0x00000b 0x7b6b5b4b};
lappend clist { 0 w 1100 0x00000c 0x7c6c5c4c};
lappend clist { 0 w 1101 0x00000d 0x7d6d5d4d};
lappend clist { 0 w 1110 0x00000e 0x7e6e5e4e};
lappend clist { 0 w 1111 0x00000f 0x7f6f5f4f};
lappend clist { 0 r 1111 0x000000 0x30201000};
lappend clist { 0 r 1111 0x000001 0x31211141};
lappend clist { 0 r 1111 0x000002 0x32225202};
lappend clist { 0 r 1111 0x000003 0x33235343};
lappend clist { 0 r 1111 0x000004 0x34641404};
lappend clist { 0 r 1111 0x000005 0x35651545};
lappend clist { 0 r 1111 0x000006 0x36665606};
lappend clist { 0 r 1111 0x000007 0x37675747};
lappend clist { 0 r 1111 0x000008 0x78281808};
lappend clist { 0 r 1111 0x000009 0x79291949};
lappend clist { 0 r 1111 0x00000a 0x7a2a5a0a};
lappend clist { 0 r 1111 0x00000b 0x7b2b5b4b};
lappend clist { 0 r 1111 0x00000c 0x7c6c1c0c};
lappend clist { 0 r 1111 0x00000d 0x7d6d1d4d};
lappend clist { 0 r 1111 0x00000e 0x7e6e5e0e};
lappend clist { 0 r 1111 0x00000f 0x7f6f5f4f};
## C write various 0-1 transition patterns (and verify)
lappend clist { 0 w 1111 0x000010 0x00000000};
lappend clist { 0 w 1111 0x000011 0xffffffff};
lappend clist { 0 w 1111 0x000012 0x00000000};
lappend clist { 0 w 1111 0x000013 0xa5a5a5a5};
lappend clist { 0 w 1111 0x000014 0x5a5a5a5a};
lappend clist { 0 w 1111 0x000015 0x00000000};
lappend clist { 0 w 1111 0x000016 0x0f0f0f0f};
lappend clist { 0 w 1111 0x000017 0xf0f0f0f0};
lappend clist { 0 w 1111 0x000018 0x00ff00ff};
lappend clist { 0 w 1111 0x000019 0xff00ff00};
lappend clist { 0 w 1111 0x00001a 0x0000ffff};
lappend clist { 0 w 1111 0x00001b 0xffff0000};
lappend clist { 0 w 1111 0x00001c 0x0ff00ff0};
lappend clist { 0 w 1111 0x00001d 0xf00ff00f};
lappend clist { 0 w 1111 0x00001e 0x01234567};
lappend clist { 0 w 1111 0x00001f 0x89abcdef};
lappend clist { 0 r 1111 0x000010 0x00000000};
lappend clist { 0 r 1111 0x000011 0xffffffff};
lappend clist { 0 r 1111 0x000012 0x00000000};
lappend clist { 0 r 1111 0x000013 0xa5a5a5a5};
lappend clist { 0 r 1111 0x000014 0x5a5a5a5a};
lappend clist { 0 r 1111 0x000015 0x00000000};
lappend clist { 0 r 1111 0x000016 0x0f0f0f0f};
lappend clist { 0 r 1111 0x000017 0xf0f0f0f0};
lappend clist { 0 r 1111 0x000018 0x00ff00ff};
lappend clist { 0 r 1111 0x000019 0xff00ff00};
lappend clist { 0 r 1111 0x00001a 0x0000ffff};
lappend clist { 0 r 1111 0x00001b 0xffff0000};
lappend clist { 0 r 1111 0x00001c 0x0ff00ff0};
lappend clist { 0 r 1111 0x00001d 0xf00ff00f};
lappend clist { 0 r 1111 0x00001e 0x01234567};
lappend clist { 0 r 1111 0x00001f 0x89abcdef};
## C alternate read sequence of 0-1 transition patterns
lappend clist { 0 r 1111 0x000010 0x00000000};
lappend clist { 0 r 1111 0x000011 0xffffffff};
lappend clist { 0 r 1111 0x00001a 0x0000ffff};
lappend clist { 0 r 1111 0x00001b 0xffff0000};
lappend clist { 0 r 1111 0x000012 0x00000000};
lappend clist { 0 r 1111 0x000013 0xa5a5a5a5};
lappend clist { 0 r 1111 0x000011 0xffffffff};
lappend clist { 0 r 1111 0x000014 0x5a5a5a5a};
lappend clist { 0 r 1111 0x000015 0x00000000};
lappend clist { 0 r 1111 0x000013 0xa5a5a5a5};
lappend clist { 0 r 1111 0x000015 0x00000000};
lappend clist { 0 r 1111 0x000014 0x5a5a5a5a};
lappend clist { 0 r 1111 0x000017 0xf0f0f0f0};
lappend clist { 0 r 1111 0x000016 0x0f0f0f0f};
lappend clist { 0 r 1111 0x000019 0xff00ff00};
lappend clist { 0 r 1111 0x000018 0x00ff00ff};
lappend clist { 0 r 1111 0x00001d 0xf00ff00f};
lappend clist { 0 r 1111 0x00001c 0x0ff00ff0};
lappend clist { 0 r 1111 0x000010 0x00000000};
lappend clist { 0 r 1111 0x00001e 0x01234567};
lappend clist { 0 r 1111 0x00001a 0x0000ffff};
lappend clist { 0 r 1111 0x00001f 0x89abcdef};
lappend clist { 0 r 1111 0x00001b 0xffff0000};
lappend clist { 0 r 1111 0x000012 0x00000000};
lappend clist { 0 r 1111 0x00001f 0x89abcdef};
lappend clist { 0 r 1111 0x000016 0x0f0f0f0f};
lappend clist { 0 r 1111 0x000018 0x00ff00ff};
lappend clist { 0 r 1111 0x000017 0xf0f0f0f0};
lappend clist { 0 r 1111 0x000019 0xff00ff00};
lappend clist { 0 r 1111 0x00001d 0xf00ff00f};
lappend clist { 0 r 1111 0x00001c 0x0ff00ff0};
lappend clist { 0 r 1111 0x00001e 0x01234567};
## C write alternating all-0 and all-1 at low and top addresses
lappend clist { 0 w 1111 0x000020 0x00000000};
lappend clist { 0 w 1111 0x000021 0xffffffff};
lappend clist { 0 w 1111 0x000022 0x00000000};
lappend clist { 0 w 1111 0x000023 0xffffffff};
lappend clist { 0 w 1111 0x000024 0x00000000};
lappend clist { 0 w 1111 0x000025 0xffffffff};
lappend clist { 0 w 1111 0x000026 0x00000000};
lappend clist { 0 w 1111 0x000027 0xffffffff};
lappend clist { 0 w 1111 0x000028 0x00000000};
lappend clist { 0 w 1111 0x03fff9 0xffffffff};
lappend clist { 0 w 1111 0x00002a 0x00000000};
lappend clist { 0 w 1111 0x03fffb 0xffffffff};
lappend clist { 0 w 1111 0x03fffc 0x00000000};
lappend clist { 0 w 1111 0x00002d 0xffffffff};
lappend clist { 0 w 1111 0x03fffe 0x00000000};
lappend clist { 0 w 1111 0x00002f 0xffffffff};
lappend clist { 0 w 1111 0x03fff0 0x00000000};
lappend clist { 0 w 1111 0x03fff1 0xffffffff};
lappend clist { 0 w 1111 0x03fff2 0x00000000};
lappend clist { 0 w 1111 0x03fff3 0xffffffff};
lappend clist { 0 w 1111 0x03fff4 0x00000000};
lappend clist { 0 w 1111 0x03fff5 0xffffffff};
lappend clist { 0 w 1111 0x03fff6 0x00000000};
lappend clist { 0 w 1111 0x03fff7 0xffffffff};
lappend clist { 0 w 1111 0x03fff8 0x00000000};
lappend clist { 0 w 1111 0x000029 0xffffffff};
lappend clist { 0 w 1111 0x03fffa 0x00000000};
lappend clist { 0 w 1111 0x00002b 0xffffffff};
lappend clist { 0 w 1111 0x00002c 0x00000000};
lappend clist { 0 w 1111 0x03fffd 0xffffffff};
lappend clist { 0 w 1111 0x00002e 0x00000000};
lappend clist { 0 w 1111 0x03ffff 0xffffffff};
## C read alternating all-0 and all-1 sequence, only data bounce
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000022 0x00000000};
lappend clist { 0 r 1111 0x000023 0xffffffff};
lappend clist { 0 r 1111 0x000024 0x00000000};
lappend clist { 0 r 1111 0x000025 0xffffffff};
lappend clist { 0 r 1111 0x000026 0x00000000};
lappend clist { 0 r 1111 0x000027 0xffffffff};
lappend clist { 0 r 1111 0x000028 0x00000000};
lappend clist { 0 r 1111 0x000029 0xffffffff};
lappend clist { 0 r 1111 0x00002a 0x00000000};
lappend clist { 0 r 1111 0x00002b 0xffffffff};
lappend clist { 0 r 1111 0x00002c 0x00000000};
lappend clist { 0 r 1111 0x00002d 0xffffffff};
lappend clist { 0 r 1111 0x00002e 0x00000000};
lappend clist { 0 r 1111 0x00002f 0xffffffff};
lappend clist { 0 r 1111 0x03fff0 0x00000000};
lappend clist { 0 r 1111 0x03fff1 0xffffffff};
lappend clist { 0 r 1111 0x03fff2 0x00000000};
lappend clist { 0 r 1111 0x03fff3 0xffffffff};
lappend clist { 0 r 1111 0x03fff4 0x00000000};
lappend clist { 0 r 1111 0x03fff5 0xffffffff};
lappend clist { 0 r 1111 0x03fff6 0x00000000};
lappend clist { 0 r 1111 0x03fff7 0xffffffff};
lappend clist { 0 r 1111 0x03fff8 0x00000000};
lappend clist { 0 r 1111 0x03fff9 0xffffffff};
lappend clist { 0 r 1111 0x03fffa 0x00000000};
lappend clist { 0 r 1111 0x03fffb 0xffffffff};
lappend clist { 0 r 1111 0x03fffc 0x00000000};
lappend clist { 0 r 1111 0x03fffd 0xffffffff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
## C read alternating all-0 and all-1 sequence, addr and data bounce
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x03fff1 0xffffffff};
lappend clist { 0 r 1111 0x000022 0x00000000};
lappend clist { 0 r 1111 0x03fff3 0xffffffff};
lappend clist { 0 r 1111 0x000024 0x00000000};
lappend clist { 0 r 1111 0x03fff5 0xffffffff};
lappend clist { 0 r 1111 0x000026 0x00000000};
lappend clist { 0 r 1111 0x03fff7 0xffffffff};
lappend clist { 0 r 1111 0x000028 0x00000000};
lappend clist { 0 r 1111 0x000029 0xffffffff};
lappend clist { 0 r 1111 0x03fffa 0x00000000};
lappend clist { 0 r 1111 0x00002b 0xffffffff};
lappend clist { 0 r 1111 0x03fffc 0x00000000};
lappend clist { 0 r 1111 0x00002d 0xffffffff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x00002f 0xffffffff};
lappend clist { 0 r 1111 0x03fff0 0x00000000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x03fff2 0x00000000};
lappend clist { 0 r 1111 0x000023 0xffffffff};
lappend clist { 0 r 1111 0x03fff4 0x00000000};
lappend clist { 0 r 1111 0x000025 0xffffffff};
lappend clist { 0 r 1111 0x03fff6 0x00000000};
lappend clist { 0 r 1111 0x000027 0xffffffff};
lappend clist { 0 r 1111 0x03fff8 0x00000000};
lappend clist { 0 r 1111 0x03fff9 0xffffffff};
lappend clist { 0 r 1111 0x00002a 0x00000000};
lappend clist { 0 r 1111 0x03fffb 0xffffffff};
lappend clist { 0 r 1111 0x00002c 0x00000000};
lappend clist { 0 r 1111 0x03fffd 0xffffffff};
lappend clist { 0 r 1111 0x00002e 0x00000000};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
## C write 32 words with single 1 bit (and verify)
lappend clist { 0 w 1111 0x000040 0x00000001};
lappend clist { 0 w 1111 0x000041 0x00000002};
lappend clist { 0 w 1111 0x000042 0x00000004};
lappend clist { 0 w 1111 0x000043 0x00000008};
lappend clist { 0 w 1111 0x000044 0x00000010};
lappend clist { 0 w 1111 0x000045 0x00000020};
lappend clist { 0 w 1111 0x000046 0x00000040};
lappend clist { 0 w 1111 0x000047 0x00000080};
lappend clist { 0 w 1111 0x000048 0x00000100};
lappend clist { 0 w 1111 0x000049 0x00000200};
lappend clist { 0 w 1111 0x00004a 0x00000400};
lappend clist { 0 w 1111 0x00004b 0x00000800};
lappend clist { 0 w 1111 0x00004c 0x00001000};
lappend clist { 0 w 1111 0x00004d 0x00002000};
lappend clist { 0 w 1111 0x00004e 0x00004000};
lappend clist { 0 w 1111 0x00004f 0x00008000};
lappend clist { 0 w 1111 0x000050 0x00010000};
lappend clist { 0 w 1111 0x000051 0x00020000};
lappend clist { 0 w 1111 0x000052 0x00040000};
lappend clist { 0 w 1111 0x000053 0x00080000};
lappend clist { 0 w 1111 0x000054 0x00100000};
lappend clist { 0 w 1111 0x000055 0x00200000};
lappend clist { 0 w 1111 0x000056 0x00400000};
lappend clist { 0 w 1111 0x000057 0x00800000};
lappend clist { 0 w 1111 0x000058 0x01000000};
lappend clist { 0 w 1111 0x000059 0x02000000};
lappend clist { 0 w 1111 0x00005a 0x04000000};
lappend clist { 0 w 1111 0x00005b 0x08000000};
lappend clist { 0 w 1111 0x00005c 0x10000000};
lappend clist { 0 w 1111 0x00005d 0x20000000};
lappend clist { 0 w 1111 0x00005e 0x40000000};
lappend clist { 0 w 1111 0x00005f 0x80000000};
lappend clist { 0 r 1111 0x000040 0x00000001};
lappend clist { 0 r 1111 0x000041 0x00000002};
lappend clist { 0 r 1111 0x000042 0x00000004};
lappend clist { 0 r 1111 0x000043 0x00000008};
lappend clist { 0 r 1111 0x000044 0x00000010};
lappend clist { 0 r 1111 0x000045 0x00000020};
lappend clist { 0 r 1111 0x000046 0x00000040};
lappend clist { 0 r 1111 0x000047 0x00000080};
lappend clist { 0 r 1111 0x000048 0x00000100};
lappend clist { 0 r 1111 0x000049 0x00000200};
lappend clist { 0 r 1111 0x00004a 0x00000400};
lappend clist { 0 r 1111 0x00004b 0x00000800};
lappend clist { 0 r 1111 0x00004c 0x00001000};
lappend clist { 0 r 1111 0x00004d 0x00002000};
lappend clist { 0 r 1111 0x00004e 0x00004000};
lappend clist { 0 r 1111 0x00004f 0x00008000};
lappend clist { 0 r 1111 0x000050 0x00010000};
lappend clist { 0 r 1111 0x000051 0x00020000};
lappend clist { 0 r 1111 0x000052 0x00040000};
lappend clist { 0 r 1111 0x000053 0x00080000};
lappend clist { 0 r 1111 0x000054 0x00100000};
lappend clist { 0 r 1111 0x000055 0x00200000};
lappend clist { 0 r 1111 0x000056 0x00400000};
lappend clist { 0 r 1111 0x000057 0x00800000};
lappend clist { 0 r 1111 0x000058 0x01000000};
lappend clist { 0 r 1111 0x000059 0x02000000};
lappend clist { 0 r 1111 0x00005a 0x04000000};
lappend clist { 0 r 1111 0x00005b 0x08000000};
lappend clist { 0 r 1111 0x00005c 0x10000000};
lappend clist { 0 r 1111 0x00005d 0x20000000};
lappend clist { 0 r 1111 0x00005e 0x40000000};
lappend clist { 0 r 1111 0x00005f 0x80000000};
## C alternating read of 1 bit and all-1 word
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000040 0x00000001};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000041 0x00000002};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000042 0x00000004};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000043 0x00000008};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000044 0x00000010};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000045 0x00000020};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000046 0x00000040};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000047 0x00000080};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000048 0x00000100};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000049 0x00000200};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00004a 0x00000400};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00004b 0x00000800};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00004c 0x00001000};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00004d 0x00002000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00004e 0x00004000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00004f 0x00008000};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000050 0x00010000};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000051 0x00020000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000052 0x00040000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000053 0x00080000};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000054 0x00100000};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000055 0x00200000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000056 0x00400000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000057 0x00800000};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000058 0x01000000};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000059 0x02000000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00005a 0x04000000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00005b 0x08000000};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00005c 0x10000000};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00005d 0x20000000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00005e 0x40000000};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00005f 0x80000000};
## C write 32 words with thermometer code (and verify)
lappend clist { 0 w 1111 0x000060 0x00000001};
lappend clist { 0 w 1111 0x000061 0x00000003};
lappend clist { 0 w 1111 0x000062 0x00000007};
lappend clist { 0 w 1111 0x000063 0x0000000f};
lappend clist { 0 w 1111 0x000064 0x0000001f};
lappend clist { 0 w 1111 0x000065 0x0000003f};
lappend clist { 0 w 1111 0x000066 0x0000007f};
lappend clist { 0 w 1111 0x000067 0x000000ff};
lappend clist { 0 w 1111 0x000068 0x000001ff};
lappend clist { 0 w 1111 0x000069 0x000003ff};
lappend clist { 0 w 1111 0x00006a 0x000007ff};
lappend clist { 0 w 1111 0x00006b 0x00000fff};
lappend clist { 0 w 1111 0x00006c 0x00001fff};
lappend clist { 0 w 1111 0x00006d 0x00003fff};
lappend clist { 0 w 1111 0x00006e 0x00007fff};
lappend clist { 0 w 1111 0x00006f 0x0000ffff};
lappend clist { 0 w 1111 0x000070 0x0001ffff};
lappend clist { 0 w 1111 0x000071 0x0003ffff};
lappend clist { 0 w 1111 0x000072 0x0007ffff};
lappend clist { 0 w 1111 0x000073 0x000fffff};
lappend clist { 0 w 1111 0x000074 0x001fffff};
lappend clist { 0 w 1111 0x000075 0x003fffff};
lappend clist { 0 w 1111 0x000076 0x007fffff};
lappend clist { 0 w 1111 0x000077 0x00ffffff};
lappend clist { 0 w 1111 0x000078 0x01ffffff};
lappend clist { 0 w 1111 0x000079 0x03ffffff};
lappend clist { 0 w 1111 0x00007a 0x07ffffff};
lappend clist { 0 w 1111 0x00007b 0x0fffffff};
lappend clist { 0 w 1111 0x00007c 0x1fffffff};
lappend clist { 0 w 1111 0x00007d 0x3fffffff};
lappend clist { 0 w 1111 0x00007e 0x7fffffff};
lappend clist { 0 w 1111 0x00007f 0xffffffff};
lappend clist { 0 r 1111 0x000060 0x00000001};
lappend clist { 0 r 1111 0x000061 0x00000003};
lappend clist { 0 r 1111 0x000062 0x00000007};
lappend clist { 0 r 1111 0x000063 0x0000000f};
lappend clist { 0 r 1111 0x000064 0x0000001f};
lappend clist { 0 r 1111 0x000065 0x0000003f};
lappend clist { 0 r 1111 0x000066 0x0000007f};
lappend clist { 0 r 1111 0x000067 0x000000ff};
lappend clist { 0 r 1111 0x000068 0x000001ff};
lappend clist { 0 r 1111 0x000069 0x000003ff};
lappend clist { 0 r 1111 0x00006a 0x000007ff};
lappend clist { 0 r 1111 0x00006b 0x00000fff};
lappend clist { 0 r 1111 0x00006c 0x00001fff};
lappend clist { 0 r 1111 0x00006d 0x00003fff};
lappend clist { 0 r 1111 0x00006e 0x00007fff};
lappend clist { 0 r 1111 0x00006f 0x0000ffff};
lappend clist { 0 r 1111 0x000070 0x0001ffff};
lappend clist { 0 r 1111 0x000071 0x0003ffff};
lappend clist { 0 r 1111 0x000072 0x0007ffff};
lappend clist { 0 r 1111 0x000073 0x000fffff};
lappend clist { 0 r 1111 0x000074 0x001fffff};
lappend clist { 0 r 1111 0x000075 0x003fffff};
lappend clist { 0 r 1111 0x000076 0x007fffff};
lappend clist { 0 r 1111 0x000077 0x00ffffff};
lappend clist { 0 r 1111 0x000078 0x01ffffff};
lappend clist { 0 r 1111 0x000079 0x03ffffff};
lappend clist { 0 r 1111 0x00007a 0x07ffffff};
lappend clist { 0 r 1111 0x00007b 0x0fffffff};
lappend clist { 0 r 1111 0x00007c 0x1fffffff};
lappend clist { 0 r 1111 0x00007d 0x3fffffff};
lappend clist { 0 r 1111 0x00007e 0x7fffffff};
lappend clist { 0 r 1111 0x00007f 0xffffffff};
## C alternating read of thermometer code and all-1 word
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000060 0x00000001};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000061 0x00000003};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000062 0x00000007};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000063 0x0000000f};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000064 0x0000001f};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000065 0x0000003f};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000066 0x0000007f};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000067 0x000000ff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000068 0x000001ff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000069 0x000003ff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00006a 0x000007ff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00006b 0x00000fff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00006c 0x00001fff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00006d 0x00003fff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00006e 0x00007fff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00006f 0x0000ffff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000070 0x0001ffff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000071 0x0003ffff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000072 0x0007ffff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000073 0x000fffff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000074 0x001fffff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000075 0x003fffff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000076 0x007fffff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x000077 0x00ffffff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000078 0x01ffffff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x000079 0x03ffffff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00007a 0x07ffffff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00007b 0x0fffffff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00007c 0x1fffffff};
lappend clist { 0 r 1111 0x000021 0xffffffff};
lappend clist { 0 r 1111 0x00007d 0x3fffffff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00007e 0x7fffffff};
lappend clist { 0 r 1111 0x03ffff 0xffffffff};
lappend clist { 0 r 1111 0x00007f 0xffffffff};
## C alternating read of thermometer code and all-0 word
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000060 0x00000001};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000061 0x00000003};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x000062 0x00000007};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x000063 0x0000000f};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000064 0x0000001f};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000065 0x0000003f};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x000066 0x0000007f};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x000067 0x000000ff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000068 0x000001ff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000069 0x000003ff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x00006a 0x000007ff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x00006b 0x00000fff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x00006c 0x00001fff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x00006d 0x00003fff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x00006e 0x00007fff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x00006f 0x0000ffff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000070 0x0001ffff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000071 0x0003ffff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x000072 0x0007ffff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x000073 0x000fffff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000074 0x001fffff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000075 0x003fffff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x000076 0x007fffff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x000077 0x00ffffff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000078 0x01ffffff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x000079 0x03ffffff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x00007a 0x07ffffff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x00007b 0x0fffffff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x00007c 0x1fffffff};
lappend clist { 0 r 1111 0x000020 0x00000000};
lappend clist { 0 r 1111 0x00007d 0x3fffffff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x00007e 0x7fffffff};
lappend clist { 0 r 1111 0x03fffe 0x00000000};
lappend clist { 0 r 1111 0x00007f 0xffffffff};
## # random sequence generated with gen_tst_sram_ranseq 64
## C now do some write/read tests with random addr/data
## C 16 writes
lappend clist { 0 w 1111 0x0039dc 0x96d0e73e};
lappend clist { 0 w 1111 0x006d4a 0xbbbb4372};
lappend clist { 0 w 1111 0x0092b6 0xf58ace40};
lappend clist { 0 w 1111 0x01393e 0xeb748a98};
lappend clist { 0 w 1111 0x019b4c 0x69281826};
lappend clist { 0 w 1111 0x02a8ba 0xdae538d7};
lappend clist { 0 w 1111 0x00341a 0x8f42ffbd};
lappend clist { 0 w 1111 0x01b18a 0x5b523e97};
lappend clist { 0 w 1111 0x039bb7 0x46eea237};
lappend clist { 0 w 1111 0x03f294 0x8824fcef};
lappend clist { 0 w 1111 0x036375 0xd1c10ba8};
lappend clist { 0 w 1111 0x0067f6 0xfc93d1dc};
lappend clist { 0 w 1111 0x01242e 0x1316562d};
lappend clist { 0 w 1111 0x00a090 0x0779b757};
lappend clist { 0 w 1111 0x01aebe 0xe06ae43f};
lappend clist { 0 w 1111 0x019109 0xf558ccb4};
## C 16 writes and 16 reads mixed
lappend clist { 0 w 1111 0x03c4a6 0x96dbbcff};
lappend clist { 0 r 1111 0x0039dc 0x96d0e73e};
lappend clist { 0 w 1111 0x016ea6 0x14010c8f};
lappend clist { 0 r 1111 0x006d4a 0xbbbb4372};
lappend clist { 0 r 1111 0x0092b6 0xf58ace40};
lappend clist { 0 w 1111 0x037728 0xe4b4e052};
lappend clist { 0 w 1111 0x0265d5 0x9d612c95};
lappend clist { 0 r 1111 0x01393e 0xeb748a98};
lappend clist { 0 w 1111 0x017b76 0xfe2576be};
lappend clist { 0 r 1111 0x019b4c 0x69281826};
lappend clist { 0 w 1111 0x0172cc 0x4f67af1f};
lappend clist { 0 w 1111 0x005b4b 0x8f7e559d};
lappend clist { 0 w 1111 0x019341 0xa829717d};
lappend clist { 0 r 1111 0x02a8ba 0xdae538d7};
lappend clist { 0 r 1111 0x00341a 0x8f42ffbd};
lappend clist { 0 r 1111 0x01b18a 0x5b523e97};
lappend clist { 0 w 1111 0x034de2 0xd53f120f};
lappend clist { 0 r 1111 0x039bb7 0x46eea237};
lappend clist { 0 w 1111 0x02119e 0x6253f647};
lappend clist { 0 r 1111 0x03f294 0x8824fcef};
lappend clist { 0 w 1111 0x00f1ac 0x936c2522};
lappend clist { 0 r 1111 0x036375 0xd1c10ba8};
lappend clist { 0 w 1111 0x00716b 0x2db9e1fa};
lappend clist { 0 r 1111 0x0067f6 0xfc93d1dc};
lappend clist { 0 w 1111 0x01781f 0xae31b1e7};
lappend clist { 0 r 1111 0x01242e 0x1316562d};
lappend clist { 0 w 1111 0x0187bf 0xccdbf8e7};
lappend clist { 0 w 1111 0x029b82 0x95274e53};
lappend clist { 0 r 1111 0x00a090 0x0779b757};
lappend clist { 0 r 1111 0x01aebe 0xe06ae43f};
lappend clist { 0 w 1111 0x0244c7 0x5fd2ee97};
lappend clist { 0 r 1111 0x019109 0xf558ccb4};
## C 16 writes and 16 reads mixed, with waits
lappend clist { 0 w 1111 0x0239b6 0x8f147909};
lappend clist { 1 r 1111 0x03c4a6 0x96dbbcff};
lappend clist { 0 w 1111 0x03b485 0x9f2c58f4};
lappend clist { 2 r 1111 0x016ea6 0x14010c8f};
lappend clist { 0 w 1111 0x01e384 0xde6a4ad3};
lappend clist { 0 r 1111 0x037728 0xe4b4e052};
lappend clist { 1 w 1111 0x00abc1 0x4a3aafbe};
lappend clist { 0 r 1111 0x0265d5 0x9d612c95};
lappend clist { 2 w 1111 0x03cbb0 0x0adff6f0};
lappend clist { 0 r 1111 0x017b76 0xfe2576be};
lappend clist { 2 r 1111 0x0172cc 0x4f67af1f};
lappend clist { 0 w 1111 0x0128cc 0x94959a76};
lappend clist { 1 r 1111 0x005b4b 0x8f7e559d};
lappend clist { 0 r 1111 0x019341 0xa829717d};
lappend clist { 2 w 1111 0x029a71 0xad031981};
lappend clist { 0 r 1111 0x034de2 0xd53f120f};
lappend clist { 3 r 1111 0x02119e 0x6253f647};
lappend clist { 0 w 1111 0x004b60 0xcb3cfc9a};
lappend clist { 1 r 1111 0x00f1ac 0x936c2522};
lappend clist { 0 w 1111 0x03dc56 0x1bd4948d};
lappend clist { 2 w 1111 0x01a28a 0x9b8c1f3d};
lappend clist { 0 r 1111 0x00716b 0x2db9e1fa};
lappend clist { 3 w 1111 0x037682 0x4f8e2aca};
lappend clist { 0 w 1111 0x00d920 0xb6f4fdfc};
lappend clist { 1 r 1111 0x01781f 0xae31b1e7};
lappend clist { 0 w 1111 0x024aed 0x289e121a};
lappend clist { 2 w 1111 0x037d2d 0x43b8b430};
lappend clist { 0 r 1111 0x0187bf 0xccdbf8e7};
lappend clist { 3 w 1111 0x008798 0x19a1600a};
lappend clist { 0 w 1111 0x02eb94 0xda68509a};
lappend clist { 1 r 1111 0x029b82 0x95274e53};
lappend clist { 2 r 1111 0x0244c7 0x5fd2ee97};
## C finally 16 reads
lappend clist { 0 r 1111 0x0239b6 0x8f147909};
lappend clist { 0 r 1111 0x03b485 0x9f2c58f4};
lappend clist { 0 r 1111 0x01e384 0xde6a4ad3};
lappend clist { 0 r 1111 0x00abc1 0x4a3aafbe};
lappend clist { 0 r 1111 0x03cbb0 0x0adff6f0};
lappend clist { 0 r 1111 0x0128cc 0x94959a76};
lappend clist { 0 r 1111 0x029a71 0xad031981};
lappend clist { 0 r 1111 0x004b60 0xcb3cfc9a};
lappend clist { 0 r 1111 0x03dc56 0x1bd4948d};
lappend clist { 0 r 1111 0x01a28a 0x9b8c1f3d};
lappend clist { 0 r 1111 0x037682 0x4f8e2aca};
lappend clist { 0 r 1111 0x00d920 0xb6f4fdfc};
lappend clist { 0 r 1111 0x024aed 0x289e121a};
lappend clist { 0 r 1111 0x037d2d 0x43b8b430};
lappend clist { 0 r 1111 0x008798 0x19a1600a};
lappend clist { 0 r 1111 0x02eb94 0xda68509a};
return $clist
}
}

View File

@@ -0,0 +1,634 @@
# $Id: test_seq.tcl 785 2016-07-10 12:22:41Z mueller $
#
# Copyright 2016- 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 2, 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
# 2016-07-10 785 1.1 add wswap and wloop tests
# 2016-07-09 784 1.0 Initial version (ported from tb_tst_sram_stim.dat)
#
package provide tst_sram 1.0
package require rutiltpp
package require rutil
package require rlink
namespace eval tst_sram {
#
# test_seq_srum: helper: run sequencer and check status
#
proc test_seq_srun {{sstat 0} {tout 10.} {seaddr 0} {sedath 0} {sedatl 0}} {
variable nscmd
if {$nscmd == 0} {error "no or empty scmd list loaded"}
#
# set slim, sstat and start sequencer
rlc exec \
-wreg sr.slim [expr {$nscmd-1}] \
-wreg sr.sstat $sstat \
-wreg sr.sstart 0
# wait for completion
rlc wtlam $tout
# harvest attn and check sequencer status
# also check rlink command status (RB_STAT(1) <= R_REGS.sfail)
set seqmsk [rutil::com16 [regbld tst_sram::SSTAT wide]]; # ign sstat.wide !
set stamsk [regbld rlink::STAT {stat -1} rbtout rbnak rberr];
if {$seaddr == 0} { # fail=0 --> check saddr
rlc exec \
-attn -edata 0x0001 \
-rreg sr.sstat -edata $sstat $seqmsk -estat 0 $stamsk \
-rreg sr.saddr -edata $nscmd -estat 0 $stamsk
} else { # fail=1 --> check seaddr
set sstat_exp [expr {$sstat | [regbld tst_sram::SSTAT fail]}]
set stabad [regbld rlink::STAT {stat 2}]; # expect status.stat = 0x2
rlc exec \
-attn -edata 0x0001 \
-rreg sr.sstat -edata $sstat_exp $seqmsk -estat $stabad $stamsk \
-rreg sr.seaddr -edata $seaddr -estat $stabad $stamsk \
-rreg sr.sedath -edata $sedath -estat $stabad $stamsk \
-rreg sr.sedatl -edata $sedatl -estat $stabad $stamsk
}
return ""
}
#
# test_seq_setxor: helper: setup maddr* and mdi*
#
proc test_seq_setxor {maddrh maddrl mdih mdil} {
rlc exec \
-wreg sr.maddrh $maddrh \
-wreg sr.maddrl $maddrl \
-wreg sr.mdih $mdih \
-wreg sr.mdil $mdil
}
#
# test_seq: Test sequencer, basic 18 bit mode
#
proc test_seq {{tout 10.}} {
variable nscmd
#
set errcnt 0
rlc errcnt -clear
set sm [rutil::com16 [regbld tst_sram::SSTAT wide]]
rlink::anena 1; # enable attn notify
#
rlc log "tst_sram::test_seq ----------------------------------------------"
#
#-------------------------------------------------------------------------
rlc log " test 1: list of write commands"
# load list of 8 mem write commands
set clist {}
lappend clist { 0 w 1111 0x000110 0x70605040};
lappend clist { 0 w 1111 0x000111 0x71615141};
lappend clist { 0 w 1111 0x000112 0x72625242};
lappend clist { 0 w 1111 0x000113 0x73635343};
lappend clist { 0 w 1111 0x000114 0x74645444};
lappend clist { 0 w 1111 0x000115 0x75655545};
lappend clist { 0 w 1111 0x000116 0x76665646};
lappend clist { 0 w 1111 0x000117 0x77675747};
scmd_write $clist
# run sequencer (plain xord=0 xora=0 veri=0)
test_seq_srun 0 $tout
# read back 8 longwords
rlc exec \
-wreg sr.maddrh 0x0000 \
-wreg sr.maddrl 0x0110 \
-wblk sr.mblk {0x7060 0x5040 \
0x7161 0x5141 \
0x7262 0x5242 \
0x7363 0x5343 \
0x7464 0x5444 \
0x7565 0x5545 \
0x7666 0x5646 \
0x7767 0x5747}
#
#-------------------------------------------------------------------------
rlc log " test 2: list of read commands"
# load list of 8 mem read commands
set clist {}
lappend clist { 0 r 1111 0x000110 0xdead0000};
lappend clist { 0 r 1111 0x000111 0xbeaf1111};
lappend clist { 0 r 1111 0x000112 0xdead2222};
lappend clist { 0 r 1111 0x000113 0xbeaf3333};
lappend clist { 0 r 1111 0x000114 0xdead4444};
lappend clist { 0 r 1111 0x000115 0xbeaf5555};
lappend clist { 0 r 1111 0x000116 0xdead6666};
lappend clist { 0 r 1111 0x000117 0xbeaf7777};
scmd_write $clist
# run sequencer (plain xord=0 xora=0 veri=0)
test_seq_srun 0 $tout
# read back data part of sequencer
rlc exec \
-wreg sr.saddr 0x0000 \
-rblk sr.sblkd 16 -edata {0x7060 0x5040
0x7161 0x5141 \
0x7262 0x5242 \
0x7363 0x5343 \
0x7464 0x5444 \
0x7565 0x5545 \
0x7666 0x5646 \
0x7767 0x5747}
#
#-------------------------------------------------------------------------
rlc log " test 3: mixed list of writes (some byte wise) and reads"
# this list modifies the memory left from previous test !
set clist {}
lappend clist { 0 w 0001 0x000112 0x00000082}; # wr 12 0001
lappend clist { 0 w 0010 0x000113 0x00009300}; # wr 13 0010
lappend clist { 0 r 1111 0x000110 0x00000000}; # rd 10
lappend clist { 0 w 0100 0x000114 0x00a40000}; # wr 14 0100
lappend clist { 0 r 1111 0x000111 0x00000000}; # rd 11
lappend clist { 0 w 1000 0x000115 0xb5000000}; # wr 15 1000
lappend clist { 0 r 1111 0x000112 0x00000000}; # rd 12
lappend clist { 0 r 1111 0x000113 0x00000000}; # rd 13
lappend clist { 0 w 1111 0x000118 0x78685848}; # wr 18
lappend clist { 0 r 1111 0x000114 0x00000000}; # rd 14
lappend clist { 0 w 1111 0x000119 0x79695949}; # wr 19
lappend clist { 0 w 1111 0x00011a 0x7a6a5a4a}; # wr 1a
lappend clist { 0 r 1111 0x000115 0x00000000}; # rd 15
lappend clist { 0 w 1111 0x00011b 0x7b6b5b4b}; # wr 1b
lappend clist { 0 r 1111 0x000116 0x00000000}; # rd 16
lappend clist { 0 w 1111 0x00011c 0x7c6c5c4c}; # wr 1c
lappend clist { 0 w 1111 0x00011d 0x7d6d5d4d}; # wr 1d
lappend clist { 0 r 1111 0x000117 0x00000000}; # rd 17
lappend clist { 0 r 1111 0x000118 0x00000000}; # rd 18
lappend clist { 0 w 1111 0x00011e 0x7e6e5e4e}; # wr 1e
lappend clist { 0 w 1111 0x00011f 0x7f6f5f4f}; # wr 1f
lappend clist { 0 r 1111 0x000119 0x00000000}; # rd 19
lappend clist { 0 r 1111 0x00011a 0x00000000}; # rd 1a
lappend clist { 0 r 1111 0x00011b 0x00000000}; # rd 1b
lappend clist { 0 r 1111 0x00011c 0x00000000}; # rd 1c
lappend clist { 0 r 1111 0x00011d 0x00000000}; # rd 1d
lappend clist { 0 r 1111 0x00011e 0x00000000}; # rd 1e
lappend clist { 0 r 1111 0x00011f 0x00000000}; # rd 1f
scmd_write $clist
# run sequencer (plain xord=0 xora=0 veri=0)
test_seq_srun 0 $tout
# read back data part of sequencer
rlc exec \
-wreg sr.saddr 0x0000 \
-rblk sr.sblkd 56 -edata {0x0000 0x0082 \
0x0000 0x9300 \
0x7060 0x5040 \
0x00a4 0x0000 \
0x7161 0x5141 \
0xb500 0x0000 \
0x7262 0x5282 \
0x7363 0x9343 \
0x7868 0x5848 \
0x74a4 0x5444 \
0x7969 0x5949 \
0x7a6a 0x5a4a \
0xb565 0x5545 \
0x7b6b 0x5b4b \
0x7666 0x5646 \
0x7c6c 0x5c4c \
0x7d6d 0x5d4d \
0x7767 0x5747 \
0x7868 0x5848 \
0x7e6e 0x5e4e \
0x7f6f 0x5f4f \
0x7969 0x5949 \
0x7a6a 0x5a4a \
0x7b6b 0x5b4b \
0x7c6c 0x5c4c \
0x7d6d 0x5d4d \
0x7e6e 0x5e4e \
0x7f6f 0x5f4f}
#
#-------------------------------------------------------------------------
rlc log " test 4: sequencer verify mode"
# list of 4 mem write and 4 read commands
set clist {}
lappend clist { 0 w 1111 0x000220 0xb0a09080};
lappend clist { 0 w 1111 0x000221 0xb1a19181};
lappend clist { 0 r 1111 0x000220 0xb0a09080};
lappend clist { 0 w 1111 0x000222 0xb2a29282};
lappend clist { 0 r 1111 0x000221 0xb1a19181};
lappend clist { 0 w 1111 0x000223 0xb3a39383};
lappend clist { 0 r 1111 0x000222 0xb2a29282};
lappend clist { 0 r 1111 0x000223 0xb3a39383};
scmd_write $clist
# run sequencer (veri=1)
test_seq_srun [regbld tst_sram::SSTAT veri] $tout
# again, but with mismatch on 2nd read
set clist {}
lappend clist { 0 w 1111 0x000230 0xb0a09080}; # 0
lappend clist { 0 w 1111 0x000231 0xb1a19181}; # 1
lappend clist { 0 r 1111 0x000230 0xb0a09080}; # 2
lappend clist { 0 w 1111 0x000232 0xb2a29282}; # 3
lappend clist { 0 r 1111 0x000231 0x00000000}; # 4 <-- read mismatch here
lappend clist { 0 w 1111 0x000233 0xb3a39383}; # 5
lappend clist { 0 r 1111 0x000232 0xb2a29282}; # 6
lappend clist { 0 r 1111 0x000233 0xb3a39383}; # 7
scmd_write $clist
# run sequencer (veri=1, expect fail)
test_seq_srun [regbld tst_sram::SSTAT veri] $tout 4 0xb1a1 0x9181
# sblkd re-read data, check that data part wasn't overwritten
rlc exec \
-wreg sr.saddr 0 \
-rblk sr.sblkd 16 -edata {0xb0a0 0x9080 \
0xb1a1 0x9181 \
0xb0a0 0x9080 \
0xb2a2 0x9282 \
0x0000 0x0000 \
0xb3a3 0x9383 \
0xb2a2 0x9282 \
0xb3a3 0x9383}
#
#-------------------------------------------------------------------------
rlc log " test 5: test reset via init"
# expects state from fail srun of previous test with
# seaddr=0x0004 sedath=0xb1a1 sedatl=0x9181
# re-check fail bit status bit set from previous test
rlc exec \
-rreg sr.sstat -edata [regbld tst_sram::SSTAT veri fail] $sm \
-rreg sr.seaddr -edata 0x0004 \
-rreg sr.sedath -edata 0xb1a1 \
-rreg sr.sedatl -edata 0x9181
# init 0x0 --> noop
rlc exec \
-init sr.mdih 0x0000 \
-rreg sr.sstat -edata [regbld tst_sram::SSTAT veri fail] $sm \
-rreg sr.seaddr -edata 0x0004 \
-rreg sr.sedath -edata 0xb1a1 \
-rreg sr.sedatl -edata 0x9181
# init 0x2 --> reset MEM, no effect on SEQ state
rlc exec \
-init sr.mdih 0x0002 \
-rreg sr.sstat -edata [regbld tst_sram::SSTAT veri fail] $sm \
-rreg sr.seaddr -edata 0x0004 \
-rreg sr.sedath -edata 0xb1a1 \
-rreg sr.sedatl -edata 0x9181
# init 0x1 --> reset SEQ, add registers cleared
rlc exec \
-init sr.mdih 0x0001 \
-rreg sr.sstat -edata 0 $sm \
-rreg sr.seaddr -edata 0 \
-rreg sr.sedath -edata 0 \
-rreg sr.sedatl -edata 0
#
#-------------------------------------------------------------------------
rlc log " test 6: xord and xora options"
# list of 4 mem write and 4 read commands
set clist {}
lappend clist { 0 w 1111 0x000440 0xc0b0a090};
lappend clist { 0 w 1111 0x000441 0xc1b1a191};
lappend clist { 0 r 1111 0x000440 0xc0b0a090};
lappend clist { 0 w 1111 0x000442 0xc2b2a292};
lappend clist { 0 r 1111 0x000441 0xc1b1a191};
lappend clist { 0 w 1111 0x000443 0xc3b3a393};
lappend clist { 0 r 1111 0x000442 0xc2b2a292};
lappend clist { 0 r 1111 0x000443 0xc3b3a393};
scmd_write $clist
# run sequencer (xord=1,xora=1,veri=1) and maddr=0 mdi=0
test_seq_setxor 0x00 0x0000 0x0000 0x0000
test_seq_srun [regbld tst_sram::SSTAT xord xora veri] $tout
# read and check mem data (in 440...443, data as in smem)
rlc exec \
-wreg sr.maddrh 0x0000 \
-wreg sr.maddrl 0x0440 \
-rblk sr.mblk 8 -edata {0xc0b0 0xa090 \
0xc1b1 0xa191 \
0xc2b2 0xa292 \
0xc3b3 0xa393}
# start sequencer with xord=1 and mdi=f0f0f0f0
# now 9=1001 <-> 6=0110
# now a=1010 <-> 5=0101
# now b=1011 <-> 4=0100
# now c=1100 <-> 3=0011
test_seq_setxor 0x00 0x0000 0xf0f0 0xf0f0
test_seq_srun [regbld tst_sram::SSTAT xord veri] $tout
# read and check mem data (in 440...443, now xord'ed)
rlc exec \
-wreg sr.maddrh 0x0000 \
-wreg sr.maddrl 0x0440 \
-rblk sr.mblk 8 -edata {0x3040 0x5060 \
0x3141 0x5161 \
0x3242 0x5262 \
0x3343 0x5363}
# start sequencer with xord=1 and mdi=0f0f0f0f
# now 0=0000 -> f=1111
# now 1=0001 -> e=1110
# now 2=0010 -> d=1101
# now 3=0011 -> c=1100
test_seq_setxor 0x00 0x0000 0x0f0f 0x0f0f
test_seq_srun [regbld tst_sram::SSTAT xord veri] $tout
rlc exec \
-wreg sr.maddrh 0x0000 \
-wreg sr.maddrl 0x0440 \
-rblk sr.mblk 8 -edata {0xcfbf 0xaf9f \
0xcebe 0xae9e \
0xcdbd 0xad9d \
0xccbc 0xac9c}
# start sequencer with xora=1 and maddr=1000
test_seq_setxor 0x00 0x1000 0x0000 0x0000
test_seq_srun [regbld tst_sram::SSTAT xora veri] $tout
# read and check mem data (in 1440...1443, data as in smem)
rlc exec \
-wreg sr.maddrh 0x0000 \
-wreg sr.maddrl 0x1440 \
-rblk sr.mblk 8 -edata {0xc0b0 0xa090 \
0xc1b1 0xa191 \
0xc2b2 0xa292 \
0xc3b3 0xa393}
# start sequencer with xord=1,xora=1 and maddr=2000,mdi=f0f0f0f0
test_seq_setxor 0x00 0x2000 0xf0f0 0xf0f0
test_seq_srun [regbld tst_sram::SSTAT xord xora veri] $tout
# read and check mem data (in 2440...2443, data xord'ed)
rlc exec \
-wreg sr.maddrh 0x0000 \
-wreg sr.maddrl 0x2440 \
-rblk sr.mblk 8 -edata {0x3040 0x5060 \
0x3141 0x5161 \
0x3242 0x5262 \
0x3343 0x5363}
# finally check, that sedat hold pure mem data
# list of 4 mem write and 4 read commands
set clist {}
lappend clist { 0 w 1111 0x000550 0xc0b0a090};
lappend clist { 0 w 1111 0x000551 0xc1b1a191};
lappend clist { 0 w 1111 0x000552 0xc2b2a292};
lappend clist { 0 w 1111 0x000553 0xc3b3a393};
lappend clist { 0 r 1111 0x000550 0x00000000}; # add read deta wrong
lappend clist { 0 r 1111 0x000551 0x00000000};
lappend clist { 0 r 1111 0x000552 0x00000000};
lappend clist { 0 r 1111 0x000553 0x00000000};
scmd_write $clist
# start sequencer with xord=1,xora=1 and maddr=4000,mdi=f0f0f0f0
# check that data in sedat is xor'ed !!
test_seq_setxor 0x00 0x4000 0xf0f0 0xf0f0
test_seq_srun [regbld tst_sram::SSTAT xord xora veri] $tout \
4 0x3040 0x5060
# read and check mem data (in 4550...4553, data xord'ed)
rlc exec \
-wreg sr.maddrh 0x0000 \
-wreg sr.maddrl 0x4550 \
-rblk sr.mblk 8 -edata {0x3040 0x5060 \
0x3141 0x5161 \
0x3242 0x5262 \
0x3343 0x5363}
# finally clear veri error
rlc exec -init sr.mdih 0x1; # reset SEQ
#
#-------------------------------------------------------------------------
rlc log " test 7: loop option (with xora)"
# list of 4 mem write and 4 read commands
set clist {}
lappend clist { 0 w 1111 0x000000 0x00102030};
lappend clist { 0 w 1111 0x000001 0x01112131};
lappend clist { 0 r 1111 0x000000 0x00102030};
lappend clist { 0 w 1111 0x000002 0x02122232};
lappend clist { 0 r 1111 0x000001 0x01112131};
lappend clist { 0 w 1111 0x000003 0x03132333};
lappend clist { 0 r 1111 0x000002 0x02122232};
lappend clist { 0 r 1111 0x000003 0x03132333};
scmd_write $clist
# start sequencer with loop=1,xora=1 and maddr=3fff0 (will loop to 3ffff)
test_seq_setxor 0x03 0xfff0 0x0000 0x0000
test_seq_srun [regbld tst_sram::SSTAT loop xora veri] $tout
# check that maddr incremented
rlc exec \
-rreg sr.maddrh -edata 0x0003 \
-rreg sr.maddrl -edata 0xffff
# last iteration will write into
# 00000 xor 03ffff -> 03ffff (00102030)
# 00001 xor 03ffff -> 03fffe (01112131)
# 00002 xor 03ffff -> 03fffd (02122232)
# 00003 xor 03ffff -> 03fffc (03132333)
# read back 4 longwords 03fffc..03ffff
rlc exec \
-wreg sr.maddrh 0x0003 \
-wreg sr.maddrl 0xfffc \
-rblk sr.mblk 8 -edata {0x0313 0x2333 \
0x0212 0x2232 \
0x0111 0x2131 \
0x0010 0x2030}
#
#-------------------------------------------------------------------------
rlc log " test 8: loop option (with xora), verify fail case"
# list of 4 mem write and 4 read commands, 2nd read will fail
set clist {}
lappend clist { 0 w 1111 0x000100 0x00102030};
lappend clist { 0 w 1111 0x000101 0x01112131};
lappend clist { 0 w 1111 0x000102 0x02122232};
lappend clist { 0 w 1111 0x000103 0x03132333};
lappend clist { 0 r 1111 0x000100 0x00102030};
lappend clist { 0 r 1111 0x000101 0x00000000}; # <-- will fail
lappend clist { 0 r 1111 0x000102 0x00000000};
lappend clist { 0 r 1111 0x000103 0x00000000};
scmd_write $clist
# start with loop=1,xora=1 and maddr=03fff0 (tried to loop to 03ffff)
test_seq_setxor 0x03 0xfff0 0x0000 0x0000
test_seq_srun [regbld tst_sram::SSTAT loop xora veri] $tout \
5 0x0111 0x2131
# check that maddr do not increment (fail on first loop !)
rlc exec \
-rreg sr.maddrh -edata 0x0003 \
-rreg sr.maddrl -edata 0xfff0
# finally clear veri error
rlc exec -init sr.mdih 0x1; # reset SEQ
#
#-------------------------------------------------------------------------
rlc log " test 9: wait field in sequencer"
# list of 16 writes and 16 reads, with increasing waits
set clist {}
lappend clist { 0x0 w 1111 0x000110 0x20001000}; # writes
lappend clist { 0x1 w 1111 0x000111 0x20011001};
lappend clist { 0x2 w 1111 0x000112 0x20021002};
lappend clist { 0x3 w 1111 0x000113 0x20031003};
lappend clist { 0x4 w 1111 0x000114 0x20041004};
lappend clist { 0x5 w 1111 0x000115 0x20051005};
lappend clist { 0x6 w 1111 0x000116 0x20061006};
lappend clist { 0x7 w 1111 0x000117 0x20071007};
lappend clist { 0x8 w 1111 0x000118 0x20081008};
lappend clist { 0x9 w 1111 0x000119 0x20091009};
lappend clist { 0xa w 1111 0x00011a 0x200a100a};
lappend clist { 0xb w 1111 0x00011b 0x200b100b};
lappend clist { 0xc w 1111 0x00011c 0x200c100c};
lappend clist { 0xd w 1111 0x00011d 0x200d100d};
lappend clist { 0xe w 1111 0x00011e 0x200e100e};
lappend clist { 0xf w 1111 0x00011f 0x200f100f};
lappend clist { 0x0 r 1111 0x000110 0x20001000}; # read
lappend clist { 0x1 r 1111 0x000111 0x20011001};
lappend clist { 0x2 r 1111 0x000112 0x20021002};
lappend clist { 0x3 r 1111 0x000113 0x20031003};
lappend clist { 0x4 r 1111 0x000114 0x20041004};
lappend clist { 0x5 r 1111 0x000115 0x20051005};
lappend clist { 0x6 r 1111 0x000116 0x20061006};
lappend clist { 0x7 r 1111 0x000117 0x20071007};
lappend clist { 0x8 r 1111 0x000118 0x20081008};
lappend clist { 0x9 r 1111 0x000119 0x20091009};
lappend clist { 0xa r 1111 0x00011a 0x200a100a};
lappend clist { 0xb r 1111 0x00011b 0x200b100b};
lappend clist { 0xc r 1111 0x00011c 0x200c100c};
lappend clist { 0xd r 1111 0x00011d 0x200d100d};
lappend clist { 0xe r 1111 0x00011e 0x200e100e};
lappend clist { 0xf r 1111 0x00011f 0x200f100f};
scmd_write $clist
# start sequencer with xora=1 and maddr=11000
test_seq_setxor 0x01 0x1000 0x0000 0x0000
test_seq_srun [regbld tst_sram::SSTAT xora veri] $tout
# list of groups of 2 write / 2 read, with increasing wait
set clist {}
lappend clist { 0x0 w 1111 0x000120 0x30002000}; # write
lappend clist { 0x0 w 1111 0x000121 0x30012001};
lappend clist { 0x0 r 1111 0x000120 0x30002000}; # read
lappend clist { 0x0 r 1111 0x000121 0x30012001};
lappend clist { 0x1 w 1111 0x000122 0x30022002}; # write
lappend clist { 0x1 w 1111 0x000123 0x30032003};
lappend clist { 0x1 r 1111 0x000122 0x30022002}; # read
lappend clist { 0x1 r 1111 0x000123 0x30032003};
lappend clist { 0x2 w 1111 0x000124 0x30042004}; # write
lappend clist { 0x2 w 1111 0x000125 0x30052005};
lappend clist { 0x2 r 1111 0x000124 0x30042004}; # read
lappend clist { 0x2 r 1111 0x000125 0x30052005};
lappend clist { 0x3 w 1111 0x000126 0x30062006}; # write
lappend clist { 0x3 w 1111 0x000127 0x30072007};
lappend clist { 0x3 r 1111 0x000126 0x30062006}; # read
lappend clist { 0x3 r 1111 0x000127 0x30072007};
lappend clist { 0x4 w 1111 0x000128 0x30082008}; # write
lappend clist { 0x4 w 1111 0x000129 0x30092009};
lappend clist { 0x4 r 1111 0x000128 0x30082008}; # read
lappend clist { 0x4 r 1111 0x000129 0x30092009};
lappend clist { 0x5 w 1111 0x00012a 0x300a200a}; # write
lappend clist { 0x5 w 1111 0x00012b 0x300b200b};
lappend clist { 0x5 r 1111 0x00012a 0x300a200a}; # read
lappend clist { 0x5 r 1111 0x00012b 0x300b200b};
lappend clist { 0x6 w 1111 0x00012c 0x300c200c}; # write
lappend clist { 0x6 w 1111 0x00012d 0x300d200d};
lappend clist { 0x6 r 1111 0x00012c 0x300c200c}; # read
lappend clist { 0x6 r 1111 0x00012d 0x300d200d};
lappend clist { 0x7 w 1111 0x00012e 0x300e200e}; # write
lappend clist { 0x7 w 1111 0x00012f 0x300f200f};
lappend clist { 0x7 r 1111 0x00012e 0x300e200e}; # read
lappend clist { 0x7 r 1111 0x00012f 0x300f200f};
scmd_write $clist
# start sequencer with xora=1 and maddr=22000
test_seq_setxor 0x02 0x2000 0x0000 0x0000
test_seq_srun [regbld tst_sram::SSTAT xora veri] $tout
#
#-------------------------------------------------------------------------
if {[iswide]} {
rlc log " test 10: wswap option"
# write with sequencer
# list of writes, top 2 bits of seq address change; do read back
set clist {}
lappend clist { 0x0 w 1111 0x000000 0x12340000}; # -> 0x001000
lappend clist { 0x0 w 1111 0x010011 0x12340011}; # -> 0x101011
lappend clist { 0x0 w 1111 0x020022 0x12340022}; # -> 0x201022
lappend clist { 0x0 w 1111 0x030033 0x12340033}; # -> 0x301033
lappend clist { 0x0 r 1111 0x000000 0x12340000}; # <- 0x001000
lappend clist { 0x0 r 1111 0x010011 0x12340011}; # <- 0x101011
lappend clist { 0x0 r 1111 0x020022 0x12340022}; # <- 0x201022
lappend clist { 0x0 r 1111 0x030033 0x12340033}; # <- 0x301033
scmd_write $clist
# start sequencer with xora=1 and maddr=001000
test_seq_setxor 0x00 0x1000 0x0000 0x0000
test_seq_srun [regbld tst_sram::SSTAT wswap xora veri] $tout
# check memory via mcmd reads
rlc exec \
-wreg sr.maddrl 0x1000 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld {be 0xf} {addrh 0x00}] \
-rreg sr.mdoh -edata 0x1234 \
-rreg sr.mdol -edata 0x0000 \
-wreg sr.maddrl 0x1011 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld {be 0xf} {addrh 0x10}] \
-rreg sr.mdoh -edata 0x1234 \
-rreg sr.mdol -edata 0x0011 \
-wreg sr.maddrl 0x1022 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld {be 0xf} {addrh 0x20}] \
-rreg sr.mdoh -edata 0x1234 \
-rreg sr.mdol -edata 0x0022 \
-wreg sr.maddrl 0x1033 \
-wreg sr.mcmd [regbld tst_sram::MCMD ld {be 0xf} {addrh 0x30}] \
-rreg sr.mdoh -edata 0x1234 \
-rreg sr.mdol -edata 0x0033
}
#
#-------------------------------------------------------------------------
if {[iswide]} {
rlc log " test 11: wloop option"
# like test previous test 7, but now using wloop
# list of 4 mem write and 4 read commands
set clist {}
lappend clist { 0 w 1111 0x000000 0x00102030};
lappend clist { 0 w 1111 0x000001 0x01112131};
lappend clist { 0 r 1111 0x000000 0x00102030};
lappend clist { 0 w 1111 0x000002 0x02122232};
lappend clist { 0 r 1111 0x000001 0x01112131};
lappend clist { 0 w 1111 0x000003 0x03132333};
lappend clist { 0 r 1111 0x000002 0x02122232};
lappend clist { 0 r 1111 0x000003 0x03132333};
scmd_write $clist
# start with wloop=1,loop=1,xora=1 and maddr=3ffff0 (will loop to 3fffff)
test_seq_setxor 0x3f 0xfff0 0x0000 0x0000
test_seq_srun [regbld tst_sram::SSTAT wloop loop xora veri] $tout
# check that maddr incremented
rlc exec \
-rreg sr.maddrh -edata 0x003f \
-rreg sr.maddrl -edata 0xffff
# last iteration will write into
# 00000 xor 3fffff -> 3fffff (00102030)
# 00001 xor 3fffff -> 3ffffe (01112131)
# 00002 xor 3fffff -> 3ffffd (02122232)
# 00003 xor 3fffff -> 3ffffc (03132333)
# read back 4 longwords 3ffffc..3fffff
rlc exec \
-wreg sr.maddrh 0x003f \
-wreg sr.maddrl 0xfffc \
-rblk sr.mblk 8 -edata {0x0313 0x2333 \
0x0212 0x2232 \
0x0111 0x2131 \
0x0010 0x2030}
}
#
#-------------------------------------------------------------------------
incr errcnt [rlc errcnt -clear]
return $errcnt
}
}

244
tools/tcl/tst_sram/util.tcl Normal file
View File

@@ -0,0 +1,244 @@
# $Id: util.tcl 785 2016-07-10 12:22:41Z mueller $
#
# Copyright 2011-2016 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 2, 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
# 2016-07-09 784 1.2 22bit support: mask sstat(wide); add iswide
# 2015-04-03 661 1.1 drop estatdef (stat err check default now)
# 2014-08-14 582 1.0.1 add srun* procs; add nscmd and tout variables
# 2014-08-10 581 1.0 Initial version
# 2011-07-03 387 0.1 Frist draft
#
package provide tst_sram 1.0
package require rutiltpp
package require rutil
package require rlink
namespace eval tst_sram {
# name space variables
#
variable nscmd 0; # length of current sequencer command list
variable tout 10.; # default time out
variable iswide -1; # sstat.wide cache
#
# setup register descriptions for tst_sram core design ---------------------
#
regdsc MCMD {ld 14} {inc 13} {we 12} {be 11 4} {addrh 5 6}
regdsc SSTAT {wide 15} {wswap 9} {wloop 8} \
{loop 7} {xord 6} {xora 5} {veri 4} {fail 1} {run 0}
regdsc SCMD {wait 31 4} {we 24} {be 23 4} {addr 17 18}
#
# setup: amap definitions for tst_sram core design -------------------------
#
proc setup {{base 0x0000}} {
rlc amap -insert sr.mdih [expr {$base + 0x00}]
rlc amap -insert sr.mdil [expr {$base + 0x01}]
rlc amap -insert sr.mdoh [expr {$base + 0x02}]
rlc amap -insert sr.mdol [expr {$base + 0x03}]
rlc amap -insert sr.maddrh [expr {$base + 0x04}]
rlc amap -insert sr.maddrl [expr {$base + 0x05}]
rlc amap -insert sr.mcmd [expr {$base + 0x06}]
rlc amap -insert sr.mblk [expr {$base + 0x07}]
rlc amap -insert sr.slim [expr {$base + 0x08}]
rlc amap -insert sr.saddr [expr {$base + 0x09}]
rlc amap -insert sr.sblk [expr {$base + 0x0a}]
rlc amap -insert sr.sblkc [expr {$base + 0x0b}]
rlc amap -insert sr.sblkd [expr {$base + 0x0c}]
rlc amap -insert sr.sstat [expr {$base + 0x0d}]
rlc amap -insert sr.sstart [expr {$base + 0x0e}]
rlc amap -insert sr.sstop [expr {$base + 0x0f}]
rlc amap -insert sr.seaddr [expr {$base + 0x10}]
rlc amap -insert sr.sedath [expr {$base + 0x11}]
rlc amap -insert sr.sedatl [expr {$base + 0x12}]
}
#
# init: reset tst_sram -----------------------------------------------------
#
proc init {} {
rlc exec \
-wreg sr.sstop 1 \
-wreg sr.sstat 0
}
#
# iswide: 1 if 22bit system ------------------------------------------------
#
proc iswide {} {
variable iswide
if {$iswide < 0} {
rlc exec -rreg sr.sstat sstat
set iswide [regget tst_sram::SSTAT(wide) $sstat]
}
return $iswide
}
#
# scmd_write: write a scmd list --------------------------------------------
#
proc scmd_write {scmdlist} {
variable nscmd
set buf {}
set nscmd 0
rlc exec -wreg sr.saddr 0
foreach scmditem $scmdlist {
set wait [lindex $scmditem 0]
set wec [lindex $scmditem 1]
set bec [lindex $scmditem 2]
set addr [lindex $scmditem 3]
set mval [lindex $scmditem 4]
set we [expr {($wec eq "w") ? 1 : 0}]
set scmd [regbld tst_sram::SCMD \
[list wait $wait] \
[list we $we] \
[list be [bvi b $bec]] \
[list addr $addr] ]
set scmdh [expr {($scmd>>16) & 0xffff}]
set scmdl [expr { $scmd & 0xffff}]
set mvalh [expr {($mval>>16) & 0xffff}]
set mvall [expr { $mval & 0xffff}]
lappend buf $scmdh $scmdl $mvalh $mvall
if {[llength $buf] == 256} {
rlc exec -wblk sr.sblk $buf
set buf {}
}
incr nscmd
}
if {[llength $buf] > 0} {
rlc exec -wblk sr.sblk $buf
}
return ""
}
#
# scmd_read: read a scmd list ---------------------------------------------
#
proc scmd_read {length} {
set scmdlist {}
if {$length == 0} {return $scmdlist}
rlc exec -rreg sr.saddr saddr_save \
-wreg sr.saddr 0
while {$length > 0} {
set chunk $length
if {$chunk > 64} {set chunk 64}
set length [expr {$length - $chunk}]
rlc exec -rblk sr.sblk [expr {4*$chunk}] buf
foreach {scmdh scmdl mvalh mvall} $buf {
set scmd [expr {($scmdh<<16) | $scmdl}]
set mval [expr {($mvalh<<16) | $mvall}]
set wait [regget tst_sram::SCMD(wait) $scmd]
set we [regget tst_sram::SCMD(we) $scmd]
set be [regget tst_sram::SCMD(be) $scmd]
set addr [regget tst_sram::SCMD(addr) $scmd]
set wec [expr {($we) ? "w" : "r"}]
set bec [pbvi b4 $be]
lappend scmdlist [list $wait $wec $bec $addr $mval]
}
}
rlc exec -wreg sr.saddr $saddr_save
return $scmdlist
}
#
# scmd_print: print a scmd list -------------------------------------------
#
proc scmd_print {scmdlist} {
set rval " ind: dly we be addr mval"
set ind 0
foreach scmditem $scmdlist {
set wait [lindex $scmditem 0]
set wec [lindex $scmditem 1]
set bec [lindex $scmditem 2]
set addr [lindex $scmditem 3]
set mval [lindex $scmditem 4]
append rval "\n"
append rval [format "%4d: %2d %s %s 0x%6.6x 0x%8.8x" \
$ind $wait $wec $bec $addr $mval]
incr ind
}
return $rval
}
#
# srun: single pass run of sequencer ---------------------------------------
#
proc srun {mdih mdil maddrh maddrl {tout 0.}} {
variable nscmd
if {$tout == 0} {set tout $tst_sram::tout}
if {$nscmd == 0} {error "no or empty scmd list loaded"}
set sm [rutil::com16 [regbld tst_sram::SSTAT wide]]
rlc exec -init 0 1
rlc exec -wreg sr.sstat [regbld tst_sram::SSTAT xord xora veri] \
-wreg sr.mdih $mdih \
-wreg sr.mdil $mdil \
-wreg sr.maddrh $maddrh \
-wreg sr.maddrl $maddrl \
-wreg sr.slim [expr {$nscmd-1}] \
-wreg sr.sstart 0x0000
rlc wtlam $tout
rlc exec -attn -edata 0x0001
rlc exec -rreg sr.sstat -edata [regbld tst_sram::SSTAT xord xora veri] $sm \
-rreg sr.seaddr -edata 0x0000 \
-rreg sr.sedath -edata 0x0000 \
-rreg sr.sedatl -edata 0x0000
return ""
}
#
# srun_lists: call srun for mdi and maddr lists ----------------------------
#
proc srun_lists {lmdi lmaddr {tout 0.}} {
foreach {maddrh maddrl} $lmaddr {
foreach {mdih mdil} $lmdi {
srun $mdih $mdil $maddrh $maddrl $tout
}
}
return ""
}
#
# srun_loop: full maddr* loop of sequencer ---------------------------------
#
proc srun_loop {mdih mdil maddrh maddrl {wide 0} {tout 0.}} {
variable nscmd
if {$tout == 0} {set tout $tst_sram::tout}
if {$nscmd == 0} {error "no or empty scmd list loaded"}
set sm [rutil::com16 [regbld tst_sram::SSTAT wide]]
set sstat [regbldkv tst_sram::SSTAT wswap $wide wloop $wide loop 1 \
xord 1 xora 1 veri 1]
rlc exec -init 0 1
rlc exec -wreg sr.sstat $sstat \
-wreg sr.mdih $mdih \
-wreg sr.mdil $mdil \
-wreg sr.maddrh $maddrh \
-wreg sr.maddrl $maddrl \
-wreg sr.slim [expr {$nscmd-1}] \
-wreg sr.sstart 0x0000
set tbeg [clock milliseconds]
rlc wtlam $tout
set tend [clock milliseconds]
rlc exec -attn -edata 0x0001
rlc exec -rreg sr.sstat -edata $sstat $sm \
-rreg sr.seaddr -edata 0x0000 \
-rreg sr.sedath -edata 0x0000 \
-rreg sr.sedatl -edata 0x0000
set trun [expr {($tend-$tbeg)/1000.}]
set line [format "loop done maddr=%2.2x %4.4x mdi=%4.4x %4.4x in %7.2f s" \
$maddrh $maddrl $mdih $mdil $trun]
rlc log $line
return ""
}
}

View File

@@ -0,0 +1,12 @@
# $Id: viv_default_build.tcl 792 2016-07-23 18:05:40Z mueller $
#
# Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Version Comment
# 2015-02-14 646 1.0 Initial version
# 2015-01-25 637 0.1 First draft
#
rvtb_default_build [lindex $::argv 0] [lindex $::argv 1]

View File

@@ -0,0 +1,12 @@
# $Id: viv_default_config.tcl 792 2016-07-23 18:05:40Z mueller $
#
# Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Version Comment
# 2015-02-14 646 1.0 Initial version
# 2015-01-25 637 0.1 First draft
#
rvtb_default_config [lindex $::argv 0]

View File

@@ -0,0 +1,11 @@
# $Id: viv_default_model.tcl 792 2016-07-23 18:05:40Z mueller $
#
# Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Version Comment
# 2015-02-14 646 1.0 Initial version
#
rvtb_default_model [lindex $::argv 0] [lindex $::argv 1]

14
tools/vivado/viv_init.tcl Normal file
View File

@@ -0,0 +1,14 @@
# $Id: viv_init.tcl 792 2016-07-23 18:05:40Z mueller $
#
# Copyright 2015-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Version Comment
# 2016-07-22 792 1.1 relocate viv tcl code to tools/vivado
# 2015-02-14 646 1.0 Initial version
# 2015-01-25 637 0.1 First draft
#
source -notrace "$::env(RETROBASE)/tools/vivado/viv_tools_build.tcl"
source -notrace "$::env(RETROBASE)/tools/vivado/viv_tools_config.tcl"
source -notrace "$::env(RETROBASE)/tools/vivado/viv_tools_model.tcl"

View File

@@ -0,0 +1,305 @@
# $Id: viv_tools_build.tcl 809 2016-09-18 19:49:14Z mueller $
#
# Copyright 2015-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Version Comment
# 2016-09-18 809 1.2.1 keep hierarchy for synthesis only runs
# 2016-05-22 767 1.2 cleaner setup handling; use explore flows
# add 2016.1 specific setups
# 2016-04-02 758 1.1.5 remove USR_ACCESS setup, must be done in xdc
# 2016-03-26 752 1.1.4 more steps supported: prj,opt,pla
# 2016-03-25 751 1.1.3 suppress some messages
# 2016-03-19 748 1.1.2 set bitstream USR_ACCESS to TIMESTAMP
# 2016-02-28 738 1.1.1 add 2015.4 specific setups
# 2015-02-21 649 1.1 add 2014.4 specific setups
# 2015-02-14 646 1.0 Initial version
#
#
# --------------------------------------------------------------------
#
proc rvtb_trace_cmd {cmd} {
puts "# $cmd"
eval $cmd
return ""
}
#
# --------------------------------------------------------------------
#
proc rvtb_locate_setup_file {stem} {
set name "${stem}_setup.tcl"
if {[file readable $name]} {return $name}
set name "$../{stem}_setup.tcl"
if {[file readable $name]} {return $name}
return ""
}
#
# --------------------------------------------------------------------
#
proc rvtb_mv_file {src dst} {
if {[file readable $src]} {
exec mv $src $dst
} else {
puts "rvtb_mv_file-W: file '$src' not existing"
}
return ""
}
#
# --------------------------------------------------------------------
#
proc rvtb_rm_file {src} {
exec rm -f $src
}
#
# --------------------------------------------------------------------
#
proc rvtb_cp_file {src dst} {
if {[file readable $src]} {
exec cp -p $src $dst
} else {
puts "rvtb_cp_file-W: file '$src' not existing"
}
return ""
}
#
# --------------------------------------------------------------------
#
proc rvtb_build_check {step} {
return ""
}
#
# --------------------------------------------------------------------
#
proc rvtb_version_is {val} {
set vers [version -short]
return [expr {$vers eq $val}]
}
#
# --------------------------------------------------------------------
#
proc rvtb_version_min {val} {
set vers [version -short]
return [expr {[string compare $vers $val] >= 0}]
}
#
# --------------------------------------------------------------------
#
proc rvtb_version_max {val} {
set vers [version -short]
return [expr {[string compare $vers $val] <= 0}]
}
#
# --------------------------------------------------------------------
#
proc rvtb_version_in {min max} {
set vers [version -short]
return [expr {[string compare $vers $min] >= 0 && \
[string compare $vers $max] <= 0}]
}
#
# --------------------------------------------------------------------
#
proc rvtb_default_build {stem step} {
# supported step values
# prj setup project
# syn run synthesis
# opt run synthesis + implementation up to step opt_design
# pla run synthesis + implementation up to step place_design
# imp run synthesis + implementation (but not bit file generation)
# bit Synthesize + Implement + generate bit file
if {![regexp -- {^(prj|syn|opt|pla|imp|bit)$} $step]} {
error "bad step name $step"
}
# general setups (prior to project creation) ------------------
# version dependent setups
if {[rvtb_version_is "2014.4"]} {
# suppress nonsense "cannot add Board Part xilinx.com:kc705..." messages
# set here to avoid messages during create_project
set_msg_config -suppress -id {Board 49-26}
}
# read setup
set setup_file [rvtb_locate_setup_file $stem]
if {$setup_file ne ""} {source -notrace $setup_file}
# Create project ----------------------------------------------
rvtb_trace_cmd "create_project project_mflow ./project_mflow"
# Setup project properties -------------------------------
set obj [get_projects project_mflow]
set_property "default_lib" "xil_defaultlib" $obj
set_property "part" $::rvtb_part $obj
set_property "simulator_language" "Mixed" $obj
set_property "target_language" "VHDL" $obj
# general setups -----------------------------------------
# suppress message which don't convey useful information
set_msg_config -suppress -id {DRC 23-20}; # DSP48 output pilelining
set_msg_config -suppress -id {Project 1-120}; # WebTalk mandatory
set_msg_config -suppress -id {Common 17-186}; # WebTalk info send
# Setup list of extra synthesis options (for later rodinMoreOptions)
set synth_more_opts {}
# version independent setups -----------------------------
# setup synthesis strategy and options --------------
set_property strategy Flow_PerfOptimized_high [get_runs synth_1]
# for synthesis only: keep hierarchy for easier debug
if {$step eq "syn"} {
set_property STEPS.SYNTH_DESIGN.ARGS.FLATTEN_HIERARCHY none \
[get_runs synth_1]
}
# FSM recognition threshold (default is 5)
# see http://www.xilinx.com/support/answers/58574.html
lappend synth_more_opts {rt::set_parameter minFsmStates 3}
# setup implementation strategy and options ---------
set_property strategy Performance_Explore [get_runs impl_1]
# version dependent setups -------------------------------
if {[rvtb_version_is "2014.4"]} {
# suppress nonsense "cannot add Board Part xilinx.com:kc705..." messages
# repeated here because create_project apparently clears msg_config
set_msg_config -suppress -id {Board 49-26}
}
if {[rvtb_version_is "2015.4"]} {
# enable vhdl asserts, see http://www.xilinx.com/support/answers/65415.html
lappend synth_more_opts {rt::set_parameter ignoreVhdlAssertStmts false}
}
if {[rvtb_version_min "2016.1"]} {
# enable vhdl asserts via global option (after 2016.1)
set_property STEPS.SYNTH_DESIGN.ARGS.ASSERT true [get_runs synth_1]
}
# now setup extra synthesis options
# see http://www.xilinx.com/support/answers/58248.html
# -> since used via 'set_param' it's a parameter
# -> only last definition counts
# -> use ';' separated list
# -> these options are **NOT** preserved in project file !!
if {[llength $synth_more_opts]} {
puts "# extra synthesis options:"
foreach opt $synth_more_opts { puts "# $opt"}
set_param synth.elaboration.rodinMoreOptions [join $synth_more_opts "; "]
}
# Setup filesets
set vbom_prj [exec vbomconv -vsyn_prj "${stem}.vbom"]
eval $vbom_prj
update_compile_order -fileset sources_1
if {$step eq "prj"} {
puts "rvtb_default_build-I: new project setup for ${stem}"
return ""
}
# some handy variables
set path_runs "project_mflow/project_mflow.runs"
set path_syn1 "${path_runs}/synth_1"
set path_imp1 "${path_runs}/impl_1"
# build: synthesize ------------------------------------------------
puts "# current rodinMoreOptions:"
puts [get_param synth.elaboration.rodinMoreOptions]
rvtb_trace_cmd "launch_runs synth_1"
rvtb_trace_cmd "wait_on_run synth_1"
rvtb_mv_file "$path_syn1/runme.log" "${stem}_syn.log"
rvtb_cp_file "$path_syn1/${stem}_utilization_synth.rpt" "${stem}_syn_util.rpt"
rvtb_cp_file "$path_syn1/${stem}.dcp" "${stem}_syn.dcp"
if {$step eq "syn"} {return [rvtb_build_check $step]}
# build: implement -------------------------------------------------
set launch_opt ""
if {$step eq "opt"} {set launch_opt "-to_step opt_design"}
if {$step eq "pla"} {set launch_opt "-to_step place_design"}
rvtb_trace_cmd "launch_runs ${launch_opt} impl_1"
rvtb_trace_cmd "wait_on_run impl_1"
rvtb_cp_file "$path_imp1/runme.log" "${stem}_imp.log"
rvtb_cp_file "$path_imp1/${stem}_opt.dcp" "${stem}_opt.dcp"
rvtb_cp_file "$path_imp1/${stem}_drc_opted.rpt" "${stem}_opt_drc.rpt"
if {$step eq "opt"} {
rvtb_trace_cmd "open_checkpoint $path_imp1/${stem}_opt.dcp"
report_utilization -file "${stem}_opt_util.rpt"
report_utilization -hierarchical -file "${stem}_opt_util_h.rpt"
return [rvtb_build_check $step]
}
rvtb_cp_file "$path_imp1/${stem}_placed.dcp" "${stem}_pla.dcp"
rvtb_cp_file "$path_imp1/${stem}_io_placed.rpt" "${stem}_pla_io.rpt"
rvtb_cp_file "$path_imp1/${stem}_utilization_placed.rpt" \
"${stem}_pla_util.rpt"
rvtb_cp_file "$path_imp1/${stem}_control_sets_placed.rpt" \
"${stem}_pla_clk_set.rpt"
if {$step eq "pla"} {
return [rvtb_build_check $step]
}
rvtb_cp_file "$path_imp1/${stem}_routed.dcp" "${stem}_rou.dcp"
rvtb_cp_file "$path_imp1/${stem}_route_status.rpt" "${stem}_rou_sta.rpt"
rvtb_cp_file "$path_imp1/${stem}_drc_routed.rpt" "${stem}_rou_drc.rpt"
rvtb_cp_file "$path_imp1/${stem}_timing_summary_routed.rpt" \
"${stem}_rou_tim.rpt"
rvtb_cp_file "$path_imp1/${stem}_power_routed.rpt" "${stem}_rou_pwr.rpt"
rvtb_cp_file "$path_imp1/${stem}_clock_utilization_routed.rpt" \
"${stem}_rou_clk_util.rpt"
# additional reports
rvtb_trace_cmd "open_run impl_1"
report_utilization -file "${stem}_rou_util.rpt"
report_utilization -hierarchical -file "${stem}_rou_util_h.rpt"
report_datasheet -file "${stem}_rou_ds.rpt"
report_cdc -file "${stem}_rou_cdc.rpt"
report_clock_interaction -delay_type min_max -significant_digits 3 \
-file "${stem}_rou_clk_int.rpt"
if {[get_property SSN_REPORT [get_property PART [current_project]]]} {
report_ssn -format TXT -file "${stem}_rou_ssn.rpt"
}
if {$step eq "imp"} {return [rvtb_build_check $step]}
# build: bitstream -------------------------------------------------
# check for critical warnings, e.g.
# [Timing 38-282] The design failed to meet the timing requirements.
# in that case abort build
rvtb_rm_file "./${stem}.bit"
if {[get_msg_config -severity {critical warning} -count]} {
puts "rvtb_default_build-E: abort due to critical warnings seen before"
puts "rvtb_default_build-E: no bitfile generated"
return [rvtb_build_check $step]
}
rvtb_trace_cmd "launch_runs impl_1 -to_step write_bitstream"
rvtb_trace_cmd "wait_on_run impl_1"
rvtb_mv_file "$path_imp1/runme.log" "${stem}_bit.log"
rvtb_mv_file "$path_imp1/${stem}.bit" "."
return [rvtb_build_check $step]
}

View File

@@ -0,0 +1,51 @@
# $Id: viv_tools_config.tcl 792 2016-07-23 18:05:40Z mueller $
#
# Copyright 2015-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Version Comment
# 2016-04-02 758 1.1 add USR_ACCESS readback
# 2015-02-14 646 1.0 Initial version
#
#
# --------------------------------------------------------------------
#
proc rvtb_format_usracc {usracc} {
set sec [expr { ($usracc >> 0) & 0x3f } ]; # 6 bit 05:00
set min [expr { ($usracc >> 6) & 0x3f } ]; # 6 bit 11:06
set hr [expr { ($usracc >> 12) & 0x1f } ]; # 5 bit 16:12
set yr [expr {(($usracc >> 17) & 0x3f)+2000} ]; # 6 bit 22:17
set mo [expr { ($usracc >> 23) & 0x0f } ]; # 4 bit 26:23
set day [expr { ($usracc >> 27) & 0x1f } ]; # 5 bit 31:27
return [format "%04d-%02d-%02d %02d:%02d:%02d" $yr $mo $day $hr $min $sec]
}
#
# --------------------------------------------------------------------
#
proc rvtb_default_config {stem} {
# open and connect to hardware server
open_hw
connect_hw_server
# connect to target
open_hw_target [lindex [get_hw_targets -of_objects [get_hw_servers localhost]] 0]
# setup bitfile
set_property PROGRAM.FILE "${stem}.bit" [lindex [get_hw_devices] 0]
# and configure FPGA
program_hw_devices [lindex [get_hw_devices] 0]
# and check USR_ACCESS setting
set usracc_raw [get_property REGISTER.USR_ACCESS [lindex [get_hw_devices] 0] ]
set usracc_num "0x$usracc_raw"
set usracc_fmt [rvtb_format_usracc $usracc_num]
puts ""
puts "USR_ACCESS: 0x$usracc_raw $usracc_fmt"
puts ""
return "";
}

View File

@@ -0,0 +1,59 @@
# $Id: viv_tools_model.tcl 792 2016-07-23 18:05:40Z mueller $
#
# Copyright 2015-2016 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# License disclaimer see LICENSE_gpl_v2.txt in $RETROBASE directory
#
# Revision History:
# Date Rev Version Comment
# 2016-06-24 778 1.1 support mode [sor]sim_vhdl [sorepd]sim_veri
# 2016-06-19 777 1.0.1 use full absolute path name for sdf annotate
# 2015-02-14 646 1.0 Initial version
#
# --------------------------------------------------------------------
# supported modes
# base ----- func ----- timing
# vhdl veri veri
# post synth _syn.dcp ssim_vhd ssim_v esim_v
# post phys_opt _opt.dcp osim_vhd osim_v psim_v
# post route _rou.dcp rsim_vhd rsim_v tsim_v
#
proc rvtb_default_model {stem mode} {
if {[regexp -- {^([sor])sim_(vhd|v)$} $mode matched type lang] ||
[regexp -- {^([ept])sim_(v)$} $mode matched type lang]} {
switch $type {
s -
e {open_checkpoint "${stem}_syn.dcp"}
o -
p {open_checkpoint "${stem}_opt.dcp"}
r -
t {open_checkpoint "${stem}_rou.dcp"}
}
if {$lang eq "vhd"} {
write_vhdl -mode funcsim -force "${stem}_${type}sim.vhd"
} else {
if {$type eq "s" || $type eq "o" || $type eq "r"} {
write_verilog -mode funcsim -force "${stem}_${type}sim.v"
} else {
# use full absolute path name for sdf annotate
# reason: the _tsim.v is sometimes generated in system path and
# used from the tb path. xelab doesn't find the sdf in that case
# Solution are absolute path (ugly) or symlink (ugly, who does setup..)
write_verilog -mode timesim -force \
-sdf_anno true \
-sdf_file "[pwd]/${stem}_${type}sim.sdf" \
"${stem}_${type}sim.v"
write_sdf -mode timesim -force \
-process_corner slow \
"${stem}_${type}sim.sdf"
}
}
} else {
error "rvtb_default_model-E: bad mode: $mode";
}
return "";
}