107 lines
4.2 KiB
Matlab
107 lines
4.2 KiB
Matlab
% Copyright 2024 Volvo Car Corporation
|
|
% Licensed under Apache 2.0.
|
|
|
|
function inPorts = parseInPorts(root_subsystem)
|
|
% parseInPorts Parse which block data shall be stored per block.
|
|
%
|
|
% See also parseModelInfo
|
|
|
|
% TODO: Some models have more tha one inport per variable. Should we
|
|
% check for this?
|
|
inPorts = struct();
|
|
info = {'description', 'type', 'unit', 'offset', 'lsb', 'min', 'max', 'class', 'width'};
|
|
|
|
normalInPorts = parseTLInPorts(root_subsystem, info);
|
|
normalFields = fieldnames(normalInPorts);
|
|
for idx = 1:length(normalFields)
|
|
inPorts.(normalFields{idx}) = normalInPorts.(normalFields{idx});
|
|
end
|
|
|
|
busInPorts = parseTLBusInPorts(root_subsystem, info);
|
|
busFields = fieldnames(busInPorts);
|
|
for idx = 1:length(busFields)
|
|
inPorts.(busFields{idx}) = busInPorts.(busFields{idx});
|
|
end
|
|
end
|
|
|
|
function inPorts = parseTLInPorts(root_subsystem, info)
|
|
in_ports = find_system(root_subsystem, 'FindAll', 'on', 'SearchDepth', 1, 'MaskType', 'TL_Inport');
|
|
inPorts = struct();
|
|
tmpInport = struct();
|
|
for i=1:length(in_ports)
|
|
inp = in_ports(i);
|
|
consumerBlks = getConsumerBlocks(inp);
|
|
codeSwTmp = {};
|
|
for j=1:length(consumerBlks)
|
|
consBlk = consumerBlks(j);
|
|
codeSwTmp{j} = getCodeSwitches(consBlk);
|
|
end
|
|
%TODO: Do a better reduction of code switch logics right now only duplicates are removed.
|
|
codeSw = removeConfigDuplicates(codeSwTmp);
|
|
tmpInport.handle = getPath(inp);
|
|
tmpInport.name = strtrim(getName(inp));
|
|
tmpInport.configs = codeSw;
|
|
for idx=1:length(info)
|
|
tmpValue = tl_get(inp, ['output.' info{idx}]);
|
|
tmpInport.(info{idx}) = getProperValue(inp, tmpValue);
|
|
end
|
|
|
|
tmpInport = modifyEnumStructField(tmpInport);
|
|
|
|
if strcmp(tmpInport.name, fields(inPorts))
|
|
printf('Warning: inport %s is already defined', tmpInport.name);
|
|
printf(' signal will not be added again to the input signal');
|
|
else
|
|
inPorts.(tmpInport.name) = tmpInport;
|
|
end
|
|
end
|
|
end
|
|
|
|
function busInPorts = parseTLBusInPorts(root_subsystem, info)
|
|
foundBusInPorts = find_system(root_subsystem, 'FindAll', 'on', 'SearchDepth', 1, 'MaskType', 'TL_BusInport');
|
|
busInPorts = struct();
|
|
tmpInport = struct();
|
|
for idx=1:length(foundBusInPorts)
|
|
inp = foundBusInPorts(idx);
|
|
for idy = 1:tl_get(inp, 'numoutputs')
|
|
tmpInport.handle = getPath(inp);
|
|
tmpInport.name = tl_get(inp, ['output(' num2str(idy) ').signalname']);
|
|
tmpInport.configs = getBusConfig(inp);
|
|
for idz=1:length(info)
|
|
tmpValue = tl_get(inp, ['output(' num2str(idy) ').' info{idz}]);
|
|
tmpInport.(info{idz}) = getProperValue(inp, tmpValue);
|
|
end
|
|
% TODO Fix later, cannot set width in TL_BusInport:s due to "matrix unified output".
|
|
tmpInport.width = 1;
|
|
|
|
tmpInport = modifyEnumStructField(tmpInport);
|
|
|
|
busParts = split(tmpInport.name, '.');
|
|
if ~ismember(busParts{1}, fields(busInPorts))
|
|
busInPorts.(busParts{1}) = struct();
|
|
busInPorts.(busParts{1}).(busParts{2}) = tmpInport;
|
|
elseif ~ismember(busParts{2}, fields(busInPorts.(busParts{1})))
|
|
busInPorts.(busParts{1}).(busParts{2}) = tmpInport;
|
|
else
|
|
printf('Warning: inport %s is already defined', tmpInport.name);
|
|
printf(' signal will not be added again to the input signal');
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function busConfig = getBusConfig(inp)
|
|
consumerBlks = getConsumerBlocks(inp);
|
|
codeSwTmp = {};
|
|
for idx=1:length(consumerBlks)
|
|
consBlk = consumerBlks(idx);
|
|
codeSwTmp{idx} = getCodeSwitches(consBlk);
|
|
end
|
|
%TODO: Do a better reduction of code switch logics right now only duplicates are removed.
|
|
busConfig = removeConfigDuplicates(codeSwTmp);
|
|
isValidConfig = iscell(busConfig) && length(busConfig) == 1 && strcmp(busConfig{1}, 'all');
|
|
if ~isValidConfig
|
|
error('Code switching bus inports is currently not supported. All bus inport destinations must be active.')
|
|
end
|
|
end
|