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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.6/] [tools/] [tcl/] [rutil/] [util.tcl] - Blame information for rev 40

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 wfjm
# $Id: util.tcl 517 2013-05-09 21:34:45Z mueller $
2 10 wfjm
#
3 21 wfjm
# Copyright 2011-2013 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 10 wfjm
#
5
# This program is free software; you may redistribute and/or modify it under
6
# the terms of the GNU General Public License as published by the Free
7
# Software Foundation, either version 2, or at your option any later version.
8
#
9
# This program is distributed in the hope that it will be useful, but
10
# WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
# for complete details.
13
#
14
#  Revision History:
15
# Date         Rev Version  Comment
16 21 wfjm
# 2013-05-09   517   1.0.1  add optlist2arr
17 10 wfjm
# 2011-03-27   374   1.0    Initial version
18
# 2011-03-19   372   0.1    First draft
19
#
20
 
21
package provide rutil 1.0
22
 
23
package require rutiltpp
24
 
25
namespace eval rutil {
26
  #
27 21 wfjm
  # optlist2arr: process options arguments given as key value list
28
  #
29
  proc optlist2arr {outarrname refarrname optlist} {
30
    upvar $outarrname outarr
31
    upvar $refarrname refarr
32
    array set outarr [array get refarr]
33
    foreach {key value} $optlist {
34
      if {[info exists outarr($key)]} {
35
        set outarr($key) $value
36
      } else {
37
        error "key $key not valid in optlist"
38
      }
39
    }
40
    return ""
41
  }
42
 
43
  #
44 10 wfjm
  # regdsc: setup a register descriptor
45
  #
46
  proc regdsc {name args} {
47
    upvar $name rdsc
48
    set fbegmax -1
49
    set mskftot 0
50
 
51
    foreach arg $args {
52
      set nopt [llength $arg]
53
      if {$nopt < 2} {
54
        error "wrong number of elements in field dsc \"$arg\""
55
      }
56
      set fnam [lindex $arg 0]
57
      set fbeg [lindex $arg 1]
58
      set flen [lindex $arg 2]
59
      if {$nopt < 3} { set flen 1 }
60
      set popt [lindex $arg 3]
61
      if {$nopt < 4} { set popt "b" }
62
 
63
      if {( $flen - 1 ) > $fbeg} {
64
        error "error in field dsc \"$arg\": length > start position"
65
      }
66
 
67 21 wfjm
      set mskb [expr {( 1 << $flen ) - 1}]
68
      set mskf [expr {$mskb << ( $fbeg - ( $flen - 1 ) )}]
69 10 wfjm
      set rdsc($fnam) [list $fbeg $flen $mskb $mskf $popt]
70
 
71
      if {$fbegmax < $fbeg} {set fbegmax $fbeg}
72 21 wfjm
      set mskftot [expr {$mskftot | $mskf}]
73 10 wfjm
    }
74
 
75
    set rdsc(-n) [lsort -decreasing -command regdsc_sort \
76
                    [array names rdsc -regexp {^[^-]}] ]
77
 
78 21 wfjm
    set rdsc(-w) [expr {$fbegmax + 1}]
79 10 wfjm
    set rdsc(-m) $mskftot
80
 
81
    return ""
82
  }
83
 
84
  #
85 19 wfjm
  # regdsc_print: print register descriptor
86 10 wfjm
  #
87
  proc regdsc_print {name} {
88
    upvar $name rdsc
89
    set rval ""
90
    if {! [info exists rdsc]} {
91
      error "can't access \"$name\": variable doesn't exist"
92
    }
93
 
94
    set rsize $rdsc(-w)
95
 
96
    append rval "     field   bits  bitmask"
97
 
98
    foreach fnam $rdsc(-n) {
99
      set fdsc  $rdsc($fnam)
100
      set fbeg  [lindex $fdsc 0]
101
      set flen  [lindex $fdsc 1]
102
      set fmskf [lindex $fdsc 3]
103
      set line "  "
104
      append line [format "%8s" $fnam]
105
      if {$flen > 1} {
106 21 wfjm
        append line [format "  %2d:%2d" $fbeg [expr {$fbeg - $flen + 1}]]
107 10 wfjm
      } else {
108
        append line [format "     %2d" $fbeg]
109
      }
110
      append line "  "
111
      append line [pbvi "b${rsize}" $fmskf]
112
      append rval "\n$line"
113
    }
114
    return $rval
115
  }
116
 
117
  proc regdsc_sort {a b} {
118
    upvar rdsc urdsc
119 21 wfjm
    return [expr {[lindex $urdsc($a) 0] - [lindex $urdsc($b) 0] }]
120 10 wfjm
  }
121
 
122
  #
123
  # regbld: build a register value from a list of fields
124
  #
125
  proc regbld {name args} {
126
    upvar $name rdsc
127
    set rval 0
128
    foreach arg $args {
129
      if {[llength $arg] < 1 || [llength $arg] > 2} {
130
        error "error in field specifier \"$arg\": must be 'name [val]'"
131
      }
132
      set fnam [lindex $arg 0]
133
      if {! [info exists rdsc($fnam)] } {
134
        error "error in field specifier \"$arg\": field unknown"
135
      }
136
      set fbeg [lindex $rdsc($fnam) 0]
137
      set flen [lindex $rdsc($fnam) 1]
138
 
139
      if {[llength $arg] == 1} {
140
        if {$flen > 1} {
141
          error "error in field specifier \"$arg\": no value and flen>1"
142
        }
143
        set mskf [lindex $rdsc($fnam) 3]
144 21 wfjm
        set rval [expr {$rval | $mskf}]
145 10 wfjm
 
146
      } else {
147
        set fval [lindex $arg 1]
148
        set mskb [lindex $rdsc($fnam) 2]
149
        if {$fval >= 0} {
150
          if {$fval > $mskb} {
151
            error "error in field specifier \"$arg\": value > $mskb"
152
          }
153
        } else {
154 21 wfjm
          if {$fval < [expr {- $mskb}]} {
155 10 wfjm
            error "error in field specifier \"$arg\": value < [expr -$mskb]"
156
          }
157 21 wfjm
          set fval [expr {$fval & $mskb}]
158 10 wfjm
        }
159 21 wfjm
        set rval [expr {$rval | $fval << ( $fbeg - ( $flen - 1 ) )}]
160 10 wfjm
      }
161
 
162
    }
163
    return $rval
164
  }
165
 
166
  #
167
  # regget: extract field from a register value
168
  #
169
  proc regget {name val} {
170
    upvar $name fdsc
171
    set fbeg [lindex $fdsc 0]
172
    set flen [lindex $fdsc 1]
173
    set mskb [lindex $fdsc 2]
174 21 wfjm
    return [expr {( $val >> ( $fbeg - ( $flen - 1 ) ) ) & $mskb}]
175 10 wfjm
  }
176
 
177
  #
178
  # regtxt: convert register value to a text string 
179
  #
180
  proc regtxt {name val} {
181
    upvar $name rdsc
182
    set rval ""
183
 
184
    foreach fnam $rdsc(-n) {
185
      set popt [lindex $rdsc($fnam) 4]
186
      set fval [regget rdsc($fnam) $val]
187
      if {$popt ne "-"} {
188
        if {$rval ne ""} {append rval " "}
189
        append rval "${fnam}:"
190
        if {$popt eq "b"} {
191
          set flen [lindex $rdsc($fnam) 1]
192
          append rval [pbvi b${flen} $fval]
193
        } else {
194
          append rval [format "%${popt}" $fval]
195
        }
196
      }
197
    }
198
    return $rval
199
  }
200
  #
201
  # errcnt2txt: returns "PASS" if 0 and "FAIL" otherwise
202
  #
203
  proc errcnt2txt {errcnt} {
204
    if {$errcnt} {return "FAIL"}
205
    return "PASS"
206
  }
207
 
208
  namespace export regdsc
209
  namespace export regdsc_print
210
  namespace export regbld
211
  namespace export regget
212
  namespace export regtxt
213
}
214
 
215
namespace import rutil::regdsc
216
namespace import rutil::regdsc_print
217
namespace import rutil::regbld
218
namespace import rutil::regget
219
namespace import rutil::regtxt

powered by: WebSVN 2.1.0

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