Package com.atolsystems.HwModeling

Source Code of com.atolsystems.HwModeling.VerilogModule

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package com.atolsystems.HwModeling;

import com.atolsystems.atolutilities.MutableInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

/**
*
* @author sebastien.riou
*/
public class VerilogModule implements Comparable{
    String name;
    //ArrayList<VerilogPort> ports;
    TreeMap<String,VerilogPort> inputPorts;
    TreeMap<String,VerilogPort> outputPorts;
    TreeMap<String,VerilogPort> inOutPorts;
    TreeMap<Integer,TreeMap<String,VerilogPort>> ports;
    String body;
    boolean primitive;
    protected boolean verilog1995 = false;

    /**
     * Get the value of verilog1995
     *
     * @return the value of verilog1995
     */
    public boolean isVerilog1995() {
        return verilog1995;
    }

    /**
     * Set the value of verilog1995
     *
     * @param verilog1995 new value of verilog1995
     */
    public void setVerilog1995(boolean verilog1995) {
        this.verilog1995 = verilog1995;
    }

    public VerilogModule(VerilogModule module) {
        this.name=module.name;
        initPorts(module.getPorts());
        this.body=module.body;
        this.primitive=module.primitive;
    }

    public VerilogModule(String name, ArrayList<VerilogPort> ports, String body, boolean isPrimitive) {
        this.name = name;
        initPorts(ports);
        this.body = body;
        this.primitive=isPrimitive;
    }

    final void initPorts(Collection<VerilogPort> ports){
        inputPorts=new TreeMap<String, VerilogPort>();
        outputPorts=new TreeMap<String, VerilogPort>();
        inOutPorts=new TreeMap<String, VerilogPort>();
        this.ports=new TreeMap<Integer,TreeMap<String, VerilogPort>>();
        this.ports.put(VerilogPort.INPUT, inputPorts);
        this.ports.put(VerilogPort.OUTPUT, outputPorts);
        this.ports.put(VerilogPort.OUTPUT_REG, outputPorts);
        this.ports.put(VerilogPort.INOUT, inOutPorts);

        if(null==ports) return;
        for(VerilogPort p:ports){
            if(p.isPort()){
                if(hasPort(p.getName()))  throw new RuntimeException("Port '"+p.getName()+"' already defined in module "+this.getName());
                this.ports.get(p.getType()).put(p.getName(), p);
            } else {
                if(!p.isWire()) throw new RuntimeException("Port '"+p.getName()+"': unknown port type "+p.getType());
            }
        }
    }

    public VerilogModule(String name) {
        this.name = name;
        body="";
        initPorts(null);
    }

    public VerilogModule() {
        body="";
        initPorts(null);
    }

    public boolean isPrimitive() {
        return primitive;
    }

    public void setPrimitive(boolean primitive) {
        this.primitive = primitive;
    }

    public String getBody() {
        return body;
    }

