Python脚本生成寄存器模型
第一种形式
| register | address | reg_access | field | field_access | reset_value | bitpos_end | bitpos_start | function |
|---|---|---|---|---|---|---|---|---|
| chnl0_ctrl | 0x00 | RW | chnl_en | RW | 0x1 | 0 | 0 | channel enable |
| prio_level | RW | 0x3 | 2 | 1 | priority level | |||
| pkt_len | RW | 0x0 | 5 | 3 | packet length | |||
| reserved | RO | 0x0 | 31 | 6 | reserved | |||
| chnl1_ctrl | 0x04 | RW | chnl_en | RW | 0x1 | 0 | 0 | channel enable |
| prio_level | RW | 0x3 | 2 | 1 | priority level | |||
| pkt_len | RW | 0x0 | 5 | 3 | packet length | |||
| reserved | RO | 0x0 | 31 | 6 | reserved | |||
| chnl2_ctrl | 0x08 | RW | chnl_en | RW | 0x1 | 0 | 0 | channel enable |
| prio_level | RW | 0x3 | 2 | 1 | priority level | |||
| pkt_len | RW | 0x0 | 5 | 3 | packet length | |||
| reserved | RO | 0x0 | 31 | 6 | reserved | |||
| chnl0_stat | 0x10 | RO | fifo_avail | RO | 0x20 | 7 | 0 | fifo available storage |
| reserved | RO | 0x0 | 31 | 8 | reserved | |||
| chnl1_stat | 0x14 | RO | fifo_avail | RO | 0x20 | 7 | 0 | fifo available storage |
| reserved | RO | 0x0 | 31 | 8 | reserved | |||
| chnl2_stat | 0x18 | RO | fifo_avail | RO | 0x20 | 7 | 0 | fifo available storage |
| reserved | RO | 0x0 | 31 | 8 | reserved |
第二种形式
| register | address | reg_access | field | field_access | reset_value | bitpos_end | bitpos_start | function |
|---|---|---|---|---|---|---|---|---|
| slv_en | 0x00 | RW | en | RW | 0x0 | 3 | 0 | slave enable |
| reserved | RO | 0x0 | 31 | 4 | reserved | |||
| parity_err_clr | 0x04 | RW | err_clr | RW | 0x0 | 3 | 0 | parity error flag clear |
| reserved | RO | 0x0 | 31 | 4 | reserved | |||
| slv_id | 0x08 | RW | slv0_id | RW | 0x0 | 7 | 0 | slave0 packet id |
| slv1_id | RW | 0x1 | 15 | 8 | slave1 packet id | |||
| slv2_id | RW | 0x2 | 23 | 16 | slave2 packet id | |||
| slv3_id | RW | 0x3 | 31 | 24 | slave3 packet id | |||
| slv_len | 0x0C | RW | slv0_len | RW | 0x0 | 7 | 0 | slave0 packet length |
| slv1_len | RW | 0x0 | 15 | 8 | slave1 packet length | |||
| slv2_len | RW | 0x0 | 23 | 16 | slave2 packet length | |||
| slv3_len | RW | 0x0 | 31 | 24 | slave3 packet length | |||
| slv0_free_slot | 0x80 | RO | free_slot | RO | 0x20 | 5 | 0 | slave0 available slot |
| reserved | RO | 0x0 | 31 | 6 | reserved | |||
| slv1_free_slot | 0x84 | RO | free_slot | RO | 0x20 | 5 | 0 | slave1 available slot |
| reserved | RO | 0x0 | 31 | 6 | reserved | |||
| slv2_free_slot | 0x88 | RO | free_slot | RO | 0x20 | 5 | 0 | slave2 available slot |
| reserved | RO | 0x0 | 31 | 6 | reserved | |||
| slv3_free_slot | 0x8C | RO | free_slot | RO | 0x20 | 5 | 0 | slave3 available slot |
| reserved | RO | 0x0 | 31 | 6 | reserved | |||
| slv0_parity_err | 0x90 | RO | parity_err | RO | 0x0 | 0 | 0 | slave0 parity error flag |
| reserved | RO | 0x0 | 31 | 1 | reserved | |||
| slv1_parity_err | 0x94 | RO | parity_err | RO | 0x0 | 0 | 0 | slave1 parity error flag |
| reserved | RO | 0x0 | 31 | 1 | reserved | |||
| slv2_parity_err | 0x98 | RO | parity_err | RO | 0x0 | 0 | 0 | slave2 parity error flag |
| reserved | RO | 0x0 | 31 | 1 | reserved | |||
| slv3_parity_err | 0x9C | RO | parity_err | RO | 0x0 | 0 | 0 | slave3 parity error flag |
| reserved | RO | 0x0 | 31 | 1 | reserved |
import re
import csv
import os
#from rkvRgmItem import RgmItem
class RgmItem:
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
self._properties = {'register':''
,'address':'0x00'
,'fields':[]
}
class GenRgm:
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
self._rgmItemList = []
self._curRegName = ''
self._uvmFileName = 'Desktop\mcdf_rgm_pkg.sv'
self._cFileName = 'mcdf_io.h'
# Excel/CSV format file read/write methods
def readRgmFile(self, filename):
"read register file and update the internal database"
rgmFile = open(filename, 'r')
self._rgmFileName = filename
reader = csv.DictReader(rgmFile)
for infos in reader:
self._readRgmInfos(infos)
def _readRgmInfos(self, infos):
"""extract register information from string line
and return it as a dictionary
"""
if(infos['register'] != ''):
rgmObj = RgmItem()
self._curRegName = infos['register']
rgmObj._properties['register'] = infos['register']
rgmObj._properties['address'] = infos['address']
rgmObj._properties['reg_access'] = infos['reg_access']
self._rgmItemList.append(rgmObj)
fieldInfos = self._readFieldInfos(infos)
self._rgmItemList[-1]._properties['fields'].append(fieldInfos)
def _readFieldInfos(self, infos):
fieldInfos = {}
fieldInfos['field'] = infos['field']
fieldInfos['field_access'] = infos['field_access']
fieldInfos['reset_value'] = infos['reset_value']
fieldInfos['bitpos_end'] = infos['bitpos_end']
fieldInfos['bitpos_start'] = infos['bitpos_start']
fieldInfos['function'] = infos['function']
return fieldInfos
def genUVMFile(self):
with open(self._uvmFileName, 'w') as uvmFile:
def _writeUVMHeader():
uvmFile.write('package mcdf_rgm_pkg;\n')
uvmFile.write(' import uvm_pkg::*;\n')
uvmFile.write(' `include "uvm_macros.svh"\n')
def _writeRegClass(rgmObj):
uvmFile.write(' class %s_reg extends uvm_reg;\n' % rgmObj._properties['register'])
uvmFile.write(' `uvm_object_utils(%s_reg)\n' % rgmObj._properties['register'])
for fd in rgmObj._properties['fields']:
uvmFile.write(' rand uvm_reg_field %s;\n' % fd['field'])
uvmFile.write(' covergroup value_cg;\n')
uvmFile.write(' option.per_instance = 1;\n')
for fd in rgmObj._properties['fields']:
uvmFile.write(' %s: coverpoint %s.value[%s:%s];\n' % (fd['field'],fd['field'],fd['bitpos_end'],fd['bitpos_start']))
uvmFile.write(' endgroup\n')
uvmFile.write('\
function new(string name = "%s_reg");\n\
super.new(name, 32, UVM_CVR_ALL);\n\
void\'(set_coverage(UVM_CVR_FIELD_VALS));\n\
if(has_coverage(UVM_CVR_FIELD_VALS)) begin\n\
value_cg = new();\n\
end\n\
endfunction\n' % rgmObj._properties['register'])
uvmFile.write(' virtual function void build();\n')
for fd in rgmObj._properties['fields']:
uvmFile.write(' %s = uvm_reg_field::type_id::create("%s");\n' % (fd['field'], fd['field']))
for fd in rgmObj._properties['fields']:
uvmFile.write(' %s.configure(this, %0d, %s, "%s", 0, \'h%s, 1, 0, 0);\n' % (fd['field'], int(fd['bitpos_end'])-int(fd['bitpos_start'])+1, fd['bitpos_start'], fd['field_access'], fd['reset_value'].replace('0x','')))
uvmFile.write(' endfunction\n')
uvmFile.write('\
function void sample(\n\
uvm_reg_data_t data,\n\
uvm_reg_data_t byte_en,\n\
bit is_read,\n\
uvm_reg_map map\n\
);\n\
super.sample(data, byte_en, is_read, map);\n\
sample_values(); \n\
endfunction\n\
function void sample_values();\n\
super.sample_values();\n\
if (get_coverage(UVM_CVR_FIELD_VALS)) begin\n\
value_cg.sample();\n\
end\n\
endfunction\n\
endclass\n\n')
def _writeRgmClass():
uvmFile.write(' class mcdf_rgm extends uvm_reg_block;\n')
uvmFile.write(' `uvm_object_utils(mcdf_rgm)\n')
for rg in self._rgmItemList:
uvmFile.write(' rand %s_reg %s;\n' % (rg._properties['register'], rg._properties['register']))
uvmFile.write('\
uvm_reg_map map;\n\
function new(string name = "mcdf_rgm");\n\
super.new(name, UVM_NO_COVERAGE);\n\
endfunction\n\
virtual function void build();\n')
for rg in self._rgmItemList:
uvmFile.write(' %s = %s_reg::type_id::create("%s");\n' % (rg._properties['register'], rg._properties['register'], rg._properties['register']))
uvmFile.write(' %s.configure(this);\n' % rg._properties['register'])
uvmFile.write(' %s.build();\n' % rg._properties['register'])
uvmFile.write(' map = create_map("map", \'h0, 4, UVM_LITTLE_ENDIAN);\n')
for rg in self._rgmItemList:
uvmFile.write(' map.add_reg(%s, 32\'h%s, "%s");\n' % (rg._properties['register'], rg._properties['address'].replace('0x',''), rg._properties['reg_access']))
for rg in self._rgmItemList:
uvmFile.write(' //%s.add_hdl_path_slice("???", 0, 32);\n' % rg._properties['register'])
uvmFile.write(' //add_hdl_path("???");\n')
uvmFile.write(' lock_model();\n')
uvmFile.write(' endfunction\n')
uvmFile.write(' endclass\n\n')
uvmFile.write('endpackage\n')
#genUVMFile main function below
_writeUVMHeader()
for rgmObj in self._rgmItemList:
_writeRegClass(rgmObj)
_writeRgmClass()
def genCFile(self):
pass
if __name__ == '__main__' :
moduleTestList = []
#[Test] clock file read
def testReadRgmFile():
print('%s \n[testReadClockFile] started \n%s\n' % (40*'*', 40*'*'))
gen = GenRgm()
gen.readRgmFile('mcdf_regs_v1.csv')
print('%s \n[testReadClockFile] PASSED \n%s\n' % (40*'*', 40*'*'))
moduleTestList.append(testReadRgmFile)
def testGenUVMRgm():
print('%s \n[testReadClockFile] started \n%s\n' % (40*'*', 40*'*'))
gen = GenRgm()
gen.readRgmFile('Desktop\mcdf_regs_v2.csv')
gen.genUVMFile()
print('%s \n[testReadClockFile] PASSED \n%s\n' % (40*'*', 40*'*'))
moduleTestList.append(testReadRgmFile)
#testReadRgmFile()
testGenUVMRgm()
浙公网安备 33010602011771号