Commit f5593123 authored by Tiago Jorge's avatar Tiago Jorge
Browse files

Add draft ZynQZC706 vhdl template and b-mapper.

parent f9a81184
# Company: GMV
# Copyright European Space Agency, 2019-2020
vhd = '''-- Company: GMV
-- Copyright European Space Agency, 2019-2020
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- import needed IPs
entity TASTE is
port (
clk_i : in std_logic; -- System clock
reset_n : in std_logic; -- System RST
-- AXI interface
axii : in axi_slv_in_type;
axio : out axi_slv_out_type;
led_complete : out std_logic;
led_start : out std_logic
);
end TASTE;
architecture arch of TASTE is
-- Circuits for the existing PIs
%(circuits)s
-- Registers for I/O
%(ioregisters)s
-- Signals for start/finish
%(startStopSignals)s
-- Debug signals --
signal led_start_reg : std_logic;
signal led_complete_reg : std_logic;
begin
led_complete <= led_complete_reg;
led_start <= led_start_reg;
-- Implement register write
process (reset_n, clk_i)
begin
if (reset_n='0') then
-- Signals for reset
%(reset)s
led_start_reg <= '0';
led_complete_reg <= '0';
elsif (clk_i'event and clk_i='1') then
%(updateStartCompleteLedRegs)s
-- Update start-stop pulses
%(updateStartStopPulses)s
if (axii.pwrite='1' and axii.psel= '1' and axii.penable = '1') then
case (axii.paddr(15 downto 0)) is
-- Read data
%(readinputdata)s
end case;
end if;
%(setStartSignalsLow)s
end if;
end process;
-- Implement register read
process (axii.paddr, axii.pwrite, axii.psel, %(outputs)s %(completions)s)
begin
axio.prdata <= (others => '0');
if (axii.pwrite='0' and axii.psel= '1') then
case (axii.paddr(15 downto 0)) is
-- Write data
%(writeoutputdata)s
when others => axio.prdata(7 downto 0) <= (others => '0');
end case;
end if;
end process;
-- Connections to the VHDL circuits
%(connectionsToSystemC)s
process(reset_n, clk_i)
begin
if (reset_n='0') then
%(updateCalculationsCompleteReset)s
elsif (clk_i'event and clk_i='1') then
%(updateCalculationsComplete)s
end if;
end process;
end arch;'''
#TODO
makefile = r'''-- Company: GMV
-- Copyright European Space Agency, 2019-2020
'''
per_circuit_vhd = """-- Company: GMV
-- Copyright European Space Agency, 2019-2020
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
%(declaration)s
architecture arch of bambu_%(pi)s is
-- Declare signals
signal CLK : std_logic;
signal RST : std_logic;
signal state : unsigned(1 downto 0);
begin
CLK <= clock_%(pi)s;
RST <= reset_%(pi)s;
-- Possible clock divider
process(CLK, RST)
begin
if (RST='0') then
finish_%(pi)s <= '0'; -- or 1?
state <= "00";
-- outp <= (others => '0');
elsif (CLK'event and CLK='1') then
case state is
when "00" =>
if start_%(pi)s = '1' then
state <= "01";
finish_%(pi)s <= '0';
end if;
when "01" =>
-----------------------------
-- Do your processing here --
-----------------------------
state <= "10";
when "10" =>
finish_%(pi)s <= '1';
state <= "00";
when others =>
state <= "00";
end case;
end if;
end process;
end arch;
"""
# TODO
script = """-- Company: GMV
-- Copyright European Space Agency, 2019-2020
"""
# (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, OutParam, 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: zynqzc706_B_mapper.py 2019-2020 tmsj@gmv $") # 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 += 4 # 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 long long tmp;\n")
lines.append(" unsigned int i;\n")
lines.append(" asn1SccSint val = 0;\n")
lines.append(" for(i=0; i<sizeof(asn1SccSint)/4; i++) {\n")
lines.append(" axi_read(R_AXI_BASEADR + %s + (i*4), &tmp, 4, R_AXI_DSTADR);\n" % hex(register))
lines.append(" tmp >>= 32; // ?\n")
lines.append(" val |= (tmp << (32*i));\n")
lines.append(" }\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, node: 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 int tmp = 0;\n")
lines.append(" axi_read(R_AXI_BASEADR + %s, &tmp, 4, R_AXI_DSTADR);\n" % hex(register))
lines.append(" %s = (asn1SccUint) tmp;\n" % destVar)
lines.append("}\n")
srcVHDL[0] += 4
return lines
def MapOctetString(self, srcVHDL: List[int], destVar: 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("OCTET STRING (in %s) must have a fixed SIZE constraint !" % node.Location()) # pragma: no cover
if isSequenceVariable(node):
panicWithCallStack("OCTET STRING (in %s) must have a fixed SIZE constraint !" % node.Location()) # pragma: no cover
if node._range[-1] % 4 != 0: # TODO
panicWithCallStack("OCTET STRING (in %s) is not a multiple of 4 bytes (this is not yet supported)." % node.Location())
register = srcVHDL[0] + srcVHDL[1]
lines = [] # type: List[str]
lines.append("{\n")
lines.append(" unsigned int tmp, i;\n")
lines.append(" for(i=0; i<%d; i++) {\n" % int(node._range[-1] / 4))
lines.append(" tmp = 0;\n")
lines.append(" axi_read(R_AXI_BASEADR + %s + (i*4), &tmp, 4, R_AXI_DSTADR);\n" % hex(register))
lines.append(" memcpy(%s.arr + (i*4), (unsigned char*)&tmp, sizeof(unsigned int));\n" % destVar)
lines.append(" }\n")
lines.append("}\n")
srcVHDL[0] += node._range[-1]
return lines
def MapEnumerated(self, srcVHDL: List[int], destVar: str, node: 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 int tmp;\n")
lines.append(" axi_read(R_AXI_BASEADR + %s, &tmp, 4, R_AXI_DSTADR);\n" % hex(register))
lines.append(" %s = tmp;\n" % destVar)
lines.append("}\n")
srcVHDL[0] += 4
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
panicWithCallStack("CHOICEs (%s) not yet supported." % node.Location()) # pragma: no cover
register = srcVHDL[0] + srcVHDL[1]
lines = [] # type: List[str]
childNo = 0
lines.append("{\n")
lines.append(" unsigned char choiceIdx = 0;\n")
#lines.append(" ZynQZC706ReadRegister(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 int tmp, i;\n")
lines.append(" asn1SccSint val = %s;\n" % srcVar)
lines.append(" for(i=0; i<sizeof(asn1SccSint)/4; i++) {\n")
lines.append(" tmp = val & 0xFFFFFFFF;\n")
lines.append(" axi_write(R_AXI_BASEADR + %s + (i*4), &tmp, 4, R_AXI_DSTADR);\n" % hex(register))
lines.append(" val >>= 32;\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 int tmp = (unsigned int)%s;\n" % srcVar)
lines.append(" axi_write(R_AXI_BASEADR + %s, &tmp, 4, R_AXI_DSTADR);\n" % hex(register))
lines.append("}\n")
dstVHDL[0] += 4
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("OCTET STRING (in %s) must have a fixed SIZE constraint !" % node.Location()) # pragma: no cover
if node._range[-1] % 4 != 0: # TODO
panicWithCallStack("OCTET STRING (in %s) is not a multiple of 4 bytes (this is not yet supported)." % node.Location())
register = dstVHDL[0] + dstVHDL[1]
lines = [] # type: List[str]
lines.append("{\n")
lines.append(" unsigned int tmp, i;\n")
lines.append(" for(i=0; i<%d; i++) {\n" % int(node._range[-1] / 4))
lines.append(" tmp = 0;\n")
lines.append(" tmp = *(unsigned int*)(%s.arr + (i*4));\n" % srcVar)
lines.append(" axi_write(R_AXI_BASEADR + %s + (i*4), &tmp, 4, R_AXI_DSTADR);\n" % hex(register))
lines.append(" }\n")
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 int tmp = (unsigned int)%s;\n" % srcVar)
lines.append(" axi_write(R_AXI_BASEADR + %s, &tmp, 4, R_AXI_DSTADR);\n" % hex(register))
lines.append("}\n")
dstVHDL[0] += 4
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(" ZynQZC706WriteRegister(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 <stdio.h>
#include <string.h>
#ifndef STATIC
#define STATIC
#endif
#define LOGERRORS
#define LOGWARNINGS