1
- #! /usr/bin/env python
1
+ #!/usr/bin/env python
2
2
"""Generate XML file from YAML input"""
3
3
import xml .etree .ElementTree as ET
4
4
from pprint import pprint
5
5
import argparse
6
6
import os
7
7
import yaml
8
8
9
+ zm_num_entries = 1024
10
+
9
11
#% %
10
- def make_node (parent : ET .Element , myid : str , thedict : dict , addr2 : int ,
12
+ def make_node (parent : ET .Element , myid : str , thedict : dict , addr2 : int , bit : int ,
11
13
parent_id : str ) -> ET .Element :
12
14
"""create the node to be inserted into the xml tree"""
13
15
# pylint: disable=too-many-branches
14
- # I disable this check because as far as I can tell it's wrong
16
+ #I disable this check because as far as I can tell it's wrong
15
17
thenode = ET .SubElement (parent , 'node' )
16
18
myid = myid .replace (' ' , '_' )
17
19
thenode .set ('id' , myid )
18
20
#address is half of the sensor address since these are 32 bit addresses
19
21
theaddr = int (addr2 / 2 )
20
- remain = addr2 % 2
22
+ remain = bit
21
23
thenode .set ('address' , str (hex (theaddr )))
22
24
#this appears to be on all the nodes
23
25
thenode .set ("permission" , "r" )
@@ -90,11 +92,12 @@ def calc_size(thedict: dict) -> int:
90
92
#and a pretty print method
91
93
class reg :
92
94
"""create an object with a name, and a start end end register"""
93
- def __init__ (self , name , sta , end , sz ):
95
+ def __init__ (self , name , sta , end , sz , width ):
94
96
self .name = name
95
97
self .start = sta
96
98
self .end = end
97
99
self .size = sz
100
+ self .width = width
98
101
99
102
def __str__ (self ):
100
103
return "name: " + self .name + " start: " + str (self .start ) + \
@@ -112,12 +115,11 @@ def overlaps(self, other):
112
115
113
116
def overloads (self ):
114
117
"""check if the object overloads the register space"""
115
- if self .start + self .size >= 255 :
118
+ if self .start + self .size >= zm_num_entries - 1 :
116
119
return True
117
120
return False
118
121
119
-
120
- # custom file type for yaml file, to be used with argparse
122
+ #custom file type for yaml file, to be used with argparse
121
123
def yaml_file (filename ):
122
124
"""custom file type for yaml file, to be used with argparse"""
123
125
if not filename .endswith ('.yml' ):
@@ -128,7 +130,7 @@ def yaml_file(filename):
128
130
parser .add_argument ('-v' , '--verbose' , action = 'store_true' ,
129
131
help = 'increase output verbosity' )
130
132
parser .add_argument ('-d' , '--directory' , type = str , help = 'output directory' )
131
- # this argument is required, one input file ending with yaml extension
133
+ #this argument is required, one input file ending with yaml extension
132
134
parser .add_argument ('input_file' , metavar = 'file' , type = yaml_file ,
133
135
help = 'input yaml file name' )
134
136
@@ -153,39 +155,64 @@ def yaml_file(filename):
153
155
cm = ET .Element ('node' )
154
156
cm .set ('id' , 'CM' )
155
157
cm .set ('address' , '0x00000000' )
156
-
158
+ prev_addr = 0x0 #keep track of the most recent address that comes into a pair of bytes for 8-bit masking
159
+ prev_j = 0x0 #keep track of the order of postfixes in each name node
160
+ prev_bit = 0x0 #keep track of the even or odd order of bytes globally sent for masking
157
161
#% %
158
162
config = y ['config' ]
159
-
160
163
for c in config : # loop over entries in configuration (sensor category)
161
164
i = 0 # counter over the number of sensors within a category
162
165
names = c ['names' ]
166
+ start = c ['start' ]
167
+ count = c ['count' ]
163
168
for n in names : # loop over names of sensors within a category
169
+ if (n == "R0B" and start != prev_start + prev_count + 1 ): #clkmonr0a and clkmon are from the same function in zynqmontask
170
+ print ("warning: the start address of clkmon should continue from clkr0a" )
164
171
if 'postfixes' in c :
165
- pp = node = ET .SubElement (cm , 'node' )
166
- pp .set ('id' , n )
167
- start = c ['start' ]
168
- addr = int ((start + i )/ 2 )
169
- pp .set ('address' , str (hex (addr )))
170
172
postfixes = c ['postfixes' ]
171
173
j = 0
172
174
for p in postfixes :
175
+ addr = int ((start + i )/ 2 )
176
+ bit = i % 2
173
177
if p == 'RESERVED' :
174
178
i += 1
175
179
j += 1
176
180
continue
177
- if args .verbose :
178
- print ("adding postfix" , p , "to node" , n )
179
- node = make_node (pp , p , c , j , n )
181
+ if (bit == 1 and j == 0 ): #the previous name node has odd bytes so this postfix node uses the previous postfix address but masks off the lower byte
182
+ pp = node = ET .SubElement (cm , 'node' )
183
+ pp .set ('id' , n )
184
+ pp .set ('address' , str (hex (prev_addr )))
185
+ node = make_node (pp , p , c , j , bit , n )
186
+ elif (bit == 0 and j == 0 ): #starting a new postfix node in a new name node
187
+ pp = node = ET .SubElement (cm , 'node' )
188
+ pp .set ('id' , n )
189
+ pp .set ('address' , str (hex (addr )))
190
+ node = make_node (pp , p , c , j , bit , n )
191
+ else : # any non-first byte in a name node
192
+ if (prev_bit == 0 ): #the upper byte of the previous postfix node
193
+ node = make_node (pp , p , c , j , bit , n )
194
+ else : #the low byte with an increasing postfix node by one
195
+ node = make_node (pp , p , c , j + 1 , bit , n )
196
+ if (prev_bit == bit and prev_addr == addr and prev_addr != 0 ) :
197
+ print ("warning : please check if masks overlapped at node " , n , " addr " , hex (prev_addr ))
198
+ prev_addr = addr
199
+ prev_j = j
200
+ prev_bit = bit
180
201
i += 1
181
202
j += 1
182
203
else :
183
- start = c ['start' ]
184
- make_node (cm , n , c , start + i , "" )
204
+ make_node (cm , n , c , start + i , (start + i )% 2 , "" )
205
+ if (prev_bit == (start + i )% 2 and prev_addr == int ((start + i )/ 2 ) and prev_addr != 0 ) :
206
+ print ("warning : please check if masks overlapped at node " , n , " addr " , hex (prev_addr ))
207
+ prev_addr = int ((start + i )/ 2 )
208
+ prev_bit = (start + i )% 2
185
209
i += 1
210
+ prev_start = start
211
+ prev_count = count
212
+
186
213
tree = ET .ElementTree (cm )
187
214
ET .indent (tree , space = '\t ' )
188
- # create output file name based on input file, replacing 'yml' with 'xml'
215
+ #create output file name based on input file, replacing 'yml' with 'xml'
189
216
out_name = os .path .basename (args .input_file )[:- len ('.yml' )] + '.xml'
190
217
out_name = args .directory + '/' + out_name
191
218
if args .verbose :
@@ -209,7 +236,20 @@ def yaml_file(filename):
209
236
postfixes = ' '
210
237
size = calc_size (c )
211
238
thislength = len (postfixes ) * len (names )* size
212
- entries .append (reg (c ['name' ], start , start + thislength - 1 , thislength ))
239
+ width = 99
240
+ if c ['type' ] == 'int8' :
241
+ width = 8
242
+ elif c ['type' ] == 'int16' :
243
+ width = 16
244
+ elif c ['type' ] == 'fp16' :
245
+ width = 16
246
+ elif c ['type' ] == 'char' :
247
+ width = 16
248
+ elif c ['type' ] == 'uint32_t' :
249
+ width = 32
250
+ elif c ['type' ] == 'uint16_t' :
251
+ width = 16
252
+ entries .append (reg (c ['name' ], start , start + thislength - 1 , thislength , width ))
213
253
if args .verbose :
214
254
for e in entries :
215
255
print (e )
0 commit comments