package synthesijer.hdl; import java.io.PrintWriter; import java.util.ArrayList; import java.util.EnumSet; import java.util.Hashtable; import synthesijer.SynthesijerComponent; import synthesijer.hdl.expr.HDLCombinationExpr; import synthesijer.hdl.expr.HDLValue; import synthesijer.hdl.verilog.GenerateVerilogVisitor; import synthesijer.hdl.vhdl.GenerateVHDLVisitor; public class HDLModule implements HDLTree, SynthesijerComponent{ private final String name; private final String sysClkName; private final String sysResetName; private final boolean syncronousFlag; private ArrayList<HDLPort> ports = new ArrayList<>(); private ArrayList<HDLSignal> signals = new ArrayList<>(); private ArrayList<HDLSequencer> sequencer = new ArrayList<>(); private ArrayList<HDLUserDefinedType> usertype = new ArrayList<>(); private ArrayList<HDLInstance> submodules = new ArrayList<>(); private ArrayList<HDLExpr> exprs = new ArrayList<>(); private ArrayList<HDLParameter> parameters = new ArrayList<>(); private ArrayList<HDLSignalBinding> bindings = new ArrayList<>(); private final Hashtable<String, LibrariesInfo> libraries = new Hashtable<>(); private HDLPort sysClk; private HDLPort sysReset; private boolean negativeResetFlag = false; private boolean componentDeclRequired = true; public HDLModule(String name, String sysClkName, String sysResetName, boolean syncFlag){ this.name = name.replace('.', '_'); this.sysClkName = sysClkName; this.sysResetName = sysResetName; if(syncFlag){ sysClk = newPort(sysClkName, HDLPort.DIR.IN, HDLPrimitiveType.genBitType()); } if(syncFlag){ sysReset = newPort(sysResetName, HDLPort.DIR.IN, HDLPrimitiveType.genBitType()); } syncronousFlag = syncFlag; } public HDLModule(String name, String sysClkName, String sysResetName){ this(name, sysClkName, sysResetName, true); } public HDLModule(String name){ this(name, "", "", false); } public HDLPort getSysClk(){ return sysClk; } public HDLPortPairItem getSysClkPairItem(){ return sysClk; } public HDLPort getSysReset(){ return sysReset; } public HDLPortPairItem getSysResetPairItem(){ return sysReset; } public boolean isSynchronous(){ return syncronousFlag; } public String getName(){ return name; } public HDLParameter newParameter(String name, HDLPrimitiveType type, HDLValue defaultValue){ HDLParameter param = new HDLParameter(name, type, defaultValue, defaultValue); parameters.add(param); return param; } public HDLParameter newParameter(String name, int defaultValue){ HDLParameter param = newParameter(name, (HDLPrimitiveType)HDLPrimitiveType.genIntegerType(), new HDLValue(String.valueOf(defaultValue), HDLPrimitiveType.genIntegerType())); return param; } public HDLParameter getParamterByName(String name){ for(HDLParameter p: parameters){ if(p.getName().equals(name)) return p; } return null; } public HDLParameter[] getParameters(){ return parameters.toArray(new HDLParameter[]{}); } public HDLPort newPort(String name, String wire, HDLPort.DIR dir, HDLType type, EnumSet<HDLPort.OPTION> opt){ HDLPort port = new HDLPort(this, name, wire, dir, type, opt); ports.add(port); return port; } public HDLPort newPort(String name, String wire, HDLPort.DIR dir, HDLType type){ HDLPort port = new HDLPort(this, name, wire, dir, type, EnumSet.noneOf(HDLPort.OPTION.class)); ports.add(port); return port; } public HDLPort newPort(String name, HDLPort.DIR dir, HDLType type, EnumSet<HDLPort.OPTION> opt){ HDLPort port = new HDLPort(this, name, dir, type, opt); ports.add(port); return port; } public HDLPort newPort(String name, HDLPort.DIR dir, HDLType type){ return newPort(name, dir, type, EnumSet.noneOf(HDLPort.OPTION.class)); } public HDLPort[] getPorts(){ return ports.toArray(new HDLPort[]{}); } public HDLPort getPort(String name){ for(HDLPort port: ports){ if(port.getName().equals(name)) return port; } return null; } public HDLSignal newSignal(String name, HDLType type, HDLSignal.ResourceKind kind, HDLExpr equivExpr, boolean equivFlag){ HDLSignal sig = new HDLSignal(this, name, type, kind, equivExpr, equivFlag); signals.add(sig); return sig; } public HDLSignal newSignal(String name, HDLType type, HDLSignal.ResourceKind kind){ HDLSignal sig = new HDLSignal(this, name, type, kind); signals.add(sig); return sig; } public HDLSignal newSignal(String name, HDLType type){ HDLSignal sig = new HDLSignal(this, name, type, HDLSignal.ResourceKind.REGISTER); signals.add(sig); return sig; } public HDLSignal newTmpSignal(HDLType type, HDLSignal.ResourceKind kind){ HDLSignal sig = new HDLSignal(this, String.format("tmp_%04d", getExprUniqueId()), type, kind); signals.add(sig); return sig; } public HDLSignal getSignal(String name){ for(HDLSignal sig: signals){ if(sig.getName().equals(name)) return sig; } return null; } public void rmSignal(HDLSignal sig){ signals.remove(sig); } public HDLUserDefinedType newUserDefinedType(String base, String[] items, int defaultIndex){ HDLUserDefinedType t = new HDLUserDefinedType(base, items, defaultIndex); usertype.add(t); return t; } public HDLExpr newExpr(HDLOp op, HDLExpr arg0, HDLExpr arg1, HDLExpr arg2){ HDLExpr expr = new HDLCombinationExpr(this, getExprUniqueId(), op, arg0, arg1, arg2); exprs.add(expr); return expr; } public HDLExpr newExpr(HDLOp op, HDLExpr arg){ HDLExpr expr = new HDLCombinationExpr(this, getExprUniqueId(), op, arg); exprs.add(expr); return expr; } public HDLExpr newExpr(HDLOp op, HDLExpr arg0, int value){ return newExpr(op, arg0, new HDLValue(String.valueOf(value), HDLPrimitiveType.genIntegerType())); } public HDLExpr[] getExprs(){ return exprs.toArray(new HDLExpr[]{}); } public HDLInstance newModuleInstance(HDLModule m, String n, String origName){ HDLInstance obj = new HDLInstance(this, n, m, origName); submodules.add(obj); return obj; } public HDLInstance newModuleInstance(HDLModule m, String n){ HDLInstance obj = new HDLInstance(this, n, m); submodules.add(obj); return obj; } public HDLInstance newModuleInstance(HDLModule m){ HDLInstance obj = new HDLInstance(this, String.format("sjr_generate_U_%04d", getExprUniqueId()), m); submodules.add(obj); return obj; } public HDLInstance[] getModuleInstances(){ return submodules.toArray(new HDLInstance[]{}); } public HDLInstance getModuleInstance(String key){ for(HDLInstance inst: submodules){ if(inst.getName().equals(key)){ return inst; } } return null; } private int uniqId = 1; public int getExprUniqueId(){ int tmp = uniqId; uniqId++; return tmp; } public HDLExpr newExpr(HDLOp op, HDLExpr arg0, HDLExpr arg1){ HDLExpr expr = null; expr = new HDLCombinationExpr(this, getExprUniqueId(), op, arg0, arg1); exprs.add(expr); return expr; } public HDLSignal[] getSignals(){ return signals.toArray(new HDLSignal[]{}); } public String getSysClkName(){ return sysClkName; } public String getSysResetName(){ return sysResetName; } public HDLSequencer newSequencer(String key){ HDLSequencer s = new HDLSequencer(this, key); sequencer.add(s); return s; } public HDLSequencer[] getSequencers(){ return sequencer.toArray(new HDLSequencer[]{}); } public HDLSequencer getSequencer(String name){ for(HDLSequencer s: sequencer){ if(s.getStateKey().getName().equals(name)) return s; } return null; } public void addSignalBinding(HDLSignalBinding binding){ bindings.add(binding); } public HDLSignalBinding[] getSignalBindings(){ return bindings.toArray(new HDLSignalBinding[0]); } public void genVHDL(PrintWriter dest){ accept(new GenerateVHDLVisitor(dest, 0)); } public void genVerilogHDL(PrintWriter dest){ accept(new GenerateVerilogVisitor(dest, 0)); } @Override public void accept(HDLTreeVisitor v) { v.visitHDLModule(this); } public boolean isNegativeReset(){ return negativeResetFlag; } public void setNegativeReset(boolean flag){ negativeResetFlag = flag; } public void setComponentDeclRequired(boolean f){ this.componentDeclRequired = f; } public boolean isComponentDeclRequired(){ return this.componentDeclRequired; } public void addLibraryUse(String key, String use){ LibrariesInfo info; if(libraries.containsKey(key)){ info = libraries.get(key); }else{ info = new LibrariesInfo(key); libraries.put(key, info); } if(info.useName.contains(use) == false){ info.useName.add(use); } } public LibrariesInfo[] getLibraries(){ return libraries.values().toArray(new LibrariesInfo[]{}); } public class LibrariesInfo{ public final String libName; public final ArrayList<String> useName = new ArrayList<>(); public LibrariesInfo(String libName){ this.libName = libName; } } }