package synthesijer.hdl.expr; import synthesijer.hdl.HDLExpr; import synthesijer.hdl.HDLLiteral; import synthesijer.hdl.HDLPrimitiveType; import synthesijer.hdl.HDLSignal; import synthesijer.hdl.HDLTreeVisitor; public class HDLValue implements HDLLiteral { private final HDLPrimitiveType type, actualType; private final String value; public HDLValue(String value, HDLPrimitiveType type) { this(value, type, type); } public HDLValue(String value, HDLPrimitiveType type, HDLPrimitiveType actualType) { this.value = value; this.type = type; this.actualType = actualType; } public HDLValue(int v) { this(String.valueOf(v), HDLPrimitiveType.genIntegerType()); } public HDLValue(String v) { this(v, HDLPrimitiveType.genStringType()); } public HDLValue(boolean v) { this(new Boolean(v).toString(), HDLPrimitiveType.genBitType()); } public String toString() { return String.format("HDLValue:: value=%s, type=%s, actualType=%s", value, type, actualType); } public String getValue() { return value; } private long asLongValue() { try { long v = 0L; if (value.contains(".")) { if (type.getWidth() == 64) { v = Double.doubleToLongBits(Double.parseDouble(value)); } else if (type.getWidth() == 32) { v = Float.floatToIntBits(Float.parseFloat(value)); } else { String msg = "HDLExpr contains floating value: " + value + ", but width is not 32 or 64"; System.err.println(msg); throw new RuntimeException(msg); } } else { v = Long.parseLong(value); } return v; } catch (NumberFormatException e) { System.err.println("HDLExpr contains illegal value: " + value); throw new RuntimeException(e); } } @Override public String getVHDL() { switch (type.getKind()) { case VECTOR: case SIGNED: { if (type.getWidth() % 4 == 0) { // String v = String.format("%016x", Long.parseLong(value)); String v = String.format("%020x", asLongValue()); // System.out.printf("%s => %s => %s\n", value, v, // v.substring(v.length()-type.getWidth()/4, v.length())); if (v.length() - type.getWidth() / 4 < 0) { System.out.println(v); System.out.println( this.getValue() + ":" + type.getWidth() + "," + v.length() + "-" + (type.getWidth() / 4)); } String s = String.format("X\"%s\"", v.substring(v.length() - type.getWidth() / 4, v.length())); return s; } else { String v = ""; for (int i = 0; i < 64; i++) { v += "0"; } // v += Long.toBinaryString(Long.parseLong(value)); v += Long.toBinaryString(asLongValue()); return String.format("\"%s\"", v.substring(v.length() - type.getWidth(), v.length())); } } case BIT: if (value.equals("true")) { return "'1'"; } else { return "'0'"; } case INTEGER: return String.valueOf(value); case STRING: // return "\"" + value + "\""; return value; default: return "UNKNWON(" + value + ")"; } } @Override public String getVerilogHDL() { switch (type.getKind()) { case VECTOR: { if (type.getWidth() % 4 == 0) { // String v = String.format("%064x", Long.parseLong(value)); String v = String.format("%080x", asLongValue()); return String.format("%d'h%s", type.getWidth(), v.substring(v.length() - type.getWidth() / 4, v.length())); } else { String v = ""; for (int i = 0; i < 64; i++) { v += "0"; } // v += Long.toBinaryString(Long.parseLong(value)); v += Long.toBinaryString(asLongValue()); return String.format("%d'b%s", type.getWidth(), v.substring(v.length() - type.getWidth(), v.length())); } } case SIGNED: { if (type.getWidth() % 4 == 0) { // String v = String.format("%064x", Long.parseLong(value)); String v = String.format("%064x", asLongValue()); return String.format("%d'sh%s", type.getWidth(), v.substring(v.length() - type.getWidth() / 4, v.length())); } else { String v = ""; for (int i = 0; i < 64; i++) { v += "0"; } // v += Long.toBinaryString(Long.parseLong(value)); v += Long.toBinaryString(asLongValue()); return String.format("%d'sb%s", type.getWidth(), v.substring(v.length() - type.getWidth(), v.length())); } } case BIT: if (value.equals("true")) { return "1'b1"; } else { return "1'b0"; } case INTEGER: return String.valueOf(value); case STRING: // return "\"" + value + "\""; return value; default: return "UNKNWON(" + value + ")"; } } @Override public void accept(HDLTreeVisitor v) { v.visitHDLLitral(this); } @Override public HDLExpr getResultExpr() { return this; } @Override public HDLPrimitiveType getType() { return actualType; } @Override public HDLSignal[] getSrcSignals() { return null; } }