1
0
mirror of https://github.com/wfjm/w11.git synced 2026-02-25 08:40:05 +00:00
Files
wfjm.w11/tools/tcl/tst_sram/util.tcl

266 lines
8.9 KiB
Tcl

# $Id: util.tcl 985 2018-01-03 08:59:40Z mueller $
#
# Copyright 2011-2017 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
#
# This program is free software; you may redistribute and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for complete details.
#
# Revision History:
# Date Rev Version Comment
# 2017-06-19 914 1.3 17bit support; use sstat(awidth); add isnarrow
# 2017-04-22 883 1.2.1 setup: now idempotent
# 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.awidth=22 cache
variable isnarrow -1; # sstat.awidth=17 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 {awidth 15 3} {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}} {
if {[rlc amap -testname sr.mdih $base]} {return}
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
}
#
# checkawidth: inspect SSTAT(awidth) ---------------------------------------
#
proc checkawidth {} {
variable iswide
variable isnarrow
rlc exec -rreg sr.sstat sstat
set awidth [regget tst_sram::SSTAT(awidth) $sstat]
set iswide [expr {$awidth + 16 == 22}]
set isnarrow [expr {$awidth + 16 == 17}]
return ""
}
#
# iswide: 1 if 22bit system ------------------------------------------------
#
proc iswide {} {
variable iswide
if {$iswide < 0} { checkawidth }
return $iswide
}
#
# isnarrow: 1 if 17bit system ----------------------------------------------
#
proc isnarrow {} {
variable isnarrow
if {$isnarrow < 0} { checkawidth }
return $isnarrow
}
#
# 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 {awidth -1}]]
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 {awidth -1}]]
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
}
}