Commit 159fc2f6 authored by Tiago Jorge's avatar Tiago Jorge
Browse files

Add new b-mapper for BRAVE; Fix pointer to global variable.

(brave b-mapper is copy of zestsc1 as starting point)
parent 4e17a4b0
# (C) Semantix Information Technologies.
#
# Semantix Information Technologies is licensing the code of the
# Data Modelling Tools (DMT) in the following dual-license mode:
#
# Commercial Developer License:
# The DMT Commercial Developer License is the suggested version
# to use for the development of proprietary and/or commercial software.
# This version is for developers/companies who do not want to comply
# with the terms of the GNU Lesser General Public License version 2.1.
#
# GNU LGPL v. 2.1:
# This version of DMT is the one to use for the development of
# applications, when you are willing to comply with the terms of the
# GNU Lesser General Public License version 2.1.
#
# Note that in both cases, there are no charges (royalties) for the
# generated code.
#
'''
This is the code generator for the VHDL code mapper.
This backend is called by aadl2glueC, when a VHDL subprogram
is identified in the input concurrency view.
This code generator supports both UPER and Native encodings.
Matlab/Simulink is a member of the synchronous "club" (SCADE, etc) ;
The subsystem developer (or rather, the APLC developer) is
building a model in Simulink, and the generated code is offered
in the form of a "function" that does all the work.
To that end, we create "glue" functions for input and output
parameters, which have C callable interfaces. The necessary
stubs (to allow calling from the VM side) are also generated.
'''
import os
import re
import math
from typing import cast, Union, List, Tuple, IO, Any, Dict # NOQA pylint: disable=unused-import
from ..commonPy.utility import panic, panicWithCallStack
from ..commonPy.asnAST import (
AsnBasicNode, AsnInt, AsnSequence, AsnSet, AsnChoice, AsnSequenceOf,
AsnSetOf, AsnEnumerated, AsnMetaMember, isSequenceVariable,
sourceSequenceLimit, AsnNode, AsnString, AsnReal, AsnOctetString,
AsnSequenceOrSetOf, AsnSequenceOrSet, AsnBool)
from ..commonPy.asnParser import AST_Lookup, AST_Leaftypes
from ..commonPy.aadlAST import (
InParam, AadlPort, AadlParameter,
)
from ..commonPy.aadlAST import Param, ApLevelContainer # NOQA pylint: disable=unused-import
from ..commonPy import asnParser
from ..commonPy.recursiveMapper import RecursiveMapperGeneric
from .synchronousTool import SynchronousToolGlueGeneratorGeneric
isAsynchronous = False
vhdlBackend = None
def Version() -> None:
print("Code generator: " + "$Id: vhdl_B_mapper.py 1754 2009-12-26 13:02:45Z ttsiodras $") # pragma: no cover
def CleanName(name: str) -> str:
return re.sub(r'[^a-zA-Z0-9_]', '_', name)
def RegistersAllocated(node_or_str: Union[str, AsnNode]) -> int:
names = asnParser.g_names
if isinstance(node_or_str, str):
node = names[node_or_str] # type: AsnNode
else:
node = node_or_str
retValue = None
if isinstance(node, AsnBasicNode):
retValue = 0
realLeafType = asnParser.g_leafTypeDict[node._leafType]
if realLeafType == "INTEGER":
retValue = 8
elif realLeafType == "REAL":
panic("The VHDL mapper can't work with REALs (non-synthesizeable circuits!) (%s)" % node.Location()) # pragma: no cover
elif realLeafType == "BOOLEAN":
retValue = 1
elif realLeafType == "OCTET STRING":
nodeOct = cast(AsnString, node)
if not nodeOct._range:
panicWithCallStack("OCTET STRING (in %s) must have a SIZE constraint inside ASN.1,\nor else we can't generate C code!" % node.Location()) # pragma: no cover
if len(nodeOct._range) > 1 and nodeOct._range[0] != nodeOct._range[1]:
panicWithCallStack("VHDL OCTET STRING (in %s) must have a fixed SIZE constraint !" % node.Location()) # pragma: no cover
retValue = nodeOct._range[-1]
else: # pragma: no cover
panicWithCallStack("Basic type %s can't be mapped..." % realLeafType) # pragma: no cover
elif isinstance(node, (AsnSequence, AsnSet)):
retValue = sum(RegistersAllocated(x[1]) for x in node._members)
elif isinstance(node, AsnChoice):
retValue = 1 + sum(RegistersAllocated(x[1]) for x in node._members)
elif isinstance(node, AsnSequenceOf):
if not node._range:
panicWithCallStack("For VHDL, a SIZE constraint is mandatory (%s)!\n" % node.Location()) # pragma: no cover
if len(node._range) > 1 and node._range[0] != node._range[1]:
panicWithCallStack("Must have a fixed SIZE constraint (in %s) for VHDL code!" % node.Location()) # pragma: no cover
retValue = node._range[-1] * RegistersAllocated(node._containedType)
elif isinstance(node, AsnSetOf):
if not node._range:
panicWithCallStack("For VHDL, a SIZE constraint is mandatory (%s)!\n" % node.Location()) # pragma: no cover
if len(node._range) > 1 and node._range[0] != node._range[1]:
panicWithCallStack("Must have a fixed SIZE constraint (in %s) for VHDL code!" % node.Location()) # pragma: no cover
retValue = node._range[-1] * RegistersAllocated(node._containedType)
elif isinstance(node, AsnEnumerated):
retValue = 1
elif isinstance(node, AsnMetaMember):
retValue = RegistersAllocated(names[node._containedType])
else: # pragma: no cover
panicWithCallStack("unsupported %s (%s)" % (str(node.__class__), node.Location())) # pragma: no cover
return retValue
class VHDL_Circuit:
allCircuits = [] # type: List[VHDL_Circuit]
lookupSP = {} # type: Dict[str, VHDL_Circuit]
currentCircuit = None # type: VHDL_Circuit
names = None # type: asnParser.AST_Lookup
leafTypeDict = None # type: asnParser.AST_Leaftypes
currentOffset = 0x0 # type: int
def __init__(self, sp: ApLevelContainer) -> None:
VHDL_Circuit.allCircuits.append(self)
VHDL_Circuit.lookupSP[sp._id] = self
VHDL_Circuit.currentCircuit = self
self._sp = sp
self._params = [] # type: List[Tuple[Param, asnParser.Typename, AsnNode]]
self._spCleanName = CleanName(sp._id)
self._offset = VHDL_Circuit.currentOffset
VHDL_Circuit.currentOffset += 1 # reserve one register for "start" signal
self._paramOffset = {} # type: Dict[str, int]
for p in sp._params:
self._paramOffset[p._id] = VHDL_Circuit.currentOffset
VHDL_Circuit.currentOffset += RegistersAllocated(p._signal._asnNodename)
def __str__(self) -> str:
msg = "PI:%s\n" % self._sp._id # pragma: no cover
msg += ''.join([p[0]._id + ':' + p[0]._signal._asnNodename + ("(in)" if isinstance(p[0], InParam) else "(out)") + '\n' for p in self._params]) # pragma: no cover
return msg # pragma: no cover
def AddParam(self, nodeTypename: str, node: AsnNode, param: Param, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> None:
VHDL_Circuit.names = names
VHDL_Circuit.leafTypeDict = leafTypeDict
self._params.append((param, nodeTypename, node))
# pylint: disable=no-self-use
class FromVHDLToASN1SCC(RecursiveMapperGeneric[List[int], str]): # pylint: disable=invalid-sequence-index
def MapInteger(self, srcVHDL: List[int], destVar: str, _: AsnInt, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
register = srcVHDL[0] + srcVHDL[1]
lines = [] # type: List[str]
lines.append("{\n")
lines.append(" unsigned char tmp, i;\n")
lines.append(" asn1SccSint val = 0;\n")
lines.append(" for(i=0; i<sizeof(asn1SccSint); i++) {\n")
#lines.append(" ZestSC1ReadRegister(g_Handle, BASE_ADDR + %s + i, &tmp);\n" % hex(register))
lines.append(" val <<= 8; val |= tmp;\n")
lines.append(" }\n")
lines.append("#if WORD_SIZE == 8\n")
lines.append(" val = __builtin_bswap64(val);\n")
lines.append("#else\n")
lines.append(" val = __builtin_bswap32(val);\n")
lines.append("#endif\n")
lines.append(" %s = val;\n" % destVar)
lines.append("}\n")
srcVHDL[0] += 8
return lines
def MapReal(self, dummy: List[int], _: str, node: AsnReal, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
panicWithCallStack("REALs (%s) cannot be used for synthesizeable VHDL" % node.Location()) # pragma: no cover
# return ["%s = (double) %s;\n" % (destVar, srcVHDL)]
def MapBoolean(self, srcVHDL: List[int], destVar: str, _: AsnBool, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
register = srcVHDL[0] + srcVHDL[1]
lines = [] # type: List[str]
lines.append("{\n")
lines.append(" unsigned char tmp;\n")
#lines.append(" ZestSC1ReadRegister(g_Handle, BASE_ADDR + %s, &tmp);\n" % hex(register))
lines.append(" %s = (asn1SccUint) tmp;\n" % destVar)
lines.append("}\n")
srcVHDL[0] += 1
return lines
def MapOctetString(self, srcVHDL: List[int], destVar: str, node: AsnOctetString, _: AST_Leaftypes, __: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
register = srcVHDL[0] + srcVHDL[1]
lines = [] # type: List[str]
if not node._range:
panicWithCallStack("OCTET STRING (in %s) must have a SIZE constraint inside ASN.1,\nor else we can't generate C code!" % node.Location()) # pragma: no cover
if len(node._range) > 1 and node._range[0] != node._range[1]:
panicWithCallStack("VHDL OCTET STRING (in %s) must have a fixed SIZE constraint !" % node.Location()) # pragma: no cover
for i in range(0, node._range[-1]):
lines.append("{\n")
lines.append(" unsigned char tmp;\n")
#lines.append(" ZestSC1ReadRegister(g_Handle, BASE_ADDR + %s, &tmp);\n" % hex(register + i))
lines.append(" %s.arr[%d] = tmp;\n" % (destVar, i))
lines.append("}\n")
if isSequenceVariable(node):
lines.append("%s.nCount = %s;\n" % (destVar, node._range[-1]))
srcVHDL[0] += node._range[-1]
return lines
def MapEnumerated(self, srcVHDL: List[int], destVar: str, _: AsnEnumerated, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
register = srcVHDL[0] + srcVHDL[1]
lines = [] # type: List[str]
lines.append("{\n")
lines.append(" unsigned char tmp;\n")
#lines.append(" ZestSC1ReadRegister(g_Handle, BASE_ADDR + %s, &tmp);\n" % hex(register))
lines.append(" %s = tmp;\n" % destVar)
lines.append("}\n")
srcVHDL[0] += 1
return lines
def MapSequence(self, srcVHDL: List[int], destVar: str, node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
lines = [] # type: List[str]
for child in node._members:
lines.extend(
self.Map(
srcVHDL,
destVar + "." + self.CleanName(child[0]),
child[1],
leafTypeDict,
names))
return lines
def MapSet(self, srcVHDL: List[int], destVar: str, node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
return self.MapSequence(srcVHDL, destVar, node, leafTypeDict, names) # pragma: nocover
def MapChoice(self, srcVHDL: List[int], destVar: str, node: AsnChoice, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
register = srcVHDL[0] + srcVHDL[1]
lines = [] # type: List[str]
childNo = 0
lines.append("{\n")
lines.append(" unsigned char choiceIdx = 0;\n")
#lines.append(" ZestSC1ReadRegister(g_Handle, BASE_ADDR + %s, &choiceIdx);\n" % hex(register))
if len(node._members) > 255:
panic("Up to 255 different CHOICEs can be supported (%s)" % node.Location()) # pragma: no cover
for child in node._members:
childNo += 1
lines.append(" %sif (choiceIdx == %d) {\n" % (self.maybeElse(childNo), childNo))
lines.extend(
[' ' + x
for x in self.Map(
srcVHDL,
destVar + ".u." + self.CleanName(child[0]),
child[1],
leafTypeDict,
names)])
lines.append(" %s.kind = %s;\n" % (destVar, self.CleanName(child[2])))
lines.append(" }\n")
lines.append("}\n")
srcVHDL[0] += 1
return lines
def MapSequenceOf(self, srcVHDL: List[int], destVar: str, node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
if not node._range:
panicWithCallStack("need a SIZE constraint or else we can't generate C code (%s)!\n" % node.Location()) # pragma: no cover
if len(node._range) > 1 and node._range[0] != node._range[1]:
panicWithCallStack("Must have a fixed SIZE constraint (in %s) for VHDL code!" % node.Location()) # pragma: no cover
lines = [] # type: List[str]
for i in range(0, node._range[-1]):
lines.extend(
self.Map(
srcVHDL,
destVar + ".arr[%d]" % i,
node._containedType,
leafTypeDict,
names))
if isSequenceVariable(node):
lines.append("%s.nCount = %s;\n" % (destVar, node._range[-1]))
return lines
def MapSetOf(self, srcVHDL: List[int], destVar: str, node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
return self.MapSequenceOf(srcVHDL, destVar, node, leafTypeDict, names) # pragma: nocover
# pylint: disable=no-self-use
class FromASN1SCCtoVHDL(RecursiveMapperGeneric[str, List[int]]): # pylint: disable=invalid-sequence-index
def MapInteger(self, srcVar: str, dstVHDL: List[int], _: AsnInt, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
register = dstVHDL[0] + dstVHDL[1]
lines = [] # type: List[str]
lines.append("{\n")
lines.append(" unsigned char tmp, i;\n")
lines.append(" asn1SccSint val = %s;\n" % srcVar)
lines.append(" for(i=0; i<sizeof(asn1SccSint); i++) {\n")
lines.append(" tmp = val & 0xFF;\n")
#lines.append(" ZestSC1WriteRegister(g_Handle, BASE_ADDR + %s + i, tmp);\n" % hex(register))
lines.append(" val >>= 8;\n")
lines.append(" }\n")
lines.append("}\n")
dstVHDL[0] += 8
return lines
def MapReal(self, dummy: str, _: List[int], node: AsnReal, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
panicWithCallStack("REALs (%s) cannot be used for synthesizeable VHDL" % node.Location()) # pragma: no cover
def MapBoolean(self, srcVar: str, dstVHDL: List[int], _: AsnBool, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
register = dstVHDL[0] + dstVHDL[1]
lines = [] # type: List[str]
lines.append("{\n")
lines.append(" unsigned char tmp = %s;\n" % srcVar)
#lines.append(" ZestSC1WriteRegister(g_Handle, BASE_ADDR + %s, tmp);\n" % hex(register))
lines.append("}\n")
dstVHDL[0] += 1
return lines
def MapOctetString(self, srcVar: str, dstVHDL: List[int], node: AsnOctetString, _: AST_Leaftypes, __: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
if not node._range:
panicWithCallStack("OCTET STRING (in %s) must have a SIZE constraint inside ASN.1,\nor else we can't generate C code!" % node.Location()) # pragma: no cover
if isSequenceVariable(node):
panicWithCallStack("VHDL OCTET STRING (in %s) must have a fixed SIZE constraint !" % node.Location()) # pragma: no cover
register = dstVHDL[0] + dstVHDL[1]
limit = sourceSequenceLimit(node, srcVar)
lines = [] # type: List[str]
for i in range(0, node._range[-1]):
lines.append("{\n")
lines.append(" unsigned char tmp;\n")
if isSequenceVariable(node):
lines.append(" if (%s >= %d)\n" % (limit, i + 1))
lines.append(" tmp = %s.arr[%d];\n" % (srcVar, i))
lines.append(" else\n")
lines.append(" tmp = 0;\n")
else:
lines.append(" tmp = %s.arr[%d];\n" % (srcVar, i))
#lines.append(" ZestSC1WriteRegister(g_Handle, BASE_ADDR + %s + %d, tmp);\n" % (hex(register), i))
lines.append("}\n")
dstVHDL[0] += node._range[-1]
return lines
def MapEnumerated(self, srcVar: str, dstVHDL: List[int], node: AsnEnumerated, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
if None in [x[1] for x in node._members]:
panicWithCallStack("an ENUMERATED must have integer values! (%s)" % node.Location()) # pragma: no cover
register = dstVHDL[0] + dstVHDL[1]
lines = [] # type: List[str]
lines.append("{\n")
lines.append(" unsigned char tmp = %s;\n" % srcVar)
#lines.append(" ZestSC1WriteRegister(g_Handle, BASE_ADDR + %s, tmp);\n" % hex(register))
lines.append("}\n")
dstVHDL[0] += 1
return lines
def MapSequence(self, srcVar: str, dstVHDL: List[int], node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
lines = [] # type: List[str]
for child in node._members:
lines.extend(
self.Map(
srcVar + "." + self.CleanName(child[0]),
dstVHDL,
child[1],
leafTypeDict,
names))
return lines
def MapSet(self, srcVar: str, dstVHDL: List[int], node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
return self.MapSequence(srcVar, dstVHDL, node, leafTypeDict, names) # pragma: nocover
def MapChoice(self, srcVar: str, dstVHDL: List[int], node: AsnChoice, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
register = dstVHDL[0] + dstVHDL[1]
lines = [] # type: List[str]
childNo = 0
if len(node._members) > 255:
panic("Up to 255 different CHOICEs can be supported (%s)" % node.Location()) # pragma: no cover
for child in node._members:
childNo += 1
lines.append("%sif (%s.kind == %s) {\n" % (self.maybeElse(childNo), srcVar, self.CleanName(child[2])))
lines.append(" unsigned char tmp = %d;\n" % childNo)
#lines.append(" ZestSC1WriteRegister(g_Handle, BASE_ADDR + %s, tmp);\n" % hex(register))
lines.extend(
[' ' + x
for x in self.Map(
srcVar + ".u." + self.CleanName(child[0]),
dstVHDL,
child[1],
leafTypeDict,
names)])
lines.append("}\n")
dstVHDL[0] += 1
return lines
def MapSequenceOf(self, srcVar: str, dstVHDL: List[int], node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
if not node._range:
panicWithCallStack("need a SIZE constraint or else we can't generate C code (%s)!\n" % node.Location()) # pragma: no cover
if len(node._range) > 1 and node._range[0] != node._range[1]:
panicWithCallStack("Must have a fixed SIZE constraint (in %s) for VHDL code!" % node.Location()) # pragma: no cover
# isMappedToPrimitive = IsElementMappedToPrimitive(node, names)
lines = [] # type: List[str]
for i in range(0, node._range[-1]):
lines.extend(self.Map(
srcVar + ".arr[%d]" % i,
dstVHDL,
node._containedType,
leafTypeDict,
names))
return lines
def MapSetOf(self, srcVar: str, dstVHDL: List[int], node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
return self.MapSequenceOf(srcVar, dstVHDL, node, leafTypeDict, names)
class VHDLGlueGenerator(SynchronousToolGlueGeneratorGeneric[List[int], List[int]]): # pylint: disable=invalid-sequence-index
def Version(self) -> None:
print("Code generator: " + "$Id: vhdl_B_mapper.py 1754 2009-12-26 13:02:45Z ttsiodras $") # pragma: no cover
def FromToolToASN1SCC(self) -> RecursiveMapperGeneric[List[int], str]: # pylint: disable=invalid-sequence-index
return FromVHDLToASN1SCC()
def FromASN1SCCtoTool(self) -> RecursiveMapperGeneric[str, List[int]]: # pylint: disable=invalid-sequence-index
return FromASN1SCCtoVHDL()
# def HeadersOnStartup(self, modelingLanguage, asnFile, subProgram, subProgramImplementation, outputDir, maybeFVname):
def HeadersOnStartup(self, unused_modelingLanguage: str, unused_asnFile: str, unused_subProgram: ApLevelContainer, unused_subProgramImplementation: str, unused_outputDir: str, unused_maybeFVname: str) -> None:
self.C_SourceFile.write("#include \"%s.h\" // Space certified compiler generated\n" % self.asn_name)
self.C_SourceFile.write('''
#include "C_ASN1_Types.h"
#ifndef STATIC
#define STATIC
#endif
#define BASE_ADDR 0x2000
#ifdef _WIN32
// For testing under the Redmond OS
static unsigned int bswap32(unsigned int x)
{
return ((x << 24) & 0xff000000 ) |
((x << 8) & 0x00ff0000 ) |
((x >> 8) & 0x0000ff00 ) |
((x >> 24) & 0x000000ff );
}
static long long bswap64(long long x)
{
unsigned *p = (unsigned*)(void *)&x;
unsigned t;
t = bswap32(p[0]);
p[0] = bswap32(p[1]);
p[1] = t;
return x;
}
#define __builtin_bswap64 bswap64
#endif
static void ErrorHandler(
const char *Function,
const char *Msg)
{
printf("**** TASTE - Function %s returned an error\\n \\"%s\\"\\n\\n", Function, Msg);
exit(1);
}
''')
# self.g_FVname = subProgram._id
# def SourceVar(self, nodeTypename, encoding, node, subProgram, subProgramImplementation, param, leafTypeDict, names):
def SourceVar(self, unused_nodeTypename: str, unused_encoding: str, unused_node: AsnNode, subProgram: ApLevelContainer, unused_subProgramImplementation: str, param: Param, unused_leafTypeDict: AST_Leaftypes, unused_names: AST_Lookup) -> List[int]: # pylint: disable=invalid-sequence-index
if isinstance(param._sourceElement, AadlPort):
srcVHDL = [0, VHDL_Circuit.lookupSP[subProgram._id]._paramOffset[param._id]] # pragma: no cover
elif isinstance(param._sourceElement, AadlParameter):
srcVHDL = [0, VHDL_Circuit.lookupSP[subProgram._id]._paramOffset[param._id]]
else: # pragma: no cover
panicWithCallStack("%s not supported (yet?)\n" % str(param._sourceElement)) # pragma: no cover
return srcVHDL
# def TargetVar(self, nodeTypename, encoding, node, subProgram, subProgramImplementation, param, leafTypeDict, names):
def TargetVar(self, unused_nodeTypename: str, unused_encoding: str, unused_node: AsnNode, subProgram: ApLevelContainer, unused_subProgramImplementation: str, param: Param, unused_leafTypeDict: AST_Leaftypes, unused_names: AST_Lookup) -> List[int]: # pylint: disable=invalid-sequence-index
if isinstance(param._sourceElement, AadlPort):
dstVHDL = [0, VHDL_Circuit.lookupSP[subProgram._id]._paramOffset[param._id]] # pragma: no cover
elif isinstance(param._sourceElement, AadlParameter):
dstVHDL = [0, VHDL_Circuit.lookupSP[subProgram._id]._paramOffset[param._id]]
else: # pragma: no cover
panicWithCallStack("%s not supported (yet?)\n" % str(param._sourceElement)) # pragma: no cover
return dstVHDL
# def InitializeBlock(self, modelingLanguage, asnFile, sp, subProgramImplementation, maybeFVname):
def InitializeBlock(self, unused_modelingLanguage: str, unused_asnFile: str, unused_sp: ApLevelContainer, unused_subProgramImplementation: str, unused_maybeFVname: str) -> None:
self.C_SourceFile.write(''' /*ZESTSC1_HANDLE Handle = (ZESTSC1_HANDLE) NULL;
ZestSC1RegisterErrorHandler(ErrorHandler);
if (g_Handle == (ZESTSC1_HANDLE) NULL) {
static unsigned int Count;
static unsigned int NumCards;
static unsigned long CardIDs[256];
static unsigned long SerialNumbers[256];
static ZESTSC1_FPGA_TYPE FPGATypes[256];
ZestSC1CountCards((unsigned long*)&NumCards, CardIDs, SerialNumbers, FPGATypes);
if (NumCards==0) {
printf("No cards in the system\\n");
exit(1);
}
ZestSC1OpenCard(CardIDs[0], &Handle);
g_Handle = Handle;
if (FPGATypes[0]==ZESTSC1_XC3S1000) {
ZestSC1ConfigureFromFile(g_Handle, "TASTE.bit");
} else {
puts("Only for XC3S1000");
exit(1);
}
ZestSC1SetSignalDirection(g_Handle, 0xf);
''')
self.C_SourceFile.write(" }*/\n")
# def ExecuteBlock(self, modelingLanguage, asnFile, sp, subProgramImplementation, maybeFVname):
def ExecuteBlock(self, unused_modelingLanguage: str, unused_asnFile: str, sp: ApLevelContainer, unused_subProgramImplementation: str, unused_maybeFVname: str) -> None:
self.C_SourceFile.write(" unsigned char flag = 0;\n\n")
self.C_SourceFile.write(" // Now that the parameters are passed inside the FPGA, run the processing logic\n")
#self.C_SourceFile.write(" ZestSC1WriteRegister(g_Handle, BASE_ADDR + %s, (unsigned char)1);\n" %
# hex(int(VHDL_Circuit.lookupSP[sp._id]._offset)))
self.C_SourceFile.write(" while (!flag) {\n")
self.C_SourceFile.write(" // Wait for processing logic to complete\n")
#self.C_SourceFile.write(" ZestSC1ReadRegister(g_Handle, BASE_ADDR + %s, &flag);\n" %
# hex(int(VHDL_Circuit.lookupSP[sp._id]._offset)))
self.C_SourceFile.write(" }\n\n")
# pylint: disable=no-self-use
class MapASN1ToVHDLCircuit(RecursiveMapperGeneric[str, str]):
def MapInteger(self, direction: str, dstVHDL: str, node: AsnInt, _: AST_Leaftypes, __: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
if not node._range:
panicWithCallStack("INTEGERs need explicit ranges when generating VHDL code... (%s)" % node.Location()) # pragma: no cover
bits = math.log(max(abs(x) for x in node._range) + 1, 2)
bits += bits if node._range[0] < 0 else 0
return [dstVHDL + ' : ' + direction + ('std_logic_vector(63 downto 0); -- ASSERT uses 64 bit INTEGERs (optimal would be %d bits)' % bits)]
def MapReal(self, _: str, __: str, node: AsnReal, ___: AST_Leaftypes, dummy: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
panic("The VHDL mapper can't work with REALs (synthesizeable circuits!) (%s)" % node.Location()) # pragma: no cover
def MapBoolean(self, direction: str, dstVHDL: str, _: AsnBool, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
return [dstVHDL + ' : ' + direction + 'std_logic;']
def MapOctetString(self, direction: str, dstVHDL: str, node: AsnOctetString, _: AST_Leaftypes, __: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
if not node._range:
panicWithCallStack("OCTET STRING (in %s) must have a SIZE constraint inside ASN.1,\nor else we can't generate C code!" % node.Location()) # pragma: no cover
if len(node._range) > 1 and node._range[0] != node._range[1]:
panicWithCallStack("VHDL OCTET STRING (in %s) must have a fixed SIZE constraint !" % node.Location()) # pragma: no cover
maxlen = len(str(node._range[-1]))
lines = [] # type: List[str]
for i in range(node._range[-1]):
lines.append(dstVHDL + ('_elem_%0*d: ' % (maxlen, i)) + direction + 'std_logic_vector(7 downto 0);')
return lines
def MapEnumerated(self, direction: str, dstVHDL: str, _: AsnEnumerated, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
return [dstVHDL + ' : ' + direction + 'std_logic_vector(7 downto 0);']
def MapSequence(self, direction: str, dstVHDL: str, node: Union[AsnSequenceOrSet, AsnChoice], leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
lines = [] # type: List[str]
for x in node._members:
lines.extend(self.Map(direction, dstVHDL + "_" + CleanName(x[0]), x[1], leafTypeDict, names))
return lines
def MapSet(self, direction: str, dstVHDL: str, node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
return self.MapSequence(direction, dstVHDL, node, leafTypeDict, names) # pragma: nocover
def MapChoice(self, direction: str, dstVHDL: str, node: AsnChoice, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
lines = [] # type: List[str]
lines.append(dstVHDL + '_choiceIdx : ' + direction + 'std_logic_vector(7 downto 0);')
lines.extend(self.MapSequence(direction, dstVHDL, node, leafTypeDict, names))
return lines
def MapSequenceOf(self, direction: str, dstVHDL: str, node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]: # pylint: disable=invalid-sequence-index
if not node._range:
panicWithCallStack("For VHDL, a SIZE constraint is mandatory (%s)!\n" % node.Location()) # pragma: no cover
if len(node._range) > 1 and node._range[0] != node._range[1]: