Commit 9ef952ce authored by Ille, Ondrej, Ing.'s avatar Ille, Ondrej, Ing.

Added generation of VHDL register map implementation from

IP-XACT xml definition.
parent fe29cdcc
################################################################################
##
## CAN with Flexible Data-Rate IP Core
##
## Copyright (C) 2017 Ondrej Ille <ondrej.ille@gmail.com>
##
## Script for generation of VHDL register map entity from IP-XACT
## specification.
##
## Arguments:
## licPath - File with license which should be placed to header of the
## all source code files.
## xactSpec - Path to a IP-XACT specification file with register maps
## memMap - Name of the IP-XACT Memory map which should be used for
## register map implementation.
## wordWidth - Size of the access bus word. Register bit field offsets
## are concatenated into word width size instead of simple
## offset from beginning of register. (E.g. 32 bit ->
## bitfields from first four 8-bit register are concatenated
## into 32 bit values)
## outDir - Output directory where register map is created.
##
##
## Revision history:
## 25.11.2018 Implemented the script
##
################################################################################
import argparse
import sys
import time
import importlib.util
import os
import inspect
import math
from pyXact_generator.gen_lib import *
from pyXact_generator.ip_xact.vhdl_reg_map_generator import VhdlRegMapGenerator
from shutil import copyfile
def parse_args():
parser = argparse.ArgumentParser(
description='Generate a VHDL package from an IP-XACT file')
parser.add_argument('--licPath', dest='licPath' , help=""" File with
license which should be placed to header of the
all source code files""")
parser.add_argument('--xactSpec', dest='xactSpec', help="""Path to a IP-XACT
specification file with register maps""")
parser.add_argument('--memMap', dest='memMap', help=""" Name of the
IP-XACT Memory map which should be used for
register map implementation""")
parser.add_argument('--wordWidth', dest='wordWidth', type=int,
help=""" Size of the
access bus word. Register bit field offsets are
concatenated into word width size instead of simple
offset from beginning of register. (E.g. 32 bit ->
bitfields from first four 8-bit register are
concatenated into 32 bit values)""")
parser.add_argument('--registeredRead', dest='registeredRead',
help=""" When set to "True" read data are read with
one clock cycle delay. When set to false read data
are available within the same clock cycle""")
parser.add_argument('--outDir', dest='outDir', help=""" Output directory
where to write VHDL register map implementation.""")
return parser.parse_args();
def write_reg_map_package(vhdlGen, dir_path):
"""
Create package with records for register blocks within an address block.
"""
reg_map_pkg_name = os.path.join(dir_path, vhdlGen.memMap.name.lower() + "_pkg.vhd")
of = open(reg_map_pkg_name, 'w')
vhdlGen.set_of(of)
write_license(lic_text, '-', of)
vhdlGen.write_reg_map_pkg()
vhdlGen.commit_to_file()
of.close()
def write_reg_map_implementation(vhdlGen, dir_path):
"""
Write register map implementation. Create separate entity file for
each register memory block.
"""
for block in vhdlGen.memMap.addressBlock:
print("Processing memory block: " + block.name)
if (block.usage == "register"):
file_path = os.path.join(dir_path, block.name.lower() + "_reg_map.vhd")
of = open(file_path, 'w')
vhdlGen.set_of(of)
write_license(lic_text, '-', of)
vhdlGen.write_reg_block(block)
vhdlGen.commit_to_file()
of.close()
else:
print("Skipping unsupported block type: " + block.usage)
print("\n")
def copy_reg_map_sources(vhdlGen, dir_path, destDir):
"""
Copy VHDL templates to destination directory!
"""
for templ_name, templ_path in vhdlGen.template_sources.items():
src_path = os.path.join(ROOT_PATH, templ_path)
dest_path = os.path.join(ROOT_PATH, destDir)
dest_path = os.path.join(dest_path, os.path.basename(templ_path))
copyfile(src_path, dest_path)
if __name__ == '__main__':
args = parse_args()
with open(args.xactSpec) as f:
name = None
offset = 0
# Load IP-Xact component
component = Component()
component.load(f)
# Create new VHDL register map generator
vhdlGen = VhdlRegMapGenerator(component, args.memMap, args.wordWidth)
# Load license text
lic_text = ""
if (args.licPath != ""):
lic_text = load_license(args.licPath)
# Check output directory
dir_path = os.path.join(ROOT_PATH, args.outDir)
if (not os.path.isdir(dir_path)):
print("ERROR: " + dir_path + " is not a directory")
sys.exit(1)
# Configure registered / non-registered read
if (args.registeredRead == "y" or args.registeredRead == "yes"):
vhdlGen.registered_read = True
else:
vhdlGen.registered_read = False
# Create common package for whole address map
write_reg_map_package(vhdlGen, dir_path)
# Create implementation of each register block within address map
write_reg_map_implementation(vhdlGen, dir_path)
# Copy source templates to destination directory
copy_reg_map_sources(vhdlGen, dir_path, args.outDir)
This diff is collapsed.
################################################################################
##
## CAN with Flexible Data-Rate IP Core
##
## Copyright (C) 2018 Ondrej Ille <ondrej.ille@gmail.com>
##
## Class for component declaration and instantantion in VHDL.
##
## Revision history:
## 06.10.2018 First implementation
##
################################################################################
from abc import ABCMeta, abstractmethod
class VhdlCompDeclaration(LanDeclaration):
# VHDL component declaration inherits following attributes from
# LanDeclaration:
# type = name of the entity, architecture or component
# value = name of instance in case of component instatiation.
# comment = VHDL comment before the component instantiation
# intType = "component", "entity" or "architecture"
# When true, component instance will be created, When false component
# declaration will be created.
instance = True
# List of "LanDeclarations" with signals which are ports of entity or
# component. For architecture it contains list of internal signals.
ports = None
# List of "LanDeclarations" with constants which are generics of entity.
generics = None
def __init__(self, name, value, type=None, bitWidth=None, specifier=None,
alignLen=50, gap=0, bitIndex=None, intType=None, comment=None):
self.name = name
self.value = value
self.alignLen = alignLen
self.gap = gap
if (comment != None):
self.comment = comment
if (type != None):
self.type = type
if (bitWidth != None):
self.bitWidth = bitWidth
if (specifier != None):
self.specifier = specifier
if (bitIndex != None):
self.bitIndex = bitIndex
if (intType != None):
self.intType = intType
......@@ -38,10 +38,39 @@ class LanDeclaration(metaclass=ABCMeta):
# Number of tabs before the declaration
gap = 0
# Ports of VHDL entity (Dictionary of Declarations)
ports = {}
# Generics of VHDL entity (Dictionary of Declarations)
generics = {}
# Alignment of generated declaration to the Right
alignRight = True
# Alignment of generated declaration to the Right
alignLeft = False
# Indent between name and type specifiers
doIndent = False
# Wrap declaration if it is longer than 80 characters
wrap = True
# Comment before the declaration
comment = None
comment = None
# Direction of the declaration
direction = None
# Flag if component is an instance (used for distinguishing between entity and
# component
isInstance = False
# Upper and lower boundary of std_logic_vector
upBound = None
lowBound = None
# Internal type to distinguish between various formats of declaration
# (e.g. enum element declaration has different format than structure
# element declaration)
......@@ -54,7 +83,9 @@ class LanDeclaration(metaclass=ABCMeta):
self.value = value
self.alignLen = alignLen
self.gap = gap
self.ports = {}
self.generics = {}
if (comment != None):
self.comment = comment
if (type != None):
......@@ -67,4 +98,4 @@ class LanDeclaration(metaclass=ABCMeta):
self.bitIndex = bitIndex
if (intType != None):
self.intType = intType
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment