mirror of
https://github.com/wfjm/w11.git
synced 2026-02-25 08:40:05 +00:00
266 lines
8.9 KiB
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
|
|
}
|
|
}
|
|
|