    /**
     * body should not be null
     * @param body
     */
    public void setBody(String body) {
        this.body = body;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * Remove ports which are defined as port in this module
     * @param ports
     */
     public void excludePorts(Collection<VerilogPort> ports){
        ArrayList<VerilogPort> toRemove=new ArrayList<VerilogPort>();
        for(VerilogPort p:ports){
            if(null!=this.inputPorts.get(p.getName()))
                toRemove.add(p);
            if(null!=this.outputPorts.get(p.getName()))
                toRemove.add(p);
            if(null!=this.inOutPorts.get(p.getName()))
                toRemove.add(p);
        }
        ports.removeAll(toRemove);
    }

    /*public ArrayList<VerilogPort> getPorts() {
        ArrayList<VerilogPort> out=getInputs();
        out.addAll(getOutputs());
        out.addAll(getInOuts());
        return out;
    }*/
    public ArrayList<VerilogPort> getPorts() {
        ArrayList<VerilogPort> out=new ArrayList<VerilogPort>();
        out.addAll(getInputs());
        out.addAll(getOutputs());
        out.addAll(getInOuts());
        return out;
    }
   
    VerilogPort getPort(String portName) {
        VerilogPort out = this.getInput(portName);
        if(null!=out) return out;
        out=this.getOutput(portName);
        if(null!=out) return out;
        out=this.getInOut(portName);
        return out;
    }

    public void setPorts(ArrayList<VerilogPort> ports) {
        initPorts(ports);
    }

    /*public ArrayList<VerilogPort> getInputs(){
        return inputPorts.values();
    }
    public ArrayList<VerilogPort> getOutputs(){
        return outputPorts;
    }
    public ArrayList<VerilogPort> getInOuts(){
        return inOutPorts;
    }*/
    public Collection<VerilogPort> getInputs(){
        return inputPorts.values();
    }
    public ArrayList<VerilogPort> getInputsArrayList(){
        ArrayList<VerilogPort> out=new ArrayList<VerilogPort>();
        out.addAll(inputPorts.values());
        return out;
    }
    public VerilogPort getFirstInput(){
        return inputPorts.firstEntry().getValue();
    }
    public String getFirstInputName(){
        return inputPorts.firstKey();
    }
    public Collection<VerilogPort> getOutputs(){
        return outputPorts.values();
    }
    public ArrayList<VerilogPort> getOutputsArrayList(){
        ArrayList<VerilogPort> out=new ArrayList<VerilogPort>();
        out.addAll(outputPorts.values());
        return out;
    }
    public VerilogPort getFirstOutput(){
        return outputPorts.firstEntry().getValue();
    }
    public String getFirstOutputName(){
        return outputPorts.firstKey();
    }
    public Collection<VerilogPort> getInOuts(){
        return inOutPorts.values();
    }
    public ArrayList<VerilogPort> getOutputsInOuts(){
        ArrayList<VerilogPort> outPorts=new ArrayList<VerilogPort>();
        outPorts.addAll(getOutputs());
        outPorts.addAll(getInOuts());
        return outPorts;
    }
    public ArrayList<VerilogPort> getInputsInOuts(){
        ArrayList<VerilogPort> inPorts=new ArrayList<VerilogPort>();
        inPorts.addAll(getInputs());
        inPorts.addAll(getInOuts());
        return inPorts;
    }
    public VerilogPort getInput(String name){
        return inputPorts.get(name);
    }
    public VerilogPort getInputInOut(String name){
        VerilogPort out=inputPorts.get(name);
        if(null==out) out=inOutPorts.get(name);
        return out;
    }
    public VerilogPort getOutput(String name){
        return outputPorts.get(name);
    }
    public VerilogPort getOutputInOut(String name){
        VerilogPort out=outputPorts.get(name);
        if(null==out) out=inOutPorts.get(name);
        return out;
    }
    public VerilogPort getInOut(String name){
        return inOutPorts.get(name);
    }
    public boolean isInOut(String name){
        VerilogPort p=inOutPorts.get(name);
        if(null!=p) return true;
        if(outputPorts.containsKey(name) | inputPorts.containsKey(name)) return false;
        throw new RuntimeException("Port '"+name+"' is not declared in module '"+this.getName()+"'");
    }
    public boolean isInput(String name){
        VerilogPort p=inputPorts.get(name);
        if(null!=p) return true;
        if(outputPorts.containsKey(name) | inOutPorts.containsKey(name)) return false;
        throw new RuntimeException("Port '"+name+"' is not declared in module '"+this.getName()+"'");
    }
    public boolean isOutput(String name){
        VerilogPort p=outputPorts.get(name);
        if(null!=p) return true;
        if(inputPorts.containsKey(name) | inOutPorts.containsKey(name)) return false;
        throw new RuntimeException("Port '"+name+"' is not declared in module '"+this.getName()+"'");
    }
    public boolean hasPort(String name){
        if(outputPorts.containsKey(name) | inputPorts.containsKey(name) | inOutPorts.containsKey(name)) return true;
        return false;
    }
  
    public String instantiate(String instanceName){
        TreeMap<String,String> connections=new TreeMap<String,String>();
        for(VerilogPort p:getInputs())
            connections.put(p.getName(), p.getName());
        for(VerilogPort p:getOutputs())
            connections.put(p.getName(), p.getName());
        for(VerilogPort p:getInOuts())
            connections.put(p.getName(), p.getName());
        return instantiate(instanceName,connections);
    }
   
    public String instantiate(String instanceName, Map<String,String> connections){ 
        StringBuilder sb=new StringBuilder();
        int remaining=connections.entrySet().size();
        if(remaining!=getPorts().size()){
            if(0==remaining) throw new RuntimeException("No connections defined for instance '"+instanceName+"' ("+this.getName()+")");
            sb.append("//WARNING: ");
            sb.append(getPorts().size()-remaining);
            sb.append(" unconnected ports\n");
            int unconnectedCnt=0;
            for(VerilogPort p:getPorts()){
                if(!connections.containsKey(p.getName())){
                    connections.put(p.getName(), instanceName+"_unconnected"+unconnectedCnt);
                    unconnectedCnt++;
                }
            }
        }
        sb.append(name);
        sb.append(" ");
        sb.append(instanceName);
        sb.append(" (\n   .");
        for(Entry<String,String> e:connections.entrySet()){
            sb.append(e.getKey());
            sb.append("(");
            sb.append(e.getValue());
            sb.append(")");
            if(1==remaining)
                sb.append("\n   );");
            else
                sb.append(",\n   .");
            remaining--;
        }
        return sb.toString();
    }

    protected void addPortDeclaration(StringBuilder sb, VerilogPort p, boolean justName){
        if(!justName){
            if(verilog1995 && p.isOutputReg()){
                sb.append("output ");
                sb.append(p.getName());
                sb.append("; reg");
            }else
                sb.append(p.getTypeString());
            sb.append(" ");
            if(p.getWidth()!=1){
                sb.append("[");
                sb.append(p.getWidth()-1);
                sb.append(":0]");
            }
        }
        sb.append(p.getName());
    }
    protected void addPortsDeclaration(StringBuilder sb, MutableInteger remaining, Collection<VerilogPort> ports){
        if(null==remaining) remaining=new MutableInteger(ports.size());
        for(VerilogPort p:ports){
            addPortDeclaration(sb, p, verilog1995);
            if(1!=remaining.value)
                sb.append(",\n   ");
            remaining.value=remaining.value-1;
        }
    }
    protected void addPortsTypeDeclaration(StringBuilder sb, MutableInteger remaining, Collection<VerilogPort> ports){
        if(null==remaining) remaining=new MutableInteger(ports.size());
        for(VerilogPort p:ports){
            addPortDeclaration(sb, p, false);
            if(1==remaining.value)
                sb.append(";\n");
            else
                sb.append(";\n   ");
            remaining.value=remaining.value-1;
        }
    }
   
    @Override
    public String toString() {
        StringBuilder sb=new StringBuilder();
        if(primitive)
            sb.append("primitive ");
        else
            sb.append("module ");
        sb.append(name);
        sb.append("(\n");
        //MutableInteger remaining=null;//new MutableInteger(ports.size());
        if(hasInputs()) sb.append("//inputs:\n   ");
        addPortsDeclaration(sb,null,getInputs());
        if(hasOutputs()){
            if(hasInputs()) sb.append(",\n");
            sb.append("//outputs:\n   ");
            addPortsDeclaration(sb,null,getOutputs());
        }
        if(hasInOuts()){
            if(hasOutputs()) sb.append(",\n");
            if(hasInOuts()) sb.append("//inouts:\n   ");
            addPortsDeclaration(sb,null,getInOuts());
        }
        sb.append("\n   );\n");
        if(verilog1995){
            //remaining.value=ports.size();
            if(hasInputs()) sb.append("//inputs:\n   ");
            addPortsTypeDeclaration(sb,null,getInputs());
            if(hasOutputs()) sb.append("//outputs:\n   ");
            addPortsTypeDeclaration(sb,null,getOutputs());
            if(hasInOuts()) sb.append("//inouts:\n   ");
            addPortsTypeDeclaration(sb,null,getInOuts());
        }
        if(!body.isEmpty()){
            sb.append("\n");
            sb.append(body);
            if(!body.endsWith("\n"))
                sb.append("\n");
            if(primitive)
                sb.append("endprimitive");
            else
                sb.append("endmodule");
        }
        return sb.toString();
    }

    public boolean hasInputs() {
        return !inputPorts.isEmpty();
    }
    public boolean hasOutputs() {
        return !outputPorts.isEmpty();
    }
    public boolean hasInOuts() {
        return !inOutPorts.isEmpty();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final VerilogModule other = (VerilogModule) obj;
        if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
            return false;
        }
        if (this.inputPorts != other.inputPorts && (this.inputPorts == null || !this.inputPorts.equals(other.inputPorts))) {
            return false;
        }
        if (this.outputPorts != other.outputPorts && (this.outputPorts == null || !this.outputPorts.equals(other.outputPorts))) {
            return false;
        }
        if (this.inOutPorts != other.inOutPorts && (this.inOutPorts == null || !this.inOutPorts.equals(other.inOutPorts))) {
            return false;
        }
        if ((this.body == null) ? (other.body != null) : !this.body.equals(other.body)) {
            return false;
        }
        if (this.primitive != other.primitive) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 19 * hash + (this.name != null ? this.name.hashCode() : 0);
        hash = 19 * hash + (this.inputPorts != null ? this.inputPorts.hashCode() : 0);
        hash = 19 * hash + (this.outputPorts != null ? this.outputPorts.hashCode() : 0);
        hash = 19 * hash + (this.inOutPorts != null ? this.inOutPorts.hashCode() : 0);
        hash = 19 * hash + (this.ports != null ? this.ports.hashCode() : 0);
        hash = 19 * hash + (this.body != null ? this.body.hashCode() : 0);
        return hash;
    }

