org.pshdl.model.simulation.codegenerator.CCodeGenerator.java Source code

Java tutorial

Introduction

Here is the source code for org.pshdl.model.simulation.codegenerator.CCodeGenerator.java

Source

/**
 * PSHDL is a library and (trans-)compiler for PSHDL input. It generates
 *     output suitable for implementation or simulation of it.
 * 
 *     Copyright (C) 2013 Karsten Becker (feedback (at) pshdl (dot) org)
 * 
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 *     This License does not grant permission to use the trade names, trademarks,
 *     service marks, or product names of the Licensor, except as required for
 *     reasonable and customary use in describing the origin of the Work.
 * 
 * Contributors:
 *     Karsten Becker - initial API and implementation
 */
package org.pshdl.model.simulation.codegenerator;

import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.eclipse.xtext.xbase.lib.StringExtensions;
import org.pshdl.interpreter.ExecutableModel;
import org.pshdl.interpreter.Frame;
import org.pshdl.interpreter.IHDLInterpreterFactory;
import org.pshdl.interpreter.InternalInformation;
import org.pshdl.interpreter.NativeRunner;
import org.pshdl.interpreter.VariableInformation;
import org.pshdl.interpreter.utils.Instruction;
import org.pshdl.model.simulation.ITypeOuptutProvider;
import org.pshdl.model.simulation.SimulationTransformationExtension;
import org.pshdl.model.simulation.codegenerator.CCodeGeneratorParameter;
import org.pshdl.model.simulation.codegenerator.CommonCodeGenerator;
import org.pshdl.model.simulation.codegenerator.CommonCompilerExtension;
import org.pshdl.model.types.builtIn.busses.memorymodel.BusAccess;
import org.pshdl.model.types.builtIn.busses.memorymodel.Definition;
import org.pshdl.model.types.builtIn.busses.memorymodel.MemoryModel;
import org.pshdl.model.types.builtIn.busses.memorymodel.Row;
import org.pshdl.model.types.builtIn.busses.memorymodel.Unit;
import org.pshdl.model.types.builtIn.busses.memorymodel.v4.MemoryModelAST;
import org.pshdl.model.utils.PSAbstractCompiler;
import org.pshdl.model.utils.services.AuxiliaryContent;
import org.pshdl.model.utils.services.IOutputProvider;
import org.pshdl.model.validation.Problem;

@SuppressWarnings("all")
public class CCodeGenerator extends CommonCodeGenerator implements ITypeOuptutProvider {
    private CommonCompilerExtension cce;

    private boolean hasPow = false;

    public static String COMPILER = "/usr/bin/clang";

    public CCodeGenerator() {
    }

    public CCodeGenerator(final CCodeGeneratorParameter parameter) {
        super(parameter);
        CommonCompilerExtension _commonCompilerExtension = new CommonCompilerExtension(this.em, 64);
        this.cce = _commonCompilerExtension;
    }

    public IHDLInterpreterFactory<NativeRunner> createInterpreter(final File tempDir) {
        try {
            final File testCFile = new File(tempDir, "test.c");
            String _generateMainCode = this.generateMainCode();
            Files.write(_generateMainCode, testCFile, StandardCharsets.UTF_8);
            final File testRunner = new File(tempDir, "runner.c");
            final InputStream runnerStream = CCodeGenerator.class
                    .getResourceAsStream("/org/pshdl/model/simulation/includes/runner.c");
            final FileOutputStream fos = new FileOutputStream(testRunner);
            try {
                ByteStreams.copy(runnerStream, fos);
            } finally {
                runnerStream.close();
                fos.close();
            }
            final File executable = new File(tempDir, "testExec");
            this.writeAuxiliaryContents(tempDir);
            String _absolutePath = tempDir.getAbsolutePath();
            String _absolutePath_1 = testCFile.getAbsolutePath();
            String _absolutePath_2 = testRunner.getAbsolutePath();
            String _absolutePath_3 = executable.getAbsolutePath();
            final ProcessBuilder builder = new ProcessBuilder(CCodeGenerator.COMPILER, "-I", _absolutePath, "-O3",
                    _absolutePath_1, _absolutePath_2, "-o", _absolutePath_3);
            ProcessBuilder _directory = builder.directory(tempDir);
            ProcessBuilder _inheritIO = _directory.inheritIO();
            final Process process = _inheritIO.start();
            process.waitFor();
            int _exitValue = process.exitValue();
            boolean _notEquals = (_exitValue != 0);
            if (_notEquals) {
                throw new RuntimeException("Process did not terminate with 0");
            }
            return new IHDLInterpreterFactory<NativeRunner>() {
                public NativeRunner newInstance() {
                    try {
                        String _absolutePath = executable.getAbsolutePath();
                        final ProcessBuilder execBuilder = new ProcessBuilder(_absolutePath);
                        ProcessBuilder _directory = execBuilder.directory(tempDir);
                        ProcessBuilder _redirectErrorStream = _directory.redirectErrorStream(true);
                        final Process testExec = _redirectErrorStream.start();
                        InputStream _inputStream = testExec.getInputStream();
                        OutputStream _outputStream = testExec.getOutputStream();
                        String _absolutePath_1 = executable.getAbsolutePath();
                        return new NativeRunner(_inputStream, _outputStream, CCodeGenerator.this.em, testExec, 5,
                                _absolutePath_1);
                    } catch (Throwable _e) {
                        throw Exceptions.sneakyThrow(_e);
                    }
                }
            };
        } catch (Throwable _e) {
            throw Exceptions.sneakyThrow(_e);
        }
    }

