/*
* Copyright (c) 2013, IETR/INSA of Rennes
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the IETR/INSA of Rennes nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
package net.sf.orcc.backends.c.compa;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import net.sf.orcc.backends.c.CBackend;
import net.sf.orcc.backends.c.transform.CBroadcastAdder;
import net.sf.orcc.backends.transform.DisconnectedOutputPortRemoval;
import net.sf.orcc.backends.util.Alignable;
import net.sf.orcc.backends.util.Mapping;
import net.sf.orcc.backends.util.Validator;
import net.sf.orcc.df.Actor;
import net.sf.orcc.df.Instance;
import net.sf.orcc.df.Network;
import net.sf.orcc.df.transform.ArgumentEvaluator;
import net.sf.orcc.df.transform.Instantiator;
import net.sf.orcc.df.transform.NetworkFlattener;
import net.sf.orcc.df.transform.TypeResizer;
import net.sf.orcc.df.transform.UnitImporter;
import net.sf.orcc.df.util.XdfWriter;
import net.sf.orcc.ir.transform.RenameTransformation;
import net.sf.orcc.util.FilesManager;
import net.sf.orcc.util.OrccLogger;
import net.sf.orcc.util.Result;
/**
* C backend targeting Xilinx Zynq platforms
*
* @author Antoine Lorence
* @author Yaset Oliva
*/
public class COMPABackend extends CBackend {
final boolean printTop = false;
private NetworkPrinter netPrinter;
private InstancePrinter childrenPrinter;
private CMakePrinter cmakePrinter;
private Mapping computedMapping;
public COMPABackend() {
netPrinter = new NetworkPrinter();
childrenPrinter = new InstancePrinter();
cmakePrinter = new CMakePrinter();
}
@Override
protected void doInitializeOptions() {
// Configure the options used in code generation
netPrinter.setOptions(getOptions());
childrenPrinter.setOptions(getOptions(), printTop);
// Create the directory tree
new File(outputPath, "src").mkdir();
srcPath = new File(outputPath, "src").toString();
// Configure the map used in RenameTransformation
final Map<String, String> renameMap = new HashMap<String, String>();
renameMap.put("abs", "abs_replaced");
renameMap.put("getw", "getw_replaced");
renameMap.put("exit", "exit_replaced");
renameMap.put("index", "index_replaced");
renameMap.put("log2", "log2_replaced");
renameMap.put("max", "max_replaced");
renameMap.put("min", "min_replaced");
renameMap.put("select", "select_replaced");
renameMap.put("OUT", "OUT_REPLACED");
renameMap.put("IN", "IN_REPLACED");
renameMap.put("SIZE", "SIZE_REPLACED");
// -----------------------------------------------------
// Transformations that will be applied on the Network
// -----------------------------------------------------
networkTransfos.add(new Instantiator(true));
networkTransfos.add(new NetworkFlattener());
networkTransfos.add(new UnitImporter());
networkTransfos.add(new UnitImporter());
networkTransfos.add(new CBroadcastAdder());
networkTransfos.add(new ArgumentEvaluator());
// networkTransfos.add(new XdfExtender());
// -----------------------------------------------------
// Transformations that will be applied on Actors
// -----------------------------------------------------
childrenTransfos.add(new TypeResizer(true, false, true, false));
childrenTransfos.add(new RenameTransformation(renameMap));
childrenTransfos.add(new DisconnectedOutputPortRemoval());
}
@Override
protected Result doLibrariesExtraction() {
OrccLogger.trace("Export libraries sources");
Result result = FilesManager.extract("/runtime/COMPA/libs", outputPath);
result.merge(FilesManager.extract("/runtime/COMPA/cmake", outputPath));
return result;
}
@Override
protected void doValidate(Network network) {
Validator.checkTopLevel(network);
Validator.checkMinimalFifoSize(network, fifoSize);
network.computeTemplateMaps();
// Compute the actor mapping
computedMapping = new Mapping(network, mapping);
// update "vectorizable" information
Alignable.setAlignability(network);
}
@Override
protected Result doGenerateNetwork(Network network) {
final Result result = Result.newInstance();
// Configure the network
netPrinter.setNetwork(network);
netPrinter.setOptions(getOptions());
result.merge(FilesManager.writeFile(netPrinter.getFifoContent(), outputPath
+ "/libs/orcc/include", "fifoAllocations.h"));
if (printTop) {
result.merge(FilesManager.writeFile(netPrinter.getContent(),
srcPath, network.getSimpleName() + ".c"));
}
return result;
}
@Override
protected Result doAdditionalGeneration(Network network) {
final Result result = Result.newInstance();
OrccLogger.traceln("Print flattened and attributed network...");
new XdfWriter().write(new File(srcPath), network);
OrccLogger.traceln("Print network meta-informations...");
result.merge(FilesManager.writeFile(computedMapping.getContentFile(),
srcPath, network.getSimpleName() + ".xcf"));
return result;
}
@Override
protected Result doGenerateInstance(Instance instance) {
final Result result = Result.newInstance();
childrenPrinter.setInstance(instance);
if (printTop) {
result.merge(FilesManager.writeFile(childrenPrinter.getContent(),
srcPath, instance.getName() + ".c"));
result.merge(FilesManager.writeFile(
childrenPrinter.getTestContent(), srcPath,
instance.getName() + "_test.h"));
} else {
String childPath = outputPath + File.separator + instance.getSimpleName();
result.merge(FilesManager.writeFile(childrenPrinter.getContent(),
childPath, instance.getName() + ".c"));
result.merge(FilesManager.writeFile(
childrenPrinter.getTestContent(), childPath,
instance.getName() + "_test.h"));
result.merge(FilesManager.writeFile(
cmakePrinter.rootCMakeContent(instance.getSimpleName()),
childPath, "CMakeLists.txt"));
}
return result;
}
@Override
protected Result doGenerateActor(Actor actor) {
final Result result = Result.newInstance();
childrenPrinter.setActor(actor);
if (printTop) {
result.merge(FilesManager.writeFile(childrenPrinter.getContent(),
srcPath, actor.getName() + ".c"));
result.merge(FilesManager.writeFile(
childrenPrinter.getTestContent(), srcPath, actor.getName()
+ "_test.h"));
} else {
String childPath = outputPath + File.separator + actor.getSimpleName();
result.merge(FilesManager.writeFile(childrenPrinter.getContent(),
childPath, actor.getName() + ".c"));
result.merge(FilesManager.writeFile(
childrenPrinter.getTestContent(), childPath,
actor.getName() + "_test.h"));
result.merge(FilesManager.writeFile(
cmakePrinter.rootCMakeContent(actor.getSimpleName()),
childPath, "CMakeLists.txt"));
}
return result;
}
}