    @Override
    public int compareTo(Object o) {
        if(equals(o)) return 0;//ensure consistency with equals
        final VerilogModule other = (VerilogModule) o;
        int out = name.compareTo(other.name);
        if(0==out)
            out=inputPorts.size()-other.inputPorts.size();
        if(0==out)
            out=outputPorts.size()-other.outputPorts.size();
        if(0==out)
            out=inOutPorts.size()-other.inOutPorts.size();
        if(0==out){
            Iterator<VerilogPort> in=inputPorts.values().iterator();
            Iterator<VerilogPort> inOther=other.inputPorts.values().iterator();
            while(in.hasNext()){
                out=in.next().compareTo(inOther.next());
                if(0!=out) break;
            }
        }
        if(0==out){
            Iterator<VerilogPort> in=outputPorts.values().iterator();
            Iterator<VerilogPort> inOther=other.outputPorts.values().iterator();
            while(in.hasNext()){
                out=in.next().compareTo(inOther.next());
                if(0!=out) break;
            }
        }
        if(0==out){
            Iterator<VerilogPort> in=inOutPorts.values().iterator();
            Iterator<VerilogPort> inOther=other.inOutPorts.values().iterator();
            while(in.hasNext()){
                out=in.next().compareTo(inOther.next());
                if(0!=out) break;
            }
        }
        if(0==out){
            out=body.compareTo(other.body);
        }
        return out;
    }
    static public HashMap<String,VerilogModule> buildMap(Collection<VerilogModule> c){
        HashMap<String,VerilogModule> out=new HashMap<String,VerilogModule>();
        for(VerilogModule m:c){
            out.put(m.getName(), m);
        }
        return out;
    }
    static public VerilogModule find(Collection<VerilogModule> c, String name){
        for(VerilogModule m:c){
            if(m.getName().equals(name)) return m;
        }
        return null;
    }
}
TOP

Related Classes of com.atolsystems.HwModeling.VerilogModule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.