OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.61/] [tools/] [tcl/] [rutil/] [util.tcl] - Diff between revs 25 and 26

Only display areas with differences | Details | Blame | View Log

Rev 25 Rev 26
# $Id: util.tcl 569 2014-07-13 14:36:32Z mueller $
# $Id: util.tcl 569 2014-07-13 14:36:32Z mueller $
#
#
# Copyright 2011-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
# Copyright 2011-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
# 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
# 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.
# 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
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
# WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for complete details.
# for complete details.
#
#
#  Revision History:
#  Revision History:
# Date         Rev Version  Comment
# Date         Rev Version  Comment
# 2014-07-12   569   1.0.2  add sxt16 and sxt32
# 2014-07-12   569   1.0.2  add sxt16 and sxt32
# 2013-05-09   517   1.0.1  add optlist2arr
# 2013-05-09   517   1.0.1  add optlist2arr
# 2011-03-27   374   1.0    Initial version
# 2011-03-27   374   1.0    Initial version
# 2011-03-19   372   0.1    First draft
# 2011-03-19   372   0.1    First draft
#
#
 
 
package provide rutil 1.0
package provide rutil 1.0
 
 
package require rutiltpp
package require rutiltpp
 
 
namespace eval rutil {
namespace eval rutil {
  #
  #
  # optlist2arr: process options arguments given as key value list -----------
  # optlist2arr: process options arguments given as key value list -----------
  #
  #
  proc optlist2arr {outarrname refarrname optlist} {
  proc optlist2arr {outarrname refarrname optlist} {
    upvar $outarrname outarr
    upvar $outarrname outarr
    upvar $refarrname refarr
    upvar $refarrname refarr
    array set outarr [array get refarr]
    array set outarr [array get refarr]
    foreach {key value} $optlist {
    foreach {key value} $optlist {
      if {[info exists outarr($key)]} {
      if {[info exists outarr($key)]} {
        set outarr($key) $value
        set outarr($key) $value
      } else {
      } else {
        error "key $key not valid in optlist"
        error "key $key not valid in optlist"
      }
      }
    }
    }
    return ""
    return ""
  }
  }
 
 
  #
  #
  # regdsc: setup a register descriptor --------------------------------------
  # regdsc: setup a register descriptor --------------------------------------
  #
  #
  proc regdsc {name args} {
  proc regdsc {name args} {
    upvar $name rdsc
    upvar $name rdsc
    set fbegmax -1
    set fbegmax -1
    set mskftot 0
    set mskftot 0
 
 
    foreach arg $args {
    foreach arg $args {
      set nopt [llength $arg]
      set nopt [llength $arg]
      if {$nopt < 2} {
      if {$nopt < 2} {
        error "wrong number of elements in field dsc \"$arg\""
        error "wrong number of elements in field dsc \"$arg\""
      }
      }
      set fnam [lindex $arg 0]
      set fnam [lindex $arg 0]
      set fbeg [lindex $arg 1]
      set fbeg [lindex $arg 1]
      set flen [lindex $arg 2]
      set flen [lindex $arg 2]
      if {$nopt < 3} { set flen 1 }
      if {$nopt < 3} { set flen 1 }
      set popt [lindex $arg 3]
      set popt [lindex $arg 3]
      if {$nopt < 4} { set popt "b" }
      if {$nopt < 4} { set popt "b" }
 
 
      if {( $flen - 1 ) > $fbeg} {
      if {( $flen - 1 ) > $fbeg} {
        error "error in field dsc \"$arg\": length > start position"
        error "error in field dsc \"$arg\": length > start position"
      }
      }
 
 
      set mskb [expr {( 1 << $flen ) - 1}]
      set mskb [expr {( 1 << $flen ) - 1}]
      set mskf [expr {$mskb << ( $fbeg - ( $flen - 1 ) )}]
      set mskf [expr {$mskb << ( $fbeg - ( $flen - 1 ) )}]
      set rdsc($fnam) [list $fbeg $flen $mskb $mskf $popt]
      set rdsc($fnam) [list $fbeg $flen $mskb $mskf $popt]
 
 
      if {$fbegmax < $fbeg} {set fbegmax $fbeg}
      if {$fbegmax < $fbeg} {set fbegmax $fbeg}
      set mskftot [expr {$mskftot | $mskf}]
      set mskftot [expr {$mskftot | $mskf}]
    }
    }
 
 
    set rdsc(-n) [lsort -decreasing -command regdsc_sort \
    set rdsc(-n) [lsort -decreasing -command regdsc_sort \
                    [array names rdsc -regexp {^[^-]}] ]
                    [array names rdsc -regexp {^[^-]}] ]
 
 
    set rdsc(-w) [expr {$fbegmax + 1}]
    set rdsc(-w) [expr {$fbegmax + 1}]
    set rdsc(-m) $mskftot
    set rdsc(-m) $mskftot
 
 
    return ""
    return ""
  }
  }
 
 
  #
  #
  # regdsc_print: print register descriptor ----------------------------------
  # regdsc_print: print register descriptor ----------------------------------
  #
  #
  proc regdsc_print {name} {
  proc regdsc_print {name} {
    upvar $name rdsc
    upvar $name rdsc
    set rval ""
    set rval ""
    if {! [info exists rdsc]} {
    if {! [info exists rdsc]} {
      error "can't access \"$name\": variable doesn't exist"
      error "can't access \"$name\": variable doesn't exist"
    }
    }
 
 
    set rsize $rdsc(-w)
    set rsize $rdsc(-w)
 
 
    append rval "     field   bits  bitmask"
    append rval "     field   bits  bitmask"
 
 
    foreach fnam $rdsc(-n) {
    foreach fnam $rdsc(-n) {
      set fdsc  $rdsc($fnam)
      set fdsc  $rdsc($fnam)
      set fbeg  [lindex $fdsc 0]
      set fbeg  [lindex $fdsc 0]
      set flen  [lindex $fdsc 1]
      set flen  [lindex $fdsc 1]
      set fmskf [lindex $fdsc 3]
      set fmskf [lindex $fdsc 3]
      set line "  "
      set line "  "
      append line [format "%8s" $fnam]
      append line [format "%8s" $fnam]
      if {$flen > 1} {
      if {$flen > 1} {
        append line [format "  %2d:%2d" $fbeg [expr {$fbeg - $flen + 1}]]
        append line [format "  %2d:%2d" $fbeg [expr {$fbeg - $flen + 1}]]
      } else {
      } else {
        append line [format "     %2d" $fbeg]
        append line [format "     %2d" $fbeg]
      }
      }
      append line "  "
      append line "  "
      append line [pbvi "b${rsize}" $fmskf]
      append line [pbvi "b${rsize}" $fmskf]
      append rval "\n$line"
      append rval "\n$line"
    }
    }
    return $rval
    return $rval
  }
  }
 
 
  proc regdsc_sort {a b} {
  proc regdsc_sort {a b} {
    upvar rdsc urdsc
    upvar rdsc urdsc
    return [expr {[lindex $urdsc($a) 0] - [lindex $urdsc($b) 0] }]
    return [expr {[lindex $urdsc($a) 0] - [lindex $urdsc($b) 0] }]
  }
  }
 
 
  #
  #
  # regbld: build a register value from a list of fields ---------------------
  # regbld: build a register value from a list of fields ---------------------
  #
  #
  proc regbld {name args} {
  proc regbld {name args} {
    upvar $name rdsc
    upvar $name rdsc
    set rval 0
    set rval 0
    foreach arg $args {
    foreach arg $args {
      if {[llength $arg] < 1 || [llength $arg] > 2} {
      if {[llength $arg] < 1 || [llength $arg] > 2} {
        error "error in field specifier \"$arg\": must be 'name [val]'"
        error "error in field specifier \"$arg\": must be 'name [val]'"
      }
      }
      set fnam [lindex $arg 0]
      set fnam [lindex $arg 0]
      if {! [info exists rdsc($fnam)] } {
      if {! [info exists rdsc($fnam)] } {
        error "error in field specifier \"$arg\": field unknown"
        error "error in field specifier \"$arg\": field unknown"
      }
      }
      set fbeg [lindex $rdsc($fnam) 0]
      set fbeg [lindex $rdsc($fnam) 0]
      set flen [lindex $rdsc($fnam) 1]
      set flen [lindex $rdsc($fnam) 1]
 
 
      if {[llength $arg] == 1} {
      if {[llength $arg] == 1} {
        if {$flen > 1} {
        if {$flen > 1} {
          error "error in field specifier \"$arg\": no value and flen>1"
          error "error in field specifier \"$arg\": no value and flen>1"
        }
        }
        set mskf [lindex $rdsc($fnam) 3]
        set mskf [lindex $rdsc($fnam) 3]
        set rval [expr {$rval | $mskf}]
        set rval [expr {$rval | $mskf}]
 
 
      } else {
      } else {
        set fval [lindex $arg 1]
        set fval [lindex $arg 1]
        set mskb [lindex $rdsc($fnam) 2]
        set mskb [lindex $rdsc($fnam) 2]
        if {$fval >= 0} {
        if {$fval >= 0} {
          if {$fval > $mskb} {
          if {$fval > $mskb} {
            error "error in field specifier \"$arg\": value > $mskb"
            error "error in field specifier \"$arg\": value > $mskb"
          }
          }
        } else {
        } else {
          if {$fval < [expr {- $mskb}]} {
          if {$fval < [expr {- $mskb}]} {
            error "error in field specifier \"$arg\": value < [expr -$mskb]"
            error "error in field specifier \"$arg\": value < [expr -$mskb]"
          }
          }
          set fval [expr {$fval & $mskb}]
          set fval [expr {$fval & $mskb}]
        }
        }
        set rval [expr {$rval | $fval << ( $fbeg - ( $flen - 1 ) )}]
        set rval [expr {$rval | $fval << ( $fbeg - ( $flen - 1 ) )}]
      }
      }
 
 
    }
    }
    return $rval
    return $rval
  }
  }
 
 
  #
  #
  # regget: extract field from a register value ------------------------------
  # regget: extract field from a register value ------------------------------
  #
  #
  proc regget {name val} {
  proc regget {name val} {
    upvar $name fdsc
    upvar $name fdsc
    set fbeg [lindex $fdsc 0]
    set fbeg [lindex $fdsc 0]
    set flen [lindex $fdsc 1]
    set flen [lindex $fdsc 1]
    set mskb [lindex $fdsc 2]
    set mskb [lindex $fdsc 2]
    return [expr {( $val >> ( $fbeg - ( $flen - 1 ) ) ) & $mskb}]
    return [expr {( $val >> ( $fbeg - ( $flen - 1 ) ) ) & $mskb}]
  }
  }
 
 
  #
  #
  # regtxt: convert register value to a text string --------------------------
  # regtxt: convert register value to a text string --------------------------
  #
  #
  proc regtxt {name val} {
  proc regtxt {name val} {
    upvar $name rdsc
    upvar $name rdsc
    set rval ""
    set rval ""
 
 
    foreach fnam $rdsc(-n) {
    foreach fnam $rdsc(-n) {
      set popt [lindex $rdsc($fnam) 4]
      set popt [lindex $rdsc($fnam) 4]
      set fval [regget rdsc($fnam) $val]
      set fval [regget rdsc($fnam) $val]
      if {$popt ne "-"} {
      if {$popt ne "-"} {
        if {$rval ne ""} {append rval " "}
        if {$rval ne ""} {append rval " "}
        append rval "${fnam}:"
        append rval "${fnam}:"
        if {$popt eq "b"} {
        if {$popt eq "b"} {
          set flen [lindex $rdsc($fnam) 1]
          set flen [lindex $rdsc($fnam) 1]
          append rval [pbvi b${flen} $fval]
          append rval [pbvi b${flen} $fval]
        } else {
        } else {
          append rval [format "%${popt}" $fval]
          append rval [format "%${popt}" $fval]
        }
        }
      }
      }
    }
    }
    return $rval
    return $rval
  }
  }
  #
  #
  # errcnt2txt: returns "PASS" if 0 and "FAIL" otherwise ---------------------
  # errcnt2txt: returns "PASS" if 0 and "FAIL" otherwise ---------------------
  #
  #
  proc errcnt2txt {errcnt} {
  proc errcnt2txt {errcnt} {
    if {$errcnt} {return "FAIL"}
    if {$errcnt} {return "FAIL"}
    return "PASS"
    return "PASS"
  }
  }
  #
  #
  # sxt16: 16 bit sign extend ------------------------------------------------
  # sxt16: 16 bit sign extend ------------------------------------------------
  #
  #
  proc sxt16 {val} {
  proc sxt16 {val} {
    if {$val & 0x8000} {                    # bit 15 set ?
    if {$val & 0x8000} {                    # bit 15 set ?
      set val [expr $val | ~ 077777];       # --> set bits 15 and higher
      set val [expr $val | ~ 077777];       # --> set bits 15 and higher
    }
    }
    return $val
    return $val
  }
  }
 
 
  #
  #
  # sxt32: 32 bit sign extend ------------------------------------------------
  # sxt32: 32 bit sign extend ------------------------------------------------
  #
  #
  proc sxt32 {val} {
  proc sxt32 {val} {
    if {$val & 0x80000000} {                # bit 31 set ?
    if {$val & 0x80000000} {                # bit 31 set ?
      set val [expr $val | ~ 017777777777]; # --> set bits 31 and higher
      set val [expr $val | ~ 017777777777]; # --> set bits 31 and higher
    }
    }
    return $val
    return $val
  }
  }
 
 
  #
  #
  # ! export reg... procs to global scope ------------------------------------
  # ! export reg... procs to global scope ------------------------------------
  #
  #
 
 
  namespace export regdsc
  namespace export regdsc
  namespace export regdsc_print
  namespace export regdsc_print
  namespace export regbld
  namespace export regbld
  namespace export regget
  namespace export regget
  namespace export regtxt
  namespace export regtxt
}
}
 
 
namespace import rutil::regdsc
namespace import rutil::regdsc
namespace import rutil::regdsc_print
namespace import rutil::regdsc_print
namespace import rutil::regbld
namespace import rutil::regbld
namespace import rutil::regget
namespace import rutil::regget
namespace import rutil::regtxt
namespace import rutil::regtxt
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.