package org.pshdl.model.simulation.codegenerator;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
import java.math.BigInteger;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.pshdl.interpreter.ExecutableModel;
import org.pshdl.interpreter.Frame;
import org.pshdl.interpreter.InternalInformation;
import org.pshdl.interpreter.VariableInformation;
import org.pshdl.interpreter.utils.Instruction;
import org.pshdl.model.simulation.codegenerator.CommonCodeGenerator;
import org.pshdl.model.simulation.codegenerator.CommonCodeGeneratorParameter;
@SuppressWarnings("all")
public class VerilogCodeGenerator extends CommonCodeGenerator {
private Multimap<Integer, Frame> writes = LinkedListMultimap.<Integer, Frame>create();
private Multimap<Integer, VariableInformation> posClocks = LinkedHashMultimap.<Integer, VariableInformation>create();
private Multimap<Integer, VariableInformation> negClocks = LinkedHashMultimap.<Integer, VariableInformation>create();
public VerilogCodeGenerator(final ExecutableModel model) {
super(new CommonCodeGeneratorParameter(model, (-1), Integer.MAX_VALUE, false));
for (final Frame f : this.em.frames) {
for (final int outputId : f.outputIds) {
{
final InternalInformation internal = this.em.internals[outputId];
if ((f.edgeNegDepRes != (-1))) {
this.negClocks.put(Integer.valueOf(f.edgeNegDepRes), internal.info);
}
if ((f.edgePosDepRes != (-1))) {
this.posClocks.put(Integer.valueOf(f.edgePosDepRes), internal.info);
}
this.writes.put(Integer.valueOf(outputId), f);
}
}
}
}
public String generateMainCode() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("`timescale 1ns/1ps");
_builder.newLine();
_builder.append("module ");
CharSequence _idName = this.idName(this.em.moduleName, false, CommonCodeGenerator.NONE);
_builder.append(_idName, "");
_builder.append("(");
_builder.newLineIfNotEmpty();
{
final Function1<VariableInformation, Boolean> _function = new Function1<VariableInformation, Boolean>() {
public Boolean apply(final VariableInformation it) {
return Boolean.valueOf((it.dir != VariableInformation.Direction.INTERNAL));
}
};
Iterable<VariableInformation> _filter = IterableExtensions.<VariableInformation>filter(((Iterable<VariableInformation>)Conversions.doWrapArray(this.em.variables)), _function);
boolean _hasElements = false;
for(final VariableInformation vi : _filter) {
if (!_hasElements) {
_hasElements = true;
} else {
_builder.appendImmediate(",", "\t");
}
_builder.append("\t");
CharSequence _idName_1 = this.idName(vi, true, CommonCodeGenerator.NONE);
_builder.append(_idName_1, "\t");
_builder.newLineIfNotEmpty();
}
}
_builder.append(");");
_builder.newLine();
{
for(final VariableInformation vi_1 : this.em.variables) {
String _declaration = this.declaration(vi_1, CommonCodeGenerator.NONE);
_builder.append(_declaration, "");
_builder.newLineIfNotEmpty();
{
if (vi_1.isRegister) {
String _declaration_1 = this.declaration(vi_1, CommonCodeGenerator.SHADOWREG);
_builder.append(_declaration_1, "");
_builder.newLineIfNotEmpty();
}
}
_builder.newLine();
}
}
_builder.newLine();
{
Set<Integer> _keySet = this.posClocks.keySet();
for(final Integer ii : _keySet) {
_builder.append("always @(posedge ");
InternalInformation _get = this.em.internals[(ii).intValue()];
CharSequence _idName_2 = this.idName(_get.info, true, CommonCodeGenerator.NONE);
_builder.append(_idName_2, "");
_builder.append(")");
_builder.newLineIfNotEmpty();
_builder.append("begin");
_builder.newLine();
{
Collection<VariableInformation> _get_1 = this.posClocks.get(ii);
for(final VariableInformation vi_2 : _get_1) {
_builder.append("\t");
CharSequence _idName_3 = this.idName(vi_2, true, CommonCodeGenerator.NONE);
_builder.append(_idName_3, "\t");
_builder.append(" <= ");
CharSequence _idName_4 = this.idName(vi_2, true, CommonCodeGenerator.SHADOWREG);
_builder.append(_idName_4, "\t");
_builder.append(";");
_builder.newLineIfNotEmpty();
}
}
_builder.append("end");
_builder.newLine();
}
}
_builder.newLine();
{
Set<Integer> _keySet_1 = this.negClocks.keySet();
for(final Integer ii_1 : _keySet_1) {
_builder.append("always @(negedge ");
InternalInformation _get_2 = this.em.internals[(ii_1).intValue()];
CharSequence _idName_5 = this.idName(_get_2.info, true, CommonCodeGenerator.NONE);
_builder.append(_idName_5, "");
_builder.append(")");
_builder.newLineIfNotEmpty();
_builder.append("begin");
_builder.newLine();
{
Collection<VariableInformation> _get_3 = this.negClocks.get(ii_1);
for(final VariableInformation vi_3 : _get_3) {
_builder.append("\t");
CharSequence _idName_6 = this.idName(vi_3, true, CommonCodeGenerator.NONE);
_builder.append(_idName_6, "\t");
_builder.append(" <= ");
CharSequence _idName_7 = this.idName(vi_3, true, CommonCodeGenerator.SHADOWREG);
_builder.append(_idName_7, "\t");
_builder.append(";");
_builder.newLineIfNotEmpty();
}
}
_builder.append("end");
_builder.newLine();
}
}
_builder.newLine();
{
Set<Integer> _keySet_2 = this.writes.keySet();
for(final Integer ii_2 : _keySet_2) {
CharSequence _generateWriteProcess = this.generateWriteProcess(ii_2);
_builder.append(_generateWriteProcess, "");
_builder.newLineIfNotEmpty();
}
}
_builder.newLine();
_builder.append("endmodule;");
_builder.newLine();
return _builder.toString();
}
public CharSequence generateWriteProcess(final Integer internal) {
StringConcatenation _builder = new StringConcatenation();
_builder.append("always @(");
Collection<Frame> _get = this.writes.get(internal);
final Function1<Frame, Set<CharSequence>> _function = new Function1<Frame, Set<CharSequence>>() {
public Set<CharSequence> apply(final Frame it) {
final Function1<Integer, CharSequence> _function = new Function1<Integer, CharSequence>() {
public CharSequence apply(final Integer it) {
return VerilogCodeGenerator.this.sensitiviyName(it);
}
};
List<CharSequence> _map = ListExtensions.<Integer, CharSequence>map(((List<Integer>)Conversions.doWrapArray(it.internalDependencies)), _function);
return IterableExtensions.<CharSequence>toSet(_map);
}
};
Iterable<Set<CharSequence>> _map = IterableExtensions.<Frame, Set<CharSequence>>map(_get, _function);
Iterable<CharSequence> _flatten = Iterables.<CharSequence>concat(_map);
String _join = IterableExtensions.join(_flatten, " or ");
_builder.append(_join, "");
_builder.append(")");
_builder.newLineIfNotEmpty();
_builder.append("begin");
_builder.newLine();
{
Collection<Frame> _get_1 = this.writes.get(internal);
for(final Frame f : _get_1) {
_builder.append("\t");
final Function1<Integer, String> _function_1 = new Function1<Integer, String>() {
public String apply(final Integer it) {
CharSequence _sensitiviyName = VerilogCodeGenerator.this.sensitiviyName(it);
return (_sensitiviyName + " == 0");
}
};
List<String> _map_1 = ListExtensions.<Integer, String>map(((List<Integer>)Conversions.doWrapArray(f.predNegDepRes)), _function_1);
final Function1<Integer, CharSequence> _function_2 = new Function1<Integer, CharSequence>() {
public CharSequence apply(final Integer it) {
return VerilogCodeGenerator.this.sensitiviyName(it);
}
};
List<CharSequence> _map_2 = ListExtensions.<Integer, CharSequence>map(((List<Integer>)Conversions.doWrapArray(f.predPosDepRes)), _function_2);
final Iterable<CharSequence> predSet = Iterables.<CharSequence>concat(_map_1, _map_2);
_builder.newLineIfNotEmpty();
{
boolean _isEmpty = IterableExtensions.isEmpty(predSet);
boolean _not = (!_isEmpty);
if (_not) {
_builder.append("\t");
_builder.append("if (");
String _join_1 = IterableExtensions.join(predSet, " && ");
_builder.append(_join_1, "\t");
_builder.append(")");
_builder.newLineIfNotEmpty();
_builder.append("\t");
_builder.append(" ");
_builder.append("begin");
_builder.newLine();
_builder.append("\t");
CharSequence _frameExecution = this.frameExecution(f);
_builder.append(_frameExecution, "\t");
_builder.newLineIfNotEmpty();
_builder.append("\t");
_builder.append(" ");
_builder.append("end");
_builder.newLine();
} else {
_builder.append("\t");
CharSequence _frameExecution_1 = this.frameExecution(f);
_builder.append(_frameExecution_1, "\t");
_builder.newLineIfNotEmpty();
}
}
}
}
_builder.append("end");
_builder.newLine();
return _builder;
}
protected CharSequence updatePrediateTimestamp(final Stack<Integer> arr, final InternalInformation outputInternal) {
StringConcatenation _builder = new StringConcatenation();
return _builder;
}
protected CharSequence fixupValue(final CharSequence assignValue, final int targetSizeWithType, final boolean doMask) {
return assignValue;
}
protected StringBuilder toCastExpression(final Frame.FastInstruction exec, final Frame frame, final int pos, final int a, final int b, final Stack<Integer> arr, final int arrPos) {
final StringBuilder sb = new StringBuilder();
final String tempName = this.getTempName(a, CommonCodeGenerator.NONE);
final Instruction _switchValue = exec.inst;
if (_switchValue != null) {
switch (_switchValue) {
case bitAccessSingle:
StringConcatenation _builder = new StringConcatenation();
_builder.append(tempName, "");
_builder.append("[");
_builder.append(exec.arg1, "");
_builder.append("]");
StringBuilder _assignTempVar = this.assignTempVar(2, pos, CommonCodeGenerator.NONE, _builder, false);
sb.append(_assignTempVar);
break;
case bitAccessSingleRange:
final int highBit = exec.arg1;
final int lowBit = exec.arg2;
final int targetSize = ((highBit - lowBit) + 1);
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(tempName, "");
_builder_1.append("[");
_builder_1.append(exec.arg1, "");
_builder_1.append(":");
_builder_1.append(exec.arg2, "");
_builder_1.append("]");
StringBuilder _assignTempVar_1 = this.assignTempVar((targetSize << 1), pos, CommonCodeGenerator.NONE, _builder_1, false);
sb.append(_assignTempVar_1);
break;
case cast_int:
int _min = Math.min(exec.arg1, exec.arg2);
int _doubleLessThan = (_min << 1);
int _bitwiseOr = (_doubleLessThan | 1);
StringConcatenation _builder_2 = new StringConcatenation();
_builder_2.append(tempName, "");
_builder_2.append("[");
int _min_1 = Math.min(exec.arg1, exec.arg2);
int _minus = (_min_1 - 1);
_builder_2.append(_minus, "");
_builder_2.append(":0]");
StringBuilder _assignTempVar_2 = this.assignTempVar(_bitwiseOr, pos, CommonCodeGenerator.NONE, _builder_2, false);
sb.append(_assignTempVar_2);
break;
case cast_uint:
int _min_2 = Math.min(exec.arg1, exec.arg2);
int _doubleLessThan_1 = (_min_2 << 1);
StringConcatenation _builder_3 = new StringConcatenation();
_builder_3.append(tempName, "");
_builder_3.append("[");
int _min_3 = Math.min(exec.arg1, exec.arg2);
int _minus_1 = (_min_3 - 1);
_builder_3.append(_minus_1, "");
_builder_3.append(":0]");
StringBuilder _assignTempVar_3 = this.assignTempVar(_doubleLessThan_1, pos, CommonCodeGenerator.NONE, _builder_3, false);
sb.append(_assignTempVar_3);
break;
default:
throw new IllegalArgumentException((("Did not instruction:" + exec) + " here"));
}
} else {
throw new IllegalArgumentException((("Did not instruction:" + exec) + " here"));
}
return sb;
}
protected CharSequence toEdgeExpression(final Frame.FastInstruction exec, final Frame frame, final int pos, final int a, final int b, final Stack<Integer> arr, final int arrPos) {
StringConcatenation _builder = new StringConcatenation();
return _builder;
}
protected CharSequence handlePredicates(final Set<Integer> handledPredicates, final boolean positive, final int[] predicates) {
StringConcatenation _builder = new StringConcatenation();
return _builder;
}
protected CharSequence updatePredicateFreshness(final int pred, final boolean positive) {
StringConcatenation _builder = new StringConcatenation();
return _builder;
}
protected CharSequence updateHandledClk(final int edgeDepRes, final boolean posEdge) {
StringConcatenation _builder = new StringConcatenation();
return _builder;
}
protected CharSequence updateEdge(final int edgeDepRes, final boolean posEdge) {
StringConcatenation _builder = new StringConcatenation();
return _builder;
}
public CharSequence sensitiviyName(final Integer internal) {
InternalInformation _get = this.em.internals[(internal).intValue()];
final VariableInformation vi = _get.info;
EnumSet<CommonCodeGenerator.Attributes> attributes = CommonCodeGenerator.NONE;
if (vi.isRegister) {
attributes = CommonCodeGenerator.SHADOWREG;
}
return this.idName(vi, true, attributes);
}
public String declaration(final VariableInformation vi, final EnumSet<CommonCodeGenerator.Attributes> attributes) {
CharSequence type = null;
final VariableInformation.Direction _switchValue = vi.dir;
if (_switchValue != null) {
switch (_switchValue) {
case IN:
type = "input";
break;
case INOUT:
type = "inout";
break;
case OUT:
type = "output";
break;
case INTERNAL:
type = "reg";
break;
default:
break;
}
}
boolean _contains = attributes.contains(CommonCodeGenerator.Attributes.isShadowReg);
if (_contains) {
type = "reg";
}
StringConcatenation _builder = new StringConcatenation();
_builder.append("[");
_builder.append((vi.width - 1), "");
_builder.append(":0]");
CharSequence width = _builder;
if ((vi.width == 1)) {
boolean _isArray = this.isArray(vi);
if (_isArray) {
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("[0:");
int _arraySize = this.getArraySize(vi);
int _minus = (_arraySize - 1);
_builder_1.append(_minus, "");
_builder_1.append("]");
width = _builder_1;
} else {
width = "";
}
}
StringConcatenation _builder_2 = new StringConcatenation();
CharSequence dim = _builder_2;
boolean _isArray_1 = this.isArray(vi);
if (_isArray_1) {
if ((vi.width != 1)) {
StringConcatenation _builder_3 = new StringConcatenation();
_builder_3.append("[0:");
int _arraySize_1 = this.getArraySize(vi);
int _minus_1 = (_arraySize_1 - 1);
_builder_3.append(_minus_1, "");
_builder_3.append("]");
dim = _builder_3;
}
}
StringConcatenation _builder_4 = new StringConcatenation();
_builder_4.append(type, "");
_builder_4.append(" ");
_builder_4.append(width, "");
_builder_4.append(" ");
CharSequence _idName = this.idName(vi, true, attributes);
_builder_4.append(_idName, "");
_builder_4.append(" ");
_builder_4.append(dim, "");
_builder_4.append(";");
return _builder_4.toString();
}
protected CharSequence idName(final String name, final boolean field, final EnumSet<CommonCodeGenerator.Attributes> attributes) {
CharSequence _idName = super.idName(name, field, attributes);
String _string = _idName.toString();
return _string.replace("$", "__");
}
protected CharSequence applyRegUpdates() {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence arrayInit(final VariableInformation varInfo, final BigInteger initValue, final EnumSet<CommonCodeGenerator.Attributes> attributes) {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
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) {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence callRunMethod() {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence callStage(final int stage, final boolean constant) {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence checkRegupdates() {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence checkTestbenchListener() {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence clearRegUpdates() {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence copyArray(final VariableInformation varInfo) {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence fieldType(final VariableInformation varInfo, final EnumSet<CommonCodeGenerator.Attributes> attributes) {
String type = "reg";
String width = "";
if ((varInfo.width > 1)) {
StringConcatenation _builder = new StringConcatenation();
_builder.append("[");
_builder.append((varInfo.width - 1), "");
_builder.append(":0]");
width = _builder.toString();
}
if ((varInfo.width <= 0)) {
width = "[31:0]";
}
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append(type, "");
_builder_1.append(width, "");
return _builder_1;
}
protected CharSequence fillArray(final VariableInformation vi, final CharSequence regFillValue) {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence footer() {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence functionFooter(final Frame frame) {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence functionHeader(final Frame frame) {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence header() {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
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) {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence runMethodsFooter(final boolean constant) {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence runMethodsHeader(final boolean constant) {
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");
}
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();
return _builder;
}
protected CharSequence stageMethodsFooter(final int stage, final int totalStageCosts, final boolean constant) {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
protected CharSequence stageMethodsHeader(final int stage, final int totalStageCosts, final boolean constant) {
throw new UnsupportedOperationException("TODO: auto-generated method stub");
}
}