    protected CharSequence applyRegUpdates() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("updateRegs();");
        return _builder;
    }

    protected CharSequence assignArrayInit(final VariableInformation hvar, final BigInteger initValue,
            final EnumSet<CommonCodeGenerator.Attributes> attributes) {
        StringConcatenation _builder = new StringConcatenation();
        CharSequence _fieldName = this.fieldName(hvar, attributes);
        _builder.append(_fieldName, "");
        _builder.append("[");
        int _arraySize = this.getArraySize(hvar);
        _builder.append(_arraySize, "");
        _builder.append("];");
        return _builder;
    }

    protected CharSequence arrayInit(final VariableInformation varInfo, final BigInteger zero,
            final EnumSet<CommonCodeGenerator.Attributes> attributes) {
        throw new UnsupportedOperationException("TODO: auto-generated method stub");
    }

    protected CharSequence callStage(final int stage, final boolean constant) {
        StringConcatenation _builder = new StringConcatenation();
        CharSequence _stageMethodName = this.stageMethodName(stage, constant);
        _builder.append(_stageMethodName, "");
        _builder.append("();");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence checkRegupdates() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("regUpdatePos!=0");
        return _builder;
    }

    protected CharSequence clearRegUpdates() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("regUpdatePos=0;");
        return _builder;
    }

    protected CharSequence fieldType(final VariableInformation varInfo,
            final EnumSet<CommonCodeGenerator.Attributes> attributes) {
        boolean _isBoolean = this.isBoolean(varInfo, attributes);
        if (_isBoolean) {
            return "bool";
        }
        return "uint64_t";
    }

    protected CharSequence justDeclare(final VariableInformation varInfo,
            final EnumSet<CommonCodeGenerator.Attributes> attributes) {
        StringConcatenation _builder = new StringConcatenation();
        CharSequence _fieldName = this.fieldName(varInfo, attributes);
        _builder.append(_fieldName, "");
        {
            boolean _isArray = this.isArray(varInfo);
            if (_isArray) {
                _builder.append("[");
                int _arraySize = this.getArraySize(varInfo);
                _builder.append(_arraySize, "");
                _builder.append("]");
            }
        }
        _builder.append(";");
        return _builder;
    }

    protected CharSequence footer() {
        StringConcatenation _builder = new StringConcatenation();
        CharSequence _helperMethods = this.helperMethods();
        _builder.append(_helperMethods, "");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence postFieldDeclarations() {
        StringConcatenation _builder = new StringConcatenation();
        {
            if (this.hasClock) {
                _builder.newLineIfNotEmpty();
                _builder.append("static bool skipEdge(uint64_t local) {");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("uint64_t dc = local >> 16l;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("// Register was updated in previous delta cylce, that is ok");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("if (dc < deltaCycle)");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("return false;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("// Register was updated in this delta cycle but it is the same eps,");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("// that is ok as well");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("if ((dc == deltaCycle) && ((local & 0xFFFF) == epsCycle))");
                _builder.newLine();
                _builder.append("\t\t");
                _builder.append("return false;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("// Don\'t update");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("return true;");
                _builder.newLine();
                _builder.append("}");
                _builder.newLine();
                CharSequence _copyRegs = this.copyRegs();
                _builder.append(_copyRegs, "");
                _builder.newLineIfNotEmpty();
            }
        }
        return _builder;
    }

    protected CharSequence functionFooter(final Frame frame) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("}");
        _builder.newLine();
        return _builder;
    }

    protected CharSequence functionHeader(final Frame frame) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("static void ");
        CharSequence _frameName = this.getFrameName(frame);
        _builder.append(_frameName, "");
        _builder.append("() {");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence header() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("#include <stdint.h>");
        _builder.newLine();
        _builder.append("#include <stdbool.h>");
        _builder.newLine();
        _builder.append("#include <string.h>");
        _builder.newLine();
        _builder.append("#include \"pshdl_generic_sim.h\"");
        _builder.newLine();
        _builder.append("#include \"");
        String _headerName = this.headerName();
        _builder.append(_headerName, "");
        _builder.append(".h\"");
        _builder.newLineIfNotEmpty();
        _builder.newLine();
        {
            if (this.hasClock) {
                _builder.append("/// Don\'t use this");
                _builder.newLine();
                _builder.append("typedef struct regUpdate {");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("int internal;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("int offset;");
                _builder.newLine();
                _builder.append("\t");
                _builder.append("uint64_t fillValue;");
                _builder.newLine();
                _builder.append("} regUpdate_t;");
                _builder.newLine();
                _builder.newLine();
                _builder.append("static regUpdate_t regUpdates[");
                int _maxRegUpdates = this.maxRegUpdates();
                _builder.append(_maxRegUpdates, "");
                _builder.append("];");
                _builder.newLineIfNotEmpty();
                _builder.append("static int regUpdatePos=0;");
                _builder.newLine();
                _builder.newLine();
            }
        }
        _builder.newLine();
        return _builder;
    }

    protected CharSequence copyRegs() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("static void updateRegs() {");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("int i;");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("for (i=0;i<regUpdatePos; i++) {");
        _builder.newLine();
        _builder.append("\t\t");
        _builder.append("regUpdate_t reg=regUpdates[i];");
        _builder.newLine();
        _builder.append("\t\t");
        _builder.append("switch (reg.internal) {");
        _builder.newLine();
        _builder.append("\t\t\t");
        CharSequence _updateRegCases = this.updateRegCases();
        _builder.append(_updateRegCases, "\t\t\t");
        _builder.newLineIfNotEmpty();
        _builder.append("\t\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        return _builder;
    }

    public static int hash(final String str) {
        int hash = (-2128831035);
        final byte[] bytes = str.getBytes(StandardCharsets.ISO_8859_1);
        for (final byte b : bytes) {
            {
                int _bitwiseXor = (hash ^ b);
                hash = _bitwiseXor;
                hash = (hash * 16777619);
            }
        }
        return hash;
    }

    protected CharSequence runMethodsFooter(final boolean constant) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("}");
        _builder.newLine();
        return _builder;
    }

    protected CharSequence runMethodsHeader(final boolean constant) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("void ");
        {
            if ((!constant)) {
                _builder.append("pshdl_sim_run");
            } else {
                _builder.append("pshdl_sim_initConstants");
            }
        }
        _builder.append("() {");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence scheduleShadowReg(final InternalInformation outputInternal, final CharSequence last,
            final CharSequence cpyName, final CharSequence offset, final boolean force,
            final CharSequence fillValue) {
        StringConcatenation _builder = new StringConcatenation();
        {
            if ((!force)) {
                _builder.append("if (");
                _builder.append(cpyName, "");
                _builder.append("!=");
                _builder.append(last, "");
                _builder.append(")");
                _builder.newLineIfNotEmpty();
                CharSequence _indent = this.indent();
                _builder.append(_indent, "");
                _builder.append("\t");
            }
        }
        _builder.append("{");
        _builder.newLineIfNotEmpty();
        CharSequence _indent_1 = this.indent();
        _builder.append(_indent_1, "");
        _builder.append("\t\tstatic regUpdate_t reg;");
        _builder.newLineIfNotEmpty();
        CharSequence _indent_2 = this.indent();
        _builder.append(_indent_2, "");
        _builder.append("\t\treg.internal=");
        int _varIdx = this.getVarIdx(outputInternal);
        _builder.append(_varIdx, "");
        _builder.append(";");
        _builder.newLineIfNotEmpty();
        CharSequence _indent_3 = this.indent();
        _builder.append(_indent_3, "");
        _builder.append("\t\treg.offset=(int)");
        _builder.append(offset, "");
        _builder.append(";");
        _builder.newLineIfNotEmpty();
        CharSequence _indent_4 = this.indent();
        _builder.append(_indent_4, "");
        _builder.append("\t\treg.fillValue=");
        _builder.append(fillValue, "");
        _builder.append(";");
        _builder.newLineIfNotEmpty();
        CharSequence _indent_5 = this.indent();
        _builder.append(_indent_5, "");
        _builder.append("\t\tregUpdates[regUpdatePos++]=reg;");
        _builder.newLineIfNotEmpty();
        CharSequence _indent_6 = this.indent();
        _builder.append(_indent_6, "");
        _builder.append("\t}");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence stageMethodsFooter(final int stage, final int totalStageCosts, final boolean constant) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("}");
        _builder.newLine();
        return _builder;
    }

    protected CharSequence stageMethodsHeader(final int stage, final int totalStageCosts, final boolean constant) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("static void ");
        CharSequence _stageMethodName = this.stageMethodName(stage, constant);
        _builder.append(_stageMethodName, "");
        _builder.append("(){");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence getCast(final int targetSizeWithType) {
        boolean _isSignedType = this.isSignedType(targetSizeWithType);
        if (_isSignedType) {
            return "(int64_t)";
        }
        return "";
    }

    protected CharSequence twoOp(final Frame.FastInstruction fi, final String op, final int targetSizeWithType,
            final int pos, final int leftOperand, final int rightOperand,
            final EnumSet<CommonCodeGenerator.Attributes> attributes, final boolean doMask) {
        CharSequence _xblockexpression = null;
        {
            final Instruction _switchValue = fi.inst;
            if (_switchValue != null) {
                switch (_switchValue) {
                case sra:
                    StringConcatenation _builder = new StringConcatenation();
                    _builder.append("((int64_t)");
                    String _tempName = this.getTempName(leftOperand, CommonCodeGenerator.NONE);
                    _builder.append(_tempName, "");
                    _builder.append(") >> ");
                    String _tempName_1 = this.getTempName(rightOperand, CommonCodeGenerator.NONE);
                    _builder.append(_tempName_1, "");
                    return this.assignTempVar(targetSizeWithType, pos, attributes, _builder, true);
                case srl:
                    StringConcatenation _builder_1 = new StringConcatenation();
                    String _tempName_2 = this.getTempName(leftOperand, CommonCodeGenerator.NONE);
                    _builder_1.append(_tempName_2, "");
                    _builder_1.append(" >> ");
                    String _tempName_3 = this.getTempName(rightOperand, CommonCodeGenerator.NONE);
                    _builder_1.append(_tempName_3, "");
                    return this.assignTempVar(targetSizeWithType, pos, attributes, _builder_1, true);
                case less:
                    StringConcatenation _builder_2 = new StringConcatenation();
                    _builder_2.append("(int64_t)");
                    String _tempName_4 = this.getTempName(leftOperand, CommonCodeGenerator.NONE);
                    _builder_2.append(_tempName_4, "");
                    _builder_2.append(" < (int64_t)");
                    String _tempName_5 = this.getTempName(rightOperand, CommonCodeGenerator.NONE);
                    _builder_2.append(_tempName_5, "");
                    return this.assignTempVar(targetSizeWithType, pos, attributes, _builder_2, true);
                case less_eq:
                    StringConcatenation _builder_3 = new StringConcatenation();
                    _builder_3.append("(int64_t)");
                    String _tempName_6 = this.getTempName(leftOperand, CommonCodeGenerator.NONE);
                    _builder_3.append(_tempName_6, "");
                    _builder_3.append(" <= (int64_t)");
                    String _tempName_7 = this.getTempName(rightOperand, CommonCodeGenerator.NONE);
                    _builder_3.append(_tempName_7, "");
                    return this.assignTempVar(targetSizeWithType, pos, attributes, _builder_3, true);
                case greater:
                    StringConcatenation _builder_4 = new StringConcatenation();
                    _builder_4.append("(int64_t)");
                    String _tempName_8 = this.getTempName(leftOperand, CommonCodeGenerator.NONE);
                    _builder_4.append(_tempName_8, "");
                    _builder_4.append(" > (int64_t)");
                    String _tempName_9 = this.getTempName(rightOperand, CommonCodeGenerator.NONE);
                    _builder_4.append(_tempName_9, "");
                    return this.assignTempVar(targetSizeWithType, pos, attributes, _builder_4, true);
                case greater_eq:
                    StringConcatenation _builder_5 = new StringConcatenation();
                    _builder_5.append("(int64_t)");
                    String _tempName_10 = this.getTempName(leftOperand, CommonCodeGenerator.NONE);
                    _builder_5.append(_tempName_10, "");
                    _builder_5.append(" >= (int64_t)");
                    String _tempName_11 = this.getTempName(rightOperand, CommonCodeGenerator.NONE);
                    _builder_5.append(_tempName_11, "");
                    return this.assignTempVar(targetSizeWithType, pos, attributes, _builder_5, true);
                default:
                    break;
                }
            }
            _xblockexpression = super.twoOp(fi, op, targetSizeWithType, pos, leftOperand, rightOperand, attributes,
                    doMask);
        }
        return _xblockexpression;
    }

    protected CharSequence copyArray(final VariableInformation varInfo) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("memcpy(");
        EnumSet<CommonCodeGenerator.Attributes> _of = EnumSet.<CommonCodeGenerator.Attributes>of(
                CommonCodeGenerator.Attributes.isPrev);
        CharSequence _idName = this.idName(varInfo, true, _of);
        _builder.append(_idName, "");
        _builder.append(", ");
        CharSequence _idName_1 = this.idName(varInfo, true, CommonCodeGenerator.NONE);
        _builder.append(_idName_1, "");
        _builder.append(", ");
        int _arraySize = this.getArraySize(varInfo);
        _builder.append(_arraySize, "");
        _builder.append(");");
        _builder.newLineIfNotEmpty();
        return _builder;
    }

    protected CharSequence preField(final VariableInformation x,
            final EnumSet<CommonCodeGenerator.Attributes> attributes) {
        StringConcatenation _builder = new StringConcatenation();
        {
            boolean _contains = attributes.contains(CommonCodeGenerator.Attributes.isPublic);
            boolean _not = (!_contains);
            if (_not) {
                _builder.append("static");
            }
        }
        _builder.append(" ");
        return _builder;
    }

    protected CharSequence helperMethods() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("void pshdl_sim_setInput(uint32_t idx, uint64_t value) {");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("pshdl_sim_setInputArray(idx, value, 0);");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.append("void pshdl_sim_setInputArray(uint32_t idx, uint64_t value, uint32_t offset) {");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("switch (idx) {");
        _builder.newLine();
        _builder.append("\t\t");
        EnumSet<CommonCodeGenerator.Attributes> _of = EnumSet.<CommonCodeGenerator.Attributes>of(
                CommonCodeGenerator.Attributes.useArrayOffset);
        CharSequence _setInputCases = this.setInputCases("value", null, _of);
        _builder.append(_setInputCases, "\t\t");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("char* pshdl_sim_getName(uint32_t idx) {");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("switch (idx) {");
        _builder.newLine();
        {
            for (final VariableInformation v : this.em.variables) {
                _builder.append("\t\t");
                _builder.append("case ");
                int _varIdx = this.getVarIdx(v, false);
                _builder.append(_varIdx, "\t\t");
                _builder.append(": return \"");
                _builder.append(v.name, "\t\t");
                _builder.append("\";");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("return 0;");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("static char* jsonDesc=\"");
        String _jSONDescription = this.cce.getJSONDescription();
        _builder.append(_jSONDescription, "");
        _builder.append("\";");
        _builder.newLineIfNotEmpty();
        _builder.append("char* pshdl_sim_getJsonDesc(){");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("return jsonDesc;");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("uint64_t pshdl_sim_getDeltaCycle(){");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("return deltaCycle;");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("uint32_t pshdl_sim_getVarCount(){");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("return ");
        int _size = this.varIdx.size();
        _builder.append(_size, "\t");
        _builder.append(";");
        _builder.newLineIfNotEmpty();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("void pshdl_sim_setDisableEdges(bool enable){");
        _builder.newLine();
        {
            if (this.hasClock) {
                _builder.append("\t");
                _builder.append(CommonCodeGenerator.DISABLE_EDGES.name, "\t");
                _builder.append("=enable;");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("void pshdl_sim_setDisableRegOutputlogic(bool enable){");
        _builder.newLine();
        {
            if (this.hasClock) {
                _builder.append("\t");
                _builder.append(CommonCodeGenerator.DISABLE_REG_OUTPUTLOGIC.name, "\t");
                _builder.append("=enable;");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("static uint32_t hash(char* str){");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("size_t len=strlen(str);");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("uint32_t hash = 2166136261;");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("int i;");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("for (i=0;i<len;i++){");
        _builder.newLine();
        _builder.append("\t   \t");
        _builder.append("hash = hash ^ str[i];");
        _builder.newLine();
        _builder.append("\t   \t");
        _builder.append("hash = hash * 16777619;");
        _builder.newLine();
        _builder.append("\t   ");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("return hash;");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("int pshdl_sim_getIndex(char* name) {");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("uint32_t hashName=hash(name);");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("switch (hashName) {");
        _builder.newLine();
        {
            Map<Integer, List<VariableInformation>> _hashed = this
                    .getHashed(((Iterable<VariableInformation>) Conversions.doWrapArray(this.em.variables)));
            Set<Map.Entry<Integer, List<VariableInformation>>> _entrySet = _hashed.entrySet();
            for (final Map.Entry<Integer, List<VariableInformation>> e : _entrySet) {
                _builder.append("\t\t");
                _builder.append("case ");
                Integer _key = e.getKey();
                CharSequence _constant32Bit = this.constant32Bit((_key).intValue());
                _builder.append(_constant32Bit, "\t\t");
                _builder.append(":");
                _builder.newLineIfNotEmpty();
                {
                    List<VariableInformation> _value = e.getValue();
                    for (final VariableInformation vi : _value) {
                        _builder.append("\t\t");
                        _builder.append("\t");
                        _builder.append("if (strcmp(name, \"");
                        _builder.append(vi.name, "\t\t\t");
                        _builder.append("\") == 0)");
                        _builder.newLineIfNotEmpty();
                        _builder.append("\t\t");
                        _builder.append("\t");
                        _builder.append("\t");
                        _builder.append("return ");
                        int _varIdx_1 = this.getVarIdx(vi, this.purgeAliases);
                        _builder.append(_varIdx_1, "\t\t\t\t");
                        _builder.append(";");
                        _builder.newLineIfNotEmpty();
                    }
                }
                _builder.append("\t\t");
                _builder.append("\t");
                _builder.append("return -1; //so close...");
                _builder.newLine();
            }
        }
        _builder.append("\t");
        _builder.append("default:");
        _builder.newLine();
        _builder.append("\t\t");
        _builder.append("return -1;");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("uint64_t pshdl_sim_getOutput(uint32_t idx) {");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("return pshdl_sim_getOutputArray(idx, 0);");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("uint64_t pshdl_sim_getOutputArray(uint32_t idx, uint32_t offset) {");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("switch (idx) {");
        _builder.newLine();
        _builder.append("\t\t");
        EnumSet<CommonCodeGenerator.Attributes> _of_1 = EnumSet.<CommonCodeGenerator.Attributes>of(
                CommonCodeGenerator.Attributes.useArrayOffset);
        CharSequence _outputCases = this.getOutputCases(null, _of_1);
        _builder.append(_outputCases, "\t\t");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("return 0;");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        {
            if (this.hasPow) {
                _builder.append("static uint64_t pshdl_sim_pow(uint64_t a, uint64_t n){");
                _builder.newLine();
                _builder.append("    ");
                _builder.append("uint64_t result = 1;");
                _builder.newLine();
                _builder.append("    ");
                _builder.append("uint64_t p = a;");
                _builder.newLine();
                _builder.append("    ");
                _builder.append("while (n > 0){");
                _builder.newLine();
                _builder.append("        ");
                _builder.append("if ((n % 2) != 0)");
                _builder.newLine();
                _builder.append("            ");
                _builder.append("result = result * p;");
                _builder.newLine();
                _builder.append("        ");
                _builder.append("p = p * p;");
                _builder.newLine();
                _builder.append("        ");
                _builder.append("n = n / 2;");
                _builder.newLine();
                _builder.append("    ");
                _builder.append("}");
                _builder.newLine();
                _builder.append("    ");
                _builder.append("return result;");
                _builder.newLine();
                _builder.append("}");
                _builder.newLine();
            }
        }
        return _builder;
    }

    public Map<Integer, List<VariableInformation>> getHashed(final Iterable<VariableInformation> informations) {
        final Map<Integer, List<VariableInformation>> res = Maps
                .<Integer, List<VariableInformation>>newLinkedHashMap();
        for (final VariableInformation vi : this.em.variables) {
            {
                final int hashVal = CCodeGenerator.hash(vi.name);
                final List<VariableInformation> list = res.get(Integer.valueOf(hashVal));
                boolean _tripleEquals = (list == null);
                if (_tripleEquals) {
                    ArrayList<VariableInformation> _newArrayList = Lists.<VariableInformation>newArrayList(vi);
                    res.put(Integer.valueOf(hashVal), _newArrayList);
                } else {
                    list.add(vi);
                }
            }
        }
        return res;
    }

    protected CharSequence barrier() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("}");
        _builder.newLine();
        _builder.append("#pragma omp section");
        _builder.newLine();
        _builder.append("{");
        _builder.newLine();
        return _builder;
    }

    protected CharSequence barrierBegin(final int stage, final int totalStageCosts, final boolean createConstant) {
        CharSequence _xblockexpression = null;
        {
            int _indent = this.indent;
            this.indent = (_indent + 2);
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("#pragma omp parallel sections");
            _builder.newLine();
            CharSequence _indent_1 = this.indent();
            _builder.append(_indent_1, "");
            _builder.append("{");
            _builder.newLineIfNotEmpty();
            CharSequence _indent_2 = this.indent();
            _builder.append(_indent_2, "");
            _builder.append("#pragma omp section");
            _builder.newLineIfNotEmpty();
            CharSequence _indent_3 = this.indent();
            _builder.append(_indent_3, "");
            _builder.append("{");
            _builder.newLineIfNotEmpty();
            _xblockexpression = _builder;
        }
        return _xblockexpression;
    }

    protected CharSequence barrierEnd(final int stage, final int totalStageCosts, final boolean createConstant) {
        CharSequence _xblockexpression = null;
        {
            int _indent = this.indent;
            this.indent = (_indent - 2);
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("\t");
            _builder.append("}");
            _builder.newLine();
            CharSequence _indent_1 = this.indent();
            _builder.append(_indent_1, "");
            _builder.append("}");
            _builder.newLineIfNotEmpty();
            _xblockexpression = _builder;
        }
        return _xblockexpression;
    }

    public Iterable<AuxiliaryContent> getAuxiliaryContent() {
        try {
            final InputStream generic_hStream = CCodeGenerator.class
                    .getResourceAsStream("/org/pshdl/model/simulation/includes/pshdl_generic_sim.h");
            try {
                final AuxiliaryContent generic_h = new AuxiliaryContent("pshdl_generic_sim.h", generic_hStream,
                        true);
                String _headerName = this.headerName();
                String _plus = (_headerName + ".h");
                CharSequence _specificHeader = this.getSpecificHeader();
                String _string = _specificHeader.toString();
                final AuxiliaryContent specific_h = new AuxiliaryContent(_plus, _string);
                final ArrayList<AuxiliaryContent> res = Lists.<AuxiliaryContent>newArrayList(generic_h, specific_h);
                final String simEncapsulation = this.generateSimEncapsuation();
                boolean _tripleNotEquals = (simEncapsulation != null);
                if (_tripleNotEquals) {
                    AuxiliaryContent _auxiliaryContent = new AuxiliaryContent("simEncapsulation.c",
                            simEncapsulation);
                    res.add(_auxiliaryContent);
                }
                return res;
            } finally {
                generic_hStream.close();
            }
        } catch (Throwable _e) {
            throw Exceptions.sneakyThrow(_e);
        }
    }

    protected String headerName() {
        CharSequence _idName = this.idName(this.em.moduleName, false, CommonCodeGenerator.NONE);
        String _plus = ("pshdl_" + _idName);
        return (_plus + "_sim");
    }

    protected CharSequence getSpecificHeader() {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("/**");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @file");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @brief Provides access to all fields and their index.");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*/");
        _builder.newLine();
        _builder.newLine();
        _builder.append("#ifndef _");
        String _headerName = this.headerName();
        _builder.append(_headerName, "");
        _builder.append("_h_");
        _builder.newLineIfNotEmpty();
        _builder.append("#define _");
        String _headerName_1 = this.headerName();
        _builder.append(_headerName_1, "");
        _builder.append("_h_");
        _builder.newLineIfNotEmpty();
        _builder.append("#include \"pshdl_generic_sim.h\"");
        _builder.newLine();
        _builder.newLine();
        {
            for (final VariableInformation vi : this.em.variables) {
                _builder.append("///Use this index define to access <tt> ");
                String _replaceAll = vi.name.replaceAll("\\@", "\\\\@");
                _builder.append(_replaceAll, "");
                _builder.append(" </tt> via getOutput/setInput methods");
                _builder.newLineIfNotEmpty();
                _builder.append("#define ");
                CharSequence _defineName = this.getDefineName(vi);
                _builder.append(_defineName, "");
                _builder.append(" ");
                int _varIdx = this.getVarIdx(vi, this.purgeAliases);
                _builder.append(_varIdx, "");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.newLine();
        CharSequence _fieldDeclarations = this.fieldDeclarations(false, false);
        String _string = _fieldDeclarations.toString();
        String[] _split = _string.split("\n");
        final Function1<String, String> _function = new Function1<String, String>() {
            public String apply(final String it) {
                return ("extern" + it);
            }
        };
        List<String> _map = ListExtensions.<String, String>map(((List<String>) Conversions.doWrapArray(_split)),
                _function);
        String _join = IterableExtensions.join(_map, "\n");
        _builder.append(_join, "");
        _builder.newLineIfNotEmpty();
        _builder.newLine();
        _builder.append("#endif");
        _builder.newLine();
        return _builder;
    }

    public String generateSimEncapsuation() {
        final Unit unit = this.getUnit(this.em);
        boolean _tripleEquals = (unit == null);
        if (_tripleEquals) {
            return null;
        }
        List<Row> _buildRows = MemoryModel.buildRows(unit);
        return this.generateSimEncapsuation(unit, _buildRows);
    }

    public Unit getUnit(final ExecutableModel model) {
        try {
            Unit unit = null;
            final Splitter annoSplitter = Splitter.on(SimulationTransformationExtension.ANNO_VALUE_SEP);
            boolean _tripleNotEquals = (this.em.annotations != null);
            if (_tripleNotEquals) {
                for (final String a : this.em.annotations) {
                    boolean _startsWith = a.startsWith("busDescription");
                    if (_startsWith) {
                        Splitter _limit = annoSplitter.limit(2);
                        Iterable<String> _split = _limit.split(a);
                        final String value = IterableExtensions.<String>last(_split);
                        LinkedHashSet<Problem> _linkedHashSet = new LinkedHashSet<Problem>();
                        Unit _parseUnit = MemoryModelAST.parseUnit(value, _linkedHashSet, 0);
                        unit = _parseUnit;
                    }
                }
            }
            return unit;
        } catch (Throwable _e) {
            throw Exceptions.sneakyThrow(_e);
        }
    }

    @Extension
    private BusAccess ba = new BusAccess();

    private String generateSimEncapsuation(final Unit unit, final Iterable<Row> rows) {
        final Set<String> varNames = new LinkedHashSet<String>();
        final Procedure1<Row> _function = new Procedure1<Row>() {
            public void apply(final Row it) {
                List<Definition> _allDefs = CCodeGenerator.this.ba.allDefs(it);
                final Function1<Definition, Boolean> _function = new Function1<Definition, Boolean>() {
                    public Boolean apply(final Definition it) {
                        return Boolean.valueOf((it.type != Definition.Type.UNUSED));
                    }
                };
                Iterable<Definition> _filter = IterableExtensions.<Definition>filter(_allDefs, _function);
                final Procedure1<Definition> _function_1 = new Procedure1<Definition>() {
                    public void apply(final Definition it) {
                        String _name = it.getName();
                        varNames.add(_name);
                    }
                };
                IterableExtensions.<Definition>forEach(_filter, _function_1);
            }
        };
        IterableExtensions.<Row>forEach(rows, _function);
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("/**");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @file");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @brief  Provides methods for simulating accessing to the memory registers");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* This file is a substitue for the BusAccess.c file that is used to access real memory.");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* For each type of row there are methods for setting/getting the values");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* either directly, or as a struct. A memory map overview has been");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* generated into BusMap.html.");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*/");
        _builder.newLine();
        _builder.newLine();
        _builder.append("#include <stdint.h>");
        _builder.newLine();
        _builder.append("#include <stdbool.h>");
        _builder.newLine();
        _builder.append("#include \"BusAccess.h\"");
        _builder.newLine();
        _builder.append("#include \"BusStdDefinitions.h\"");
        _builder.newLine();
        _builder.append("#include \"");
        String _headerName = this.headerName();
        _builder.append(_headerName, "");
        _builder.append(".h\"");
        _builder.newLineIfNotEmpty();
        _builder.newLine();
        _builder.append("/**");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* This method provides a null implementation of the warning functionality. You");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* can use it to provide your own error handling, or you can use the implementation");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* provided in BusPrint.h");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*/");
        _builder.newLine();
        _builder.append(
                "static void defaultWarn(warningType_t t, uint64_t value, char *def, char *row, char *msg){");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("warnFunc_p warn=defaultWarn;");
        _builder.newLine();
        _builder.newLine();
        _builder.append("/**");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* This methods allows the user to set a custom warning function. Usually this is used");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* in conjunction with the implementation provided in BusPrint.h.");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @param warnFunction the new function to use for error reporting");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* Example Usage:");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @code");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*    #include \"BusPrint.h\"");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*    setWarn(defaultPrintfWarn);");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @endcode");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*/");
        _builder.newLine();
        _builder.append("void setWarn(warnFunc_p warnFunction){");
        _builder.newLine();
        _builder.append("    ");
        _builder.append("warn=warnFunction;");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("///The index of the Clock that is toggled for each setting");
        _builder.newLine();
        _builder.append("#define ");
        _builder.append("busclk_idx", "");
        _builder.append(" ");
        int _busIndex = this.getBusIndex();
        _builder.append(_busIndex, "");
        _builder.newLineIfNotEmpty();
        _builder.newLine();
        String res = _builder.toString();
        final LinkedHashSet<String> checkedRows = new LinkedHashSet<String>();
        final LinkedHashMap<String, Integer> rowCounts = new LinkedHashMap<String, Integer>();
        for (final Row row : rows) {
            {
                final Integer idx = rowCounts.get(row.name);
                boolean _tripleEquals = (idx == null);
                if (_tripleEquals) {
                    rowCounts.put(row.name, Integer.valueOf(1));
                } else {
                    rowCounts.put(row.name, Integer.valueOf(((idx).intValue() + 1)));
                }
            }
        }
        for (final Row row_1 : rows) {
            boolean _contains = checkedRows.contains(row_1.name);
            boolean _not = (!_contains);
            if (_not) {
                boolean _hasWriteDefs = this.ba.hasWriteDefs(row_1);
                if (_hasWriteDefs) {
                    Integer _get = rowCounts.get(row_1.name);
                    CharSequence _simSetter = this.simSetter(row_1, (_get).intValue());
                    String _plus = (res + _simSetter);
                    res = _plus;
                }
                Integer _get_1 = rowCounts.get(row_1.name);
                CharSequence _simGetter = this.simGetter(row_1, (_get_1).intValue());
                String _plus_1 = (res + _simGetter);
                res = _plus_1;
                checkedRows.add(row_1.name);
            }
        }
        return res;
    }

    protected int getBusIndex() {
        final Integer pclk = this.varIdx.get((this.em.moduleName + ".PCLK"));
        boolean _tripleEquals = (pclk == null);
        if (_tripleEquals) {
            return (this.varIdx.get((this.em.moduleName + ".Bus2IP_Clk"))).intValue();
        }
        return (pclk).intValue();
    }

    protected CharSequence getDefineName(final VariableInformation vi) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("PSHDL_SIM_");
        CharSequence _idName = this.idName(vi, true, CommonCodeGenerator.NONE);
        String _string = _idName.toString();
        String _upperCase = _string.toUpperCase();
        _builder.append(_upperCase, "");
        return _builder;
    }

    protected CharSequence getDefineNameString(final String s) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("PSHDL_SIM_");
        CharSequence _idName = this.idName(((this.em.moduleName + ".") + s), true, CommonCodeGenerator.NONE);
        String _string = _idName.toString();
        String _upperCase = _string.toUpperCase();
        _builder.append(_upperCase, "");
        return _builder;
    }

    protected CharSequence simGetter(final Row row, final int rowCount) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("/**");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* Directly retrieve the fields of row ");
        _builder.append(row.name, " ");
        _builder.append(".");
        _builder.newLineIfNotEmpty();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append(
                "* @param base a (volatile) pointer to the memory offset at which the IP core can be found in memory. For simulation this parameter is ignored.");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @param index the row that you want to access. ");
        {
            if ((rowCount == 1)) {
                _builder.append("The only valid index is 0");
            } else {
                _builder.append("Valid values are 0..");
                _builder.append((rowCount - 1), " ");
            }
        }
        _builder.newLineIfNotEmpty();
        {
            List<Definition> _allDefs = this.ba.allDefs(row);
            for (final Definition d : _allDefs) {
                _builder.append(" ");
                _builder.append("* @param ");
                _builder.append(d.name, " ");
                _builder.append(" the value of ");
                _builder.append(d.name, " ");
                _builder.append(" will be written into the memory of this pointer.");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @retval 1  Successfully retrieved the values");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @retval 0  Something went wrong (invalid index for example)");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*/");
        _builder.newLine();
        _builder.append("int get");
        String _firstUpper = StringExtensions.toFirstUpper(row.name);
        _builder.append(_firstUpper, "");
        _builder.append("Direct(uint32_t *base, uint32_t index");
        {
            List<Definition> _allDefs_1 = this.ba.allDefs(row);
            for (final Definition definition : _allDefs_1) {
                String _parameter = this.ba.getParameter(row, definition, true);
                _builder.append(_parameter, "");
            }
        }
        _builder.append("){");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("uint32_t offset[1]={index};");
        _builder.newLine();
        {
            List<Definition> _allDefs_2 = this.ba.allDefs(row);
            for (final Definition d_1 : _allDefs_2) {
                _builder.append("\t");
                _builder.append("*");
                String _varName = this.ba.getVarName(row, d_1);
                _builder.append(_varName, "\t");
                _builder.append("=(");
                CharSequence _busType = this.ba.getBusType(d_1);
                _builder.append(_busType, "\t");
                _builder.append(")pshdl_sim_getOutputArray(");
                CharSequence _defineNameString = this.getDefineNameString(d_1.name);
                _builder.append(_defineNameString, "\t");
                _builder.append(", offset);");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("\t");
        _builder.append("return 1;");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("/**");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* Retrieve the fields of row ");
        _builder.append(row.name, " ");
        _builder.append(" into the struct.");
        _builder.newLineIfNotEmpty();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append(
                "* @param base a (volatile) pointer to the memory offset at which the IP core can be found in memory. For simulation this parameter is ignored.");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @param index the row that you want to access. ");
        {
            if ((rowCount == 1)) {
                _builder.append("The only valid index is 0");
            } else {
                _builder.append("Valid values are 0..");
                _builder.append((rowCount - 1), " ");
            }
        }
        _builder.newLineIfNotEmpty();
        _builder.append(" ");
        _builder.append("* @param result the values of this row will be written into the struct");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @retval 1  Successfully retrieved the values");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @retval 0  Something went wrong (invalid index for example)");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*/");
        _builder.newLine();
        _builder.append("int get");
        String _firstUpper_1 = StringExtensions.toFirstUpper(row.name);
        _builder.append(_firstUpper_1, "");
        _builder.append("(uint32_t *base, uint32_t index, ");
        _builder.append(row.name, "");
        _builder.append("_t *result){");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("return get");
        String _firstUpper_2 = StringExtensions.toFirstUpper(row.name);
        _builder.append(_firstUpper_2, "\t");
        _builder.append("Direct(base, index");
        {
            List<Definition> _allDefs_3 = this.ba.allDefs(row);
            for (final Definition d_2 : _allDefs_3) {
                _builder.append(", &result->");
                String _varNameIndex = this.ba.getVarNameIndex(row, d_2);
                _builder.append(_varNameIndex, "\t");
            }
        }
        _builder.append(");");
        _builder.newLineIfNotEmpty();
        _builder.append("}");
        _builder.newLine();
        return _builder;
    }

    protected CharSequence simSetter(final Row row, final int rowCount) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("/**");
        _builder.newLine();
        _builder.append(" ");
        _builder.append(
                "* Updates the values in memory from the struct. This also advances the simulation by one clock cycle, ");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* unless PSHDL_SIM_NO_BUSCLK_TOGGLE is defined.");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append(
                "* @param base a (volatile) pointer to the memory offset at which the IP core can be found in memory. For simulation this parameter is ignored.");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @param index the row that you want to access. ");
        {
            if ((rowCount == 1)) {
                _builder.append("The only valid index is 0");
            } else {
                _builder.append("Valid values are 0..");
                _builder.append((rowCount - 1), " ");
            }
        }
        _builder.newLineIfNotEmpty();
        {
            List<Definition> _allDefs = this.ba.allDefs(row);
            for (final Definition d : _allDefs) {
                _builder.append(" ");
                _builder.append("* @param ");
                _builder.append(d.name, " ");
                _builder.append(" the value of ");
                _builder.append(d.name, " ");
                _builder.append(" will be written into the register. ");
                StringBuilder _explain = this.ba.explain(d);
                _builder.append(_explain, " ");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @retval 1  Successfully updated the values");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @retval 0  Something went wrong (invalid index or value exceeds its range for example)");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*/");
        _builder.newLine();
        _builder.append("int set");
        String _firstUpper = StringExtensions.toFirstUpper(row.name);
        _builder.append(_firstUpper, "");
        _builder.append("Direct(uint32_t *base, uint32_t index");
        {
            List<Definition> _writeDefs = this.ba.writeDefs(row);
            for (final Definition definition : _writeDefs) {
                String _parameter = this.ba.getParameter(row, definition, false);
                _builder.append(_parameter, "");
            }
        }
        _builder.append("){");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("if (index>");
        _builder.append((rowCount - 1), "\t");
        _builder.append(")");
        _builder.newLineIfNotEmpty();
        _builder.append("\t\t");
        _builder.append("return 0;");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("uint32_t offset[1]={index};");
        _builder.newLine();
        {
            List<Definition> _writeDefs_1 = this.ba.writeDefs(row);
            for (final Definition ne : _writeDefs_1) {
                _builder.append("\t");
                CharSequence _generateConditions = this.ba.generateConditions(row, ne);
                _builder.append(_generateConditions, "\t");
                _builder.newLineIfNotEmpty();
            }
        }
        {
            List<Definition> _writeDefs_2 = this.ba.writeDefs(row);
            for (final Definition d_1 : _writeDefs_2) {
                _builder.append("\t");
                _builder.append("pshdl_sim_setInputArray(");
                CharSequence _defineNameString = this.getDefineNameString(d_1.name);
                _builder.append(_defineNameString, "\t");
                _builder.append(", ");
                _builder.append(d_1.name, "\t");
                _builder.append(", offset);");
                _builder.newLineIfNotEmpty();
            }
        }
        _builder.append("\t");
        _builder.append("#ifndef PSHDL_SIM_NO_BUSCLK_TOGGLE");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("if (!");
        _builder.append(CommonCodeGenerator.DISABLE_EDGES.name, "\t");
        _builder.append(") {");
        _builder.newLineIfNotEmpty();
        _builder.append("\t\t");
        _builder.append("pshdl_sim_setInput(busclk_idx, 0);");
        _builder.newLine();
        _builder.append("\t\t");
        _builder.append("pshdl_sim_run();");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("}");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("pshdl_sim_setInput(busclk_idx, 1);");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("pshdl_sim_run();");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("#endif");
        _builder.newLine();
        _builder.append("\t");
        _builder.append("return 1;");
        _builder.newLine();
        _builder.append("}");
        _builder.newLine();
        _builder.newLine();
        _builder.append("/**");
        _builder.newLine();
        _builder.append(" ");
        _builder.append(
                "* Updates the values in memory from the struct. This also advances the simulation by one clock cycle, ");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* unless PSHDL_SIM_NO_BUSCLK_TOGGLE is defined.");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append(
                "* @param base a (volatile) pointer to the memory offset at which the IP core can be found in memory. For simulation this parameter is ignored.");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @param index the row that you want to access. ");
        {
            if ((rowCount == 1)) {
                _builder.append("The only valid index is 0");
            } else {
                _builder.append("Valid values are 0..");
                _builder.append((rowCount - 1), " ");
            }
        }
        _builder.newLineIfNotEmpty();
        _builder.append(" ");
        _builder.append("* @param newVal the values of this row will be written into the struct");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @retval 1  Successfully updated the values");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("* @retval 0  Something went wrong (invalid index or value exceeds range for example)");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*");
        _builder.newLine();
        _builder.append(" ");
        _builder.append("*/");
        _builder.newLine();
        _builder.append("int set");
        String _firstUpper_1 = StringExtensions.toFirstUpper(row.name);
        _builder.append(_firstUpper_1, "");
        _builder.append("(uint32_t *base, uint32_t index, ");
        _builder.append(row.name, "");
        _builder.append("_t *newVal) {");
        _builder.newLineIfNotEmpty();
        _builder.append("\t");
        _builder.append("return set");
        String _firstUpper_2 = StringExtensions.toFirstUpper(row.name);
        _builder.append(_firstUpper_2, "\t");
        _builder.append("Direct(base, index");
        {
            List<Definition> _writeDefs_3 = this.ba.writeDefs(row);
            for (final Definition d_2 : _writeDefs_3) {
                _builder.append(", newVal->");
                String _varNameIndex = this.ba.getVarNameIndex(row, d_2);
                _builder.append(_varNameIndex, "\t");
            }
        }
        _builder.append(");");
        _builder.newLineIfNotEmpty();
        _builder.append("}");
        _builder.newLine();
        return _builder;
    }

    protected CharSequence assignNextTime(final VariableInformation nextTime,
            final CharSequence currentProcessTime) {
        throw new UnsupportedOperationException("TODO: auto-generated method stub");
    }

    protected CharSequence callMethod(final CharSequence methodName, final CharSequence... args) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append(methodName, "");
        _builder.append("(");
        {
            boolean _tripleNotEquals = (args != null);
            if (_tripleNotEquals) {
                {
                    boolean _hasElements = false;
                    for (final CharSequence arg : args) {
                        if (!_hasElements) {
                            _hasElements = true;
                        } else {
                            _builder.appendImmediate(",", "");
                        }
                        _builder.append(arg, "");
                    }
                }
            }
        }
        _builder.append(")");
        return _builder;
    }

    protected CharSequence callRunMethod() {
        throw new UnsupportedOperationException("TODO: auto-generated method stub");
    }

    protected CharSequence checkTestbenchListener() {
        throw new UnsupportedOperationException("TODO: auto-generated method stub");
    }

    protected CharSequence runProcessHeader(final CommonCodeGenerator.ProcessData pd) {
        throw new UnsupportedOperationException("TODO: auto-generated method stub");
    }

    protected CharSequence runTestbenchHeader() {
        throw new UnsupportedOperationException("TODO: auto-generated method stub");
    }

    public String getHookName() {
        return "C";
    }

    public IOutputProvider.MultiOption getUsage() {
        final Options options = new Options();
        return new IOutputProvider.MultiOption(null, null, options);
    }

    public static List<PSAbstractCompiler.CompileResult> doCompile(final Set<Problem> syntaxProblems,
            final CCodeGeneratorParameter parameter) {
        final CCodeGenerator comp = new CCodeGenerator(parameter);
        final List<AuxiliaryContent> sideFiles = Lists.<AuxiliaryContent>newLinkedList();
        Iterable<AuxiliaryContent> _auxiliaryContent = comp.getAuxiliaryContent();
        Iterables.<AuxiliaryContent>addAll(sideFiles, _auxiliaryContent);
        String _generateMainCode = comp.generateMainCode();
        String _string = _generateMainCode.toString();
        String _hookName = comp.getHookName();
        PSAbstractCompiler.CompileResult _compileResult = new PSAbstractCompiler.CompileResult(syntaxProblems,
                _string, parameter.em.moduleName, sideFiles, parameter.em.source, _hookName, true);
        return Lists.<PSAbstractCompiler.CompileResult>newArrayList(_compileResult);
    }

    public List<PSAbstractCompiler.CompileResult> invoke(final CommandLine cli, final ExecutableModel em,
            final Set<Problem> syntaxProblems) throws Exception {
        CCodeGeneratorParameter _cCodeGeneratorParameter = new CCodeGeneratorParameter(em);
        return CCodeGenerator.doCompile(syntaxProblems, _cCodeGeneratorParameter);
    }

    protected CharSequence fillArray(final VariableInformation vi, final CharSequence regFillValue) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("memset(");
        CharSequence _idName = this.idName(vi, true, CommonCodeGenerator.NONE);
        _builder.append(_idName, "");
        _builder.append(", ");
        _builder.append(regFillValue, "");
        _builder.append(", ");
        int _arraySize = this.getArraySize(vi);
        _builder.append(_arraySize, "");
        _builder.append(");");
        return _builder;
    }

    protected CharSequence pow(final Frame.FastInstruction fi, final String op, final int targetSizeWithType,
            final int pos, final int leftOperand, final int rightOperand,
            final EnumSet<CommonCodeGenerator.Attributes> attributes, final boolean doMask) {
        this.hasPow = true;
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("pshdl_sim_pow(");
        String _tempName = this.getTempName(leftOperand, CommonCodeGenerator.NONE);
        _builder.append(_tempName, "");
        _builder.append(", ");
        String _tempName_1 = this.getTempName(rightOperand, CommonCodeGenerator.NONE);
        _builder.append(_tempName_1, "");
        _builder.append(")");
        return this.assignTempVar(targetSizeWithType, pos, CommonCodeGenerator.NONE, _builder, true);
    }
}