//--------------------------------------------------------------------------------// // COPYRIGHT NOTICE // //--------------------------------------------------------------------------------// // Copyright (c) 2012, Instituto de Microelectronica de Sevilla (IMSE-CNM) // // // // All rights reserved. // // // // Redistribution and use in source and binary forms, with or without // // modification, are permitted provided that the following conditions are met: // // // // * Redistributions of source code must retain the above copyright notice, // // this list of conditions and the following disclaimer. // // // // * Redistributions in binary form must reproduce the above copyright // // notice, this list of conditions and the following disclaimer in the // // documentation and/or other materials provided with the distribution. // // // // * Neither the name of the IMSE-CNM nor the names of its contributors may // // be used to endorse or promote products derived from this software // // without specific prior written permission. // // // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE // // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //--------------------------------------------------------------------------------// package xfuzzy.xfvhdl; import java.util.ArrayList; import xfuzzy.lang.CrispBlockCall; import xfuzzy.lang.CrispBlockSet; import xfuzzy.lang.FamiliarMemFunc; import xfuzzy.lang.LinguisticLabel; import xfuzzy.lang.ModuleCall; import xfuzzy.lang.ParamMemFunc; import xfuzzy.lang.Parameter; import xfuzzy.lang.RulebaseCall; import xfuzzy.lang.Specification; import xfuzzy.lang.SystemModule; import xfuzzy.lang.Variable; import xfuzzy.xfsg.XfsgInOrderMemFunc; import xfuzzy.xfsg.XfsgOutData; import xfuzzy.xfsg.XfsgPrintRulesFactory; import xfuzzy.xfsg.XfsgRulesMemData; import xfuzzy.xfsg.XfsgSTPrintRules; import xfuzzy.xfsg.XfsgStaticMethods; /** * Clase que incluye los m�todos "inicializarFLCs" e "inicializarCrispBlocks" * encargados de construir los objetos de tipo XfvhdlFLC y XfvhdlCrisp de una * especificaci�n XFL. Tambi�n incluye m�todos para determinar los tipos de * funciones de pertenencia y para calcular el segundo par�metro de ponderaci�n * usado en determinados m�todos de defuzzificacci�n. * * @author Lidia Delgado Carretero. */ public class XfvhdlLeerXfl { // ATRIBUTOS /**Lista de m�dulos de inferencia.*/ private ArrayList<XfvhdlFLC> listaflc; /**Lista de m�dulos de crisp.*/ private ArrayList<XfvhdlCrisp> listacrisp; /**Se�ales necesarias a la hora de generar el c�digo de nivel superior o * jerarqu�a del sistema jer�rquico.*/ private String se�alesjerarquia; /**Especificaci�n XFL*/ private Specification spec; // El siguiente atributo es para las funciones de pertenencia de las // variables de entrada ordenadas /**Funciones de pertenencia de las variables de entrada * ordenadas.*/ private XfsgInOrderMemFunc[] inOrderMfInput; // El siguiente atributo es para las funciones de pertenencia de las // variables de salida ordenadas /**Funciones de pertenencia de las variables de salida ordenadas.*/ private XfsgInOrderMemFunc[] inOrderMfOutput; private XfsgSTPrintRules printer; private String asignaEntrada=""; CrispBlockSet set_de_crisps; // CONSTRUCTOR /**Constructor de la clase.*/ public XfvhdlLeerXfl(Specification spec) { this.spec = spec; listaflc = new ArrayList<XfvhdlFLC>(); listacrisp = new ArrayList<XfvhdlCrisp>(); se�alesjerarquia=""; set_de_crisps=spec.getCrispBlockSet(); } // M�TODOS GET /**@return listaflc*/ public ArrayList<XfvhdlFLC> getlistaflc() { return listaflc; } /**@return listacrisp*/ public ArrayList<XfvhdlCrisp> getlistacrisp() { return listacrisp; } /**@return spec*/ public Specification getspec() { return spec; } // M�TODOS SET /**@param listaflc*/ public void setlistaflc(ArrayList<XfvhdlFLC> listaflc) { this.listaflc = listaflc; } /**@param listacrisp*/ public void setlistacrisp(ArrayList<XfvhdlCrisp> listacrisp) { this.listacrisp = listacrisp; } /**@param spec*/ public void setspec(Specification spec) { this.spec = spec; } /**M�todo encargado de inicializar toda la informaci�n relativa a los * m�dulos de inferencia, captur�ndola de la especificaci�n XFL.*/ public void inicializarFLCs() { String num_mf = "", puntos_corte = "", pendientes = ""; ArrayList<Double> listaPendientes=new ArrayList<Double>(); ArrayList<Double> listaPuntos=new ArrayList<Double>(); SystemModule sistema = spec.getSystemModule(); RulebaseCall rbcarray[] = sistema.getRulebaseCalls(); try { for (int s = 0; s < rbcarray.length; s++) { RulebaseCall rbc = rbcarray[s]; String name = rbc.getName(); /* MFC */ // Crea el FLC XfvhdlFLC flc = new XfvhdlFLC(name, rbc,spec); String defuzzy = rbc.getRulebase().getOperatorset().defuz .getFunctionName(); flc.setdefuzzy(defuzzy); // Dependiendo del m�todo de defuzzificaci�n se calcular�n los // pesos de las funciones de pertenencia if (defuzzy.equalsIgnoreCase( "WeightedFuzzyMean") || defuzzy.equalsIgnoreCase( "GammaQuality") || defuzzy.equalsIgnoreCase( "Quality")) { flc.setCalculateWeights(true); } String connective = rbc.getRulebase().getOperatorset().and .getFunctionName(); flc.setconnective(connective); Variable[] var_inputs = rbc.getRulebase().getInputs(); double min, max; int total_inputs = var_inputs.length; flc.setinputs(total_inputs); LinguisticLabel mf, mf2; int nmf; // Crea la estructura inOrderMfInput[i] (donde el �ndice i // direcciona las distintas variables de entrada) que contiene // una lista con las funciones de pertenencia ordenadas inOrderMfInput = new XfsgInOrderMemFunc[total_inputs]; for (int i = 0; i < total_inputs; i++) { inOrderMfInput[i] = new XfsgInOrderMemFunc(var_inputs[i]); inOrderMfInput[i].sort(); } /* Inicializa los MFCs */ for (int i = 0; i < total_inputs; i++) { String tipo_input = tipo_input(inOrderMfInput[i]); nmf = inOrderMfInput[i].getSize(); // N�mero de funciones de pertenencia num_mf = new Integer(nmf).toString(); // Las pendientes que se calculan son las crecientes // Familia de tipo "triangular" if (tipo_input.equals("triangular")) { puntos_corte = "[ "; listaPuntos=new ArrayList<Double>(); for (int j = 0; j < nmf; j++) { mf = inOrderMfInput[i].getMemFunc(j); double x1 = roundNum((mf.center() - mf.min()) / (mf.max() - mf.min())); listaPuntos.add(x1); puntos_corte += x1 + " "; } puntos_corte += "];\n"; pendientes = "[ "; listaPendientes=new ArrayList<Double>(); for (int j = 0; j < nmf - 1; j++) { mf = inOrderMfInput[i].getMemFunc(j); mf2 = inOrderMfInput[i].getMemFunc(j + 1); double pendiente = roundNum((mf.max() - mf .min()) / (mf2.center() - mf.center())); listaPendientes.add(pendiente); pendientes += pendiente + " "; } pendientes += "];\n"; // Familia de tipo "sh_triangular" } else if (tipo_input.equals("sh_triangular")) { puntos_corte = "[ "; listaPuntos=new ArrayList<Double>(); for (int j = 0; j < nmf; j++) { mf = inOrderMfInput[i].getMemFunc(j); double x1 = 0.0; x1 = roundNum((mf.get()[j] - mf.min()) / (mf.max() - mf.min())); listaPuntos.add(x1); puntos_corte += x1 + " "; } puntos_corte += "];\n"; pendientes = "[ "; listaPendientes=new ArrayList<Double>(); for (int j = 0; j < nmf - 1; j++) { mf = inOrderMfInput[i].getMemFunc(j); double pendiente; pendiente = roundNum((mf.max() - mf.min()) / (mf.get()[j + 1] - mf.get()[j])); listaPendientes.add(pendiente); pendientes += pendiente + " "; } pendientes += "];\n"; // MFCs de tipo "triangle" } else if (tipo_input.equals("triangle")) { puntos_corte = "[ "; listaPuntos=new ArrayList<Double>(); for (int j = 0; j < nmf; j++) { mf = inOrderMfInput[i].getMemFunc(j); double x1 = roundNum((mf.center() - mf.min()) / (mf.max() - mf.min())); listaPuntos.add(x1); puntos_corte += x1 + " "; } puntos_corte += "];\n"; pendientes = "[ "; listaPendientes=new ArrayList<Double>(); for (int j = 0; j < nmf - 1; j++) { mf = inOrderMfInput[i].getMemFunc(j); mf2 = inOrderMfInput[i].getMemFunc(j + 1); double pendiente = roundNum((mf.max() - mf .min()) / (mf2.center() - mf.center())); listaPendientes.add(pendiente); pendientes += pendiente + " "; } pendientes += "];\n"; // MFCs de tipo "trapezoid" } else if (tipo_input.equals("sh_triangle")) { /* Puntos de Corte */ puntos_corte = "[ "; listaPuntos=new ArrayList<Double>(); for (int j = 0; j < nmf; j++) { mf = inOrderMfInput[i].getMemFunc(j); double x1 = 0.0; if (j == 0) { if (mf.getClass().toString().contains( "trapezoid")) x1 = roundNum((mf.get()[2] - mf.min()) / (mf.max() - mf.min())); else if (mf.getClass().toString().contains( "triangle")) x1 = roundNum((mf.center() - mf.min()) / (mf.max() - mf.min())); } else if (j == nmf - 1) { if (mf.getClass().toString().contains( "trapezoid")) x1 = roundNum((mf.get()[1] - mf.min()) / (mf.max() - mf.min())); else if (mf.getClass().toString().contains( "triangle")) x1 = roundNum((mf.center() - mf.min()) / (mf.max() - mf.min())); } else { x1 = roundNum((mf.center() - mf.min()) / (mf.max() - mf.min())); } listaPuntos.add(x1); puntos_corte += x1 + " "; } puntos_corte += "];\n"; pendientes = "[ "; listaPendientes=new ArrayList<Double>(); for (int j = 0; j < nmf - 1; j++) { mf = inOrderMfInput[i].getMemFunc(j); mf2 = inOrderMfInput[i].getMemFunc(j + 1); double pendiente = 0.0; if (j == 0) { if (mf.getClass().toString().contains( "trapezoid")) pendiente = roundNum((mf.max() - mf .min()) / (mf2.center() - mf.get()[2])); else if (mf.getClass().toString().contains( "triangle")) pendiente = roundNum((mf.max() - mf .min()) / (mf2.center() - mf.center())); } else if (j == nmf - 2) { if (mf2.getClass().toString().contains( "trapezoid")) pendiente = roundNum((mf.max() - mf .min()) / (mf2.get()[1] - mf.center())); else if (mf.getClass().toString().contains( "triangle")) pendiente = roundNum((mf.max() - mf .min()) / (mf2.center() - mf.center())); } else pendiente = roundNum((mf.max() - mf.min()) / (mf2.center() - mf.center())); listaPendientes.add(pendiente); pendientes += pendiente + " "; } pendientes += "];\n"; }else if (tipo_input.equals("not found")) { puntos_corte = "N/A\n"; listaPuntos=new ArrayList<Double>(); pendientes = "N/A\n"; listaPendientes=new ArrayList<Double>(); flc.setEntradasNoNormalizadasMenor1(true); } flc.create_addMFC(num_mf, puntos_corte, pendientes, listaPuntos, listaPendientes); } Variable[] var_outputs = rbc.getRulebase().getOutputs(); int total_outputs = var_outputs.length; flc.setoutputs(total_outputs); // Crea la estructura inOrderMfOutput[i] (donde el �ndice i // direcciona las distintas variables de salida) que contiene // una lista con las funciones de pertenencia ordenadas inOrderMfOutput = new XfsgInOrderMemFunc[total_outputs]; for (int i = 0; i < total_outputs; i++) { inOrderMfOutput[i] = new XfsgInOrderMemFunc(var_outputs[i]); inOrderMfOutput[i].sort(); } int maxn_fp = XfsgStaticMethods.CalculaMaximon_fp(rbc); int bitsn_fp = XfsgStaticMethods.ceillog2(maxn_fp); XfsgRulesMemData contenido = new XfsgRulesMemData(rbc .getNumberOfInputs() * bitsn_fp, rbc.getRulebase(), defuzzy); for (int i = 0; i < total_outputs; i++) { // code += "\n% RB" + (i+1) + "\n"; /* Nombre de las funciones y Puntos */ nmf = inOrderMfOutput[i].getSize(); XfsgOutData outdata = new XfsgOutData(nmf, defuzzy); // Obtiene las etiquetas String[] labels = new String[nmf]; // Calcula los valores para cada etiqueta seg�n el // m�todo de defuzzificaci�n. if (defuzzy.equals("FuzzyMean") || defuzzy.equals("MaxLabel")) { double[] values = new double[nmf]; for (int j = 0; j < nmf; j++) { mf = inOrderMfOutput[i].getMemFunc2(j); labels[j] = mf.getLabel(); min = mf.min(); max = mf.max(); values[j] = roundNum((mf.center() - min) / (max - min)); } outdata.setvalues(values); } else if (defuzzy.equals("WeightedFuzzyMean") || defuzzy.equals("Quality") || defuzzy.equals("GammaQuality")) { double[][] values2 = new double[nmf][2]; for (int j = 0; j < nmf; j++) { mf = inOrderMfOutput[i].getMemFunc2(j); labels[j] = mf.getLabel(); min = mf.min(); max = mf.max(); values2[j][0] = roundNum((mf.center() - min) / (max - min)); double gamma = 0; // Si el m�todo de defuzzificaci�n es GammaQuality // hay que calcular el valor de gamma. En los otros // casos no hace falta. if (defuzzy.equals("GammaQuality")) { gamma = rbc.getRulebase().getOperatorset().defuz .getSingleParameters()[0].value; } String clase = mf.getClass().toString(); if (clase.contains("singleton")) { XfvhdlError err = new XfvhdlError(); err.newWarning(37, "Defuzzification method: " + defuzzy + ". Membership function: " + mf.getClass() + "."); } else values2[j][1] = roundNum(calculateWeight2(mf, defuzzy, gamma)); } outdata.setvalues2(values2); } else if (defuzzy.equals("TakagiSugeno")) { double[][] values2 = new double[nmf][3]; for (int j = 0; j < nmf; j++) { mf = inOrderMfOutput[i].getMemFunc2(j); labels[j] = mf.getLabel(); min = mf.min(); max = mf.max(); Parameter[] params = ((ParamMemFunc) mf) .getParameters(); values2[j][0] = roundNum(params[0].value); values2[j][1] = roundNum(params[1].value); values2[j][2] = roundNum(params[2].value); } outdata.setvalues2(values2); } outdata.setlabels(labels); if (total_outputs != 1) outdata.setnombre("_" + var_outputs[i].getName()); XfsgPrintRulesFactory factory = new XfsgPrintRulesFactory( total_inputs); printer = factory.create(contenido, defuzzy, name, bitsn_fp, outdata, inOrderMfInput, i); printer.printRules(); outdata.setRB(printer.getRB()); outdata.setpesos(printer.getPesos()); if (i == 0) { flc.setgrados(printer.getGrados()); flc.setcomplete(printer.getComplete()); } flc.addRB(outdata); } // flc.generaComponente(); listaflc.add(flc); } } catch (Exception e) { e.printStackTrace(); } } /**M�todo encargado de inicializar toda la informaci�n relativa a los * m�dulos crisp, captur�ndola de la especificaci�n XFL.*/ public void inicializarCrispBlocks() { int count = 0; SystemModule sistema = spec.getSystemModule(); ModuleCall[] call = sistema.getModuleCalls(); for (int i = 0; i < call.length; i++) if (call[i] instanceof CrispBlockCall) count++; CrispBlockCall cbcarray[] = new CrispBlockCall[count]; for (int i = 0, j = 0; i < call.length; i++) if (call[i] instanceof CrispBlockCall) { cbcarray[j] = (CrispBlockCall) call[i]; j++; } for (int i = 0; i < count; i++) { CrispBlockCall cbc = cbcarray[i]; XfvhdlCrisp c = new XfvhdlCrisp(cbc.getName(), cbc); c.setinputs(cbc.getNumberOfInputs()); c.setoutputs(cbc.getNumberOfOutputs()); // c.generaComponente(); listacrisp.add(c); } } /**M�todo de apoyo que redondea un double en su 4� cifra decimal.*/ private static double roundNum(double num) throws Exception { double valor = 0; valor = num; valor = valor * 10000; valor = java.lang.Math.round(valor); valor = valor / 10000; return valor; } /** * * @param p Representa una funci�n de pertenencia. * @param defuzzy Cadena que indica el m�todo de defuzzificaci�n. * @param gamma Valor para la variable gamma en caso de que el metodo de * defuzzificaci�n sea GammaQuality, en otro caso, vale 0. * @return Valor del par�metro de peso para ponderar la salida de una regla. */ private double calculateWeight2(LinguisticLabel p, String defuzzy, double gamma) { double universeRange = 0, w = 0; universeRange = p.max() - p.min(); try { if (defuzzy.equals("WeightedFuzzyMean")) { w = p.basis() / universeRange; } else if (defuzzy.equals("GammaQuality")) { double aux = Math.pow(p.basis(), gamma); w = (1 / aux) / universeRange; } else if (defuzzy.equals("Quality")) { w = (1 / p.basis()) / universeRange; } } catch (Exception e) { new XfvhdlError(36, defuzzy); // err.show(); return 0; } return w; } /**@param input Funciones de pertenencia de una entrada. * @return Cadena representativa del tipo de las funciones * de pertenencia de una entrada en concreto.*/ public String tipo_input(XfsgInOrderMemFunc input) { String res; // !!! CUIDADO: El orden es importante ya que, como est� definido // actualmente, si sh_triang_fam es true tambi�n es true triang_fam if (sh_triang_fam(input)) res = "sh_triangular"; else if (triang_fam(input)) res = "triangular"; else if (triang_libres_norm_trap(input)) res = "sh_triangle"; else if (triang_libres_norm(input)) res = "triangle"; else res = "not found"; return res; } /**@param input Funciones de pertenencia de una entrada. * @return Indica si el tipo de las funciones * de pertenencia de la entrada son triangulos libres normalizados.*/ private boolean triang_libres_norm(XfsgInOrderMemFunc input) { try { boolean res = true; int size = input.getSize(); // comprueba primero que todos son triangulos libres for (int i = 0; i < size && res; i++) { LinguisticLabel mf = input.getMemFunc(i); if (mf instanceof ParamMemFunc) { String clase = mf.getClass().toString(); if (!clase.contains("triangle")) res = false; } else res = false; } if (res) { // comprueba si est�n normalizados for (int i = 1; i < size && res; i++) { if (roundNum(input.getMemFunc(i).get()[0]) != roundNum(input .getMemFunc(i - 1).get()[1])) res = false; if (i == size - 1) { if (roundNum(input.getMemFunc(i).get()[1]) != roundNum(input .getMemFunc(i - 1).get()[2])) res = false; /* * if (roundNum(input.getMemFunc(i).get()[0]) != * roundNum(input .getMemFunc(i - 1).get()[1])) res = * false; */ } } } return res; } catch (Exception e) { return false; } } /**@param input Funciones de pertenencia de una entrada. * @return Indica si el tipo de las funciones * de pertenencia de la entrada son triangulos libres normalizados * con saturaci�n en los extremos.*/ private boolean triang_libres_norm_trap(XfsgInOrderMemFunc input) { try { boolean res = true; boolean uno = false, dos = false, ambos = false; int size = input.getSize(); // comprueba que los extremos son trapecios y el restos triangulos // libres for (int i = 0; i < size && res; i++) { LinguisticLabel mf = input.getMemFunc(i); if (mf instanceof ParamMemFunc) { String clase = mf.getClass().toString(); if (i == 0) { if (clase.contains("trapezoid")) uno = true; else if (clase.contains("triangle")) uno = false; else res = false; } else if (i == size - 1) { if (clase.contains("trapezoid")) { dos = true; if (uno) ambos = true; } else if (clase.contains("triangle")) { dos = false; if (!uno) res = false; } else res = false; } else { if (!clase.contains("triangle")) res = false; } } else res = false; } if (res) { // comprueba si est�n normalizados (ambos extremos son // trapecios) if (ambos) { for (int i = 1; i < size && res; i++) { if (i == 1) { if (roundNum(input.getMemFunc(i).get()[0]) != roundNum(input .getMemFunc(i - 1).get()[2])) res = false; } else if (i == size - 1) { if (roundNum(input.getMemFunc(i).get()[0]) != roundNum(input .getMemFunc(i - 1).get()[1])) res = false; if (roundNum(input.getMemFunc(i).get()[1]) != roundNum(input .getMemFunc(i - 1).get()[2])) res = false; } else { if (roundNum(input.getMemFunc(i).get()[0]) != roundNum(input .getMemFunc(i - 1).get()[1])) res = false; } } } // comprueba si est�n normalizados (s�lo el primer extremo es // trapecio) else if (uno) { for (int i = 1; i < size && res; i++) { if (i == 1) { if (roundNum(input.getMemFunc(i).get()[0]) != roundNum(input .getMemFunc(i - 1).get()[2])) res = false; } else if (i == size - 1) { if (roundNum(input.getMemFunc(i).get()[0]) != roundNum(input .getMemFunc(i - 1).get()[1])) res = false; if (roundNum(input.getMemFunc(i).get()[1]) != roundNum(input .getMemFunc(i - 1).get()[2])) res = false; } else { if (roundNum(input.getMemFunc(i).get()[0]) != roundNum(input .getMemFunc(i - 1).get()[1])) res = false; } } } // comprueba si est�n normalizados (s�lo el segundo extremo es // trapecio) else if (dos) { for (int i = 1; i < size && res; i++) { if (i == 1) { if (roundNum(input.getMemFunc(i).get()[0]) != roundNum(input .getMemFunc(i - 1).get()[1])) res = false; } else if (i == size - 1) { if (roundNum(input.getMemFunc(i).get()[0]) != roundNum(input .getMemFunc(i - 1).get()[1])) res = false; if (roundNum(input.getMemFunc(i).get()[1]) != roundNum(input .getMemFunc(i - 1).get()[2])) res = false; } else { if (roundNum(input.getMemFunc(i).get()[0]) != roundNum(input .getMemFunc(i - 1).get()[1])) res = false; } } } } return res; } catch (Exception e) { return false; } } /**@param input Funciones de pertenencia de una entrada. * @return Indica si el tipo de las funciones * de pertenencia de la entrada es una familia de tri�ngulos.*/ private boolean triang_fam(XfsgInOrderMemFunc input) { try { boolean res = true; int size = input.getSize(); // comprueba que todos son de tipo triangular, es decir, // triangulos pertenecientes a una familia, y no libres for (int i = 0; i < size && res; i++) { LinguisticLabel mf = input.getMemFunc(i); if (mf instanceof FamiliarMemFunc) { String clase = ((FamiliarMemFunc) mf).getFamily() .getFunctionName(); if (!clase.contains("triangular")) res = false; } else res = false; } return res; } catch (Exception e) { return false; } } /**@param input Funciones de pertenencia de una entrada. * @return Indica si el tipo de las funciones * de pertenencia de la entrada es una familia de tri�ngulos * con saturaci�n en los extremos.*/ private boolean sh_triang_fam(XfsgInOrderMemFunc input) { try { boolean res = true; int size = input.getSize(); // comprueba que todos son de tipo triangular, es decir, // triangulos pertenecientes a una familia, y no libres, // excepto los extremos, que deben ser trapecios. for (int i = 0; i < size && res; i++) { LinguisticLabel mf = input.getMemFunc(i); if (mf instanceof FamiliarMemFunc) { String clase = ((FamiliarMemFunc) mf).getFamily() .getFunctionName(); if (!clase.contains("sh_triangular")) res = false; } else res = false; } return res; } catch (Exception e) { return false; } } //M�TODOS DE GENERACI�N DE FICHERO DE JERARQU�A /** * @param listaGlobales Lista de variables globales. * @param var Variable del sistema jer�rquico. * @return Indica si var es una variable interna, es decir, no es global.*/ public boolean variableInterna(ArrayList<String> listaGlobales, String var){ boolean interna=true; for(int i=0;i<listaGlobales.size();i++){ if(listaGlobales.get(i).equals(var)){ interna=false; i=listaGlobales.size(); } } return interna; } /**@return Tama�o de var a la salida del m�dulo al que est� conectada.*/ public String tamSalidaModuloConectada(String var,ModuleCall[] llamadas, ArrayList<XfvhdlFLC> listaFlc, ArrayList<XfvhdlCrisp> listaCrisp){ String No=""; int icrisp=0; int iflc=0; for(int i=0; i<llamadas.length;i++){ if(llamadas[i] instanceof RulebaseCall){//Modulo de inferencia RulebaseCall rb=(RulebaseCall) llamadas[i]; if(rb.getOutputVariables()[0].getName().equals(var)){ No=listaFlc.get(iflc).getname()+"_No"; } iflc++; }else{//Modulo crisp CrispBlockCall crisp=(CrispBlockCall) llamadas[i]; if(crisp.getOutputVariables()[0].getName().equals(var)){ No=listaCrisp.get(icrisp).getname()+"_No"; } icrisp++; } } return No; } /**@return M�nimo n� de bits entre los de la salida de un m�dulo y * los de la entrada del siguiente, cuando var es interna.*/ public int minimoBitsNoN(String var,ModuleCall[] llamadas, ArrayList<XfvhdlFLC> listaFlc, ArrayList<XfvhdlCrisp> listaCrisp, int bitsEntradaActual){ int minBits=bitsEntradaActual; int icrisp=0; int iflc=0; for(int i=0; i<llamadas.length;i++){ if(llamadas[i] instanceof RulebaseCall){//Modulo de inferencia RulebaseCall rb=(RulebaseCall) llamadas[i]; if(rb.getOutputVariables()[0].getName().equals(var)){ minBits=Math.min(minBits, listaFlc.get(iflc).getNo()); } iflc++; }else{//Modulo crisp CrispBlockCall crisp=(CrispBlockCall) llamadas[i]; if(crisp.getOutputVariables()[0].getName().equals(var)){ minBits=Math.min(minBits, listaCrisp.get(icrisp).getNo()); } icrisp++; } } return minBits; } /**@return M�ximo n� de bits entre los de la entrada a un m�dulo, y la * entrada global del sistema con la que se conecta.*/ public static int maximoBitsEntradaDeSistema(String var,ModuleCall[] llamadas, ArrayList<XfvhdlFLC> listaFlc, ArrayList<XfvhdlCrisp> listaCrisp){ int maxBits=0; int icrisp=0; int iflc=0; for(int i=0; i<llamadas.length;i++){ if(llamadas[i] instanceof RulebaseCall){//Modulo de inferencia RulebaseCall rb=(RulebaseCall) llamadas[i]; for(int j=0;j<rb.getInputVariables().length;j++){ if(rb.getInputVariables()[j].getName().equals(var)){ maxBits=Math.max(listaFlc.get(iflc).getN(), maxBits); } } iflc++; }else{//Modulo crisp CrispBlockCall crisp=(CrispBlockCall) llamadas[i]; for(int j=0;j<crisp.getInputVariables().length;j++){ if(crisp.getInputVariables()[j].getName().equals(var)){ maxBits=Math.max(listaCrisp.get(icrisp).getNo(), maxBits); } } icrisp++; } } return maxBits; } /**@return Bits adecuados para la salida del sistema.*/ public static int bitsSalidaSistema(String var,ModuleCall[] llamadas, ArrayList<XfvhdlFLC> listaFlc, ArrayList<XfvhdlCrisp> listaCrisp){ int bits=0; int icrisp=0; int iflc=0; for(int i=0; i<llamadas.length&&bits==0;i++){ if(llamadas[i] instanceof RulebaseCall){//Modulo de inferencia RulebaseCall rb=(RulebaseCall) llamadas[i]; for(int j=0;j<rb.getOutputVariables().length;j++){ if(rb.getOutputVariables()[j].getName().equals(var)){ bits=listaFlc.get(iflc).getNo(); } } iflc++; }else{//Modulo crisp CrispBlockCall crisp=(CrispBlockCall) llamadas[i]; for(int j=0;j<crisp.getOutputVariables().length;j++){ if(crisp.getOutputVariables()[j].getName().equals(var)){ bits=listaCrisp.get(icrisp).getNo(); } } icrisp++; } } return bits; } /**@return Nombre de variable o se�al que se conecta con una entrada * concreta de un m�dulo de inferencia.*/ public String conectarAEntrada(XfvhdlFLC flc, int entrada, ModuleCall[] llamadas, ArrayList<String> listaEntradasSistema,ArrayList<XfvhdlFLC> listaFlc,ArrayList<XfvhdlCrisp> listaCrisp){ String res="", nombreModulo=flc.getname(), nombreEntrada=""; boolean interna=true, se�alCrisp=false; int icrisp=0,iflc=0,ise�al=0; int N=60,No=60; for(int i=0; i<llamadas.length;i++){ if(llamadas[i] instanceof RulebaseCall){//Modulo de inferencia RulebaseCall rb=(RulebaseCall) llamadas[i]; if(rb.getName().equals(nombreModulo)){ nombreEntrada=rb.getInputVariables()[entrada].getName(); } iflc++; } } for(int i=0;i<listaEntradasSistema.size()&&interna;i++){ if(nombreEntrada.equals(listaEntradasSistema.get(i))) interna=false; } if(!interna){ res+=nombreEntrada+"("; } iflc=0; icrisp=0; for(int i=0; i<llamadas.length&&interna;i++){ if(llamadas[i] instanceof CrispBlockCall){//Bloque crisp CrispBlockCall crispB= (CrispBlockCall) llamadas[i]; //prjFile.addFile("vhdl work \""+XfvhdlProperties.name_outputfiles+".vhd\""); if(crispB.getName().equals(nombreModulo)){ nombreEntrada=crispB.getInputVariables()[entrada].getName(); N=listaCrisp.get(icrisp).getNo(); } if(crispB.getOutputVariable().getName().equals(nombreEntrada)){ No=listaCrisp.get(icrisp).getNo(); if(!se�alesjerarquia.contains("signal s_"+listaCrisp.get(icrisp).getname()+"_out")) se�alesjerarquia+=" signal s_"+listaCrisp.get(icrisp).getname()+"_out : std_logic_vector("+listaCrisp.get(icrisp).getname()+"_No);\n"; se�alCrisp=true; ise�al=icrisp; } icrisp++; }else{//Modulo de inferencia RulebaseCall rb=(RulebaseCall)llamadas[i]; if(rb.getOutputVariables()[0].getName().equals(nombreEntrada)){ No=listaFlc.get(iflc).getNo(); if(!se�alesjerarquia.contains("signal s_"+listaFlc.get(iflc).getname()+"_out")) se�alesjerarquia+=" signal s_"+listaFlc.get(iflc).getname()+"_out : std_logic_vector("+listaFlc.get(iflc).getname()+"_No);\n"; se�alCrisp=false; ise�al=iflc; } iflc++; } //nombreEntrada="s_"+llamadas[i].getName()+"_in" + (i + 1); } if(se�alCrisp&&interna){ //listaCrisp.get(ise�al).getNo() es la salida de un m�dulo crip //flc.getN() es la entrada del siguiente m�dulo de inferencia if(listaCrisp.get(ise�al).getNo()==flc.getN()){ asignaEntrada+="\ts_" + flc.getname()+"_in" + (entrada + 1)+" <= s_"+listaCrisp.get(ise�al).getname()+"_out;\n"; }else if(listaCrisp.get(ise�al).getNo()>flc.getN()){ asignaEntrada+="\ts_" + flc.getname()+"_in" + (entrada + 1)+" <= s_"+listaCrisp.get(ise�al).getname()+"_out" + "("+listaCrisp.get(ise�al).getNo()+" downto "+listaCrisp.get(ise�al).getNo()+"-"+flc.getname()+"_N+1);\n"; }else if(listaCrisp.get(ise�al).getNo()<flc.getN()){ asignaEntrada+="\ts_" + flc.getname()+"_in" + (entrada + 1)+" <= s_"+listaCrisp.get(ise�al).getname()+"_out &\""; for(int i=1; i <= (flc.getN()-listaCrisp.get(ise�al).getNo()) ;i++) asignaEntrada+="0"; asignaEntrada+="\";\n"; } }else if(!se�alCrisp&&interna){ //listaFlc.get(ise�al).getNo() es la salida de un m�dulo de inferencia //flc.getN() es la entrada del siguiente m�dulo de inferencia if(listaFlc.get(ise�al).getNo()==flc.getN()){ asignaEntrada+="\ts_" + flc.getname()+"_in" + (entrada + 1)+" <= s_"+listaFlc.get(ise�al).getname()+"_out;\n"; }else if(listaFlc.get(ise�al).getNo()>flc.getN()){ asignaEntrada+="\ts_" + flc.getname()+"_in" + (entrada + 1)+" <= s_"+listaFlc.get(ise�al).getname()+"_out" + "("+listaFlc.get(ise�al).getNo()+" downto "+listaFlc.get(ise�al).getNo()+"-"+flc.getname()+"_N+1);\n"; }else if(listaFlc.get(ise�al).getNo()<flc.getN()){ asignaEntrada+="\ts_" + flc.getname()+"_in" + (entrada + 1)+" <= s_"+listaFlc.get(ise�al).getname()+"_out &\""; for(int i=1; i <= (flc.getN()-listaFlc.get(ise�al).getNo()) ;i++) asignaEntrada+="0"; asignaEntrada+="\";\n"; } } if(interna){ res+="s_" + flc.getname()+"_in" + (entrada + 1); if(!se�alesjerarquia.contains("signal s_"+flc.getname()+"_in" + (entrada + 1))) se�alesjerarquia+=" signal s_"+flc.getname()+"_in" + (entrada + 1) + " : std_logic_vector("+flc.getname()+"_N downto 1);\n"; } return res; } /**@return Nombre de variable o se�al que se conecta con una entrada * concreta de un m�dulo crisp.*/ public String conectarAEntrada(XfvhdlCrisp crisp, int entrada, ModuleCall[] llamadas, ArrayList<String> listaEntradasSistema,ArrayList<XfvhdlFLC> listaFlc,ArrayList<XfvhdlCrisp> listaCrisp){ String res="", nombreModulo=crisp.getname(), nombreEntrada=crisp.cbc.getInputVariables()[entrada].getName(); boolean interna=true, se�alCrisp=false; String funcion_crisp=""; int icrisp=0,iflc=0,ise�al=0; int N=60,No=60; for(int i=0;i<listaEntradasSistema.size()&&interna;i++){ if(crisp.cbc.getInputVariables()[entrada].getName().equals(listaEntradasSistema.get(i))) interna=false; } if(!interna){ res+=nombreEntrada+"("; } icrisp=0; iflc=0; for(int i=0; i<llamadas.length&&interna;i++){ if(llamadas[i] instanceof CrispBlockCall){//Bloque crisp CrispBlockCall crispB= (CrispBlockCall) llamadas[i]; if(crispB.getName().equals(nombreModulo)){ nombreEntrada=crispB.getInputVariables()[entrada].getName(); N=listaCrisp.get(icrisp).getNo(); } if(crispB.getOutputVariable().getName().equals(nombreEntrada)){ No=listaCrisp.get(icrisp).getNo(); if(!se�alesjerarquia.contains("signal s_"+listaCrisp.get(icrisp).getname()+"_out")) se�alesjerarquia+=" signal s_"+listaCrisp.get(icrisp).getname()+"_out : std_logic_vector("+listaCrisp.get(icrisp).getname()+"_No);\n"; se�alCrisp=true; ise�al=icrisp; } icrisp++; }else{//Modulo de inferencia RulebaseCall rb=(RulebaseCall)llamadas[i]; if(rb.getOutputVariables()[0].getName().equals(nombreEntrada)){ No=listaFlc.get(iflc).getNo(); if(!se�alesjerarquia.contains("signal s_"+listaFlc.get(iflc).getname()+"_out")) se�alesjerarquia+=" signal s_"+listaFlc.get(iflc).getname()+"_out : std_logic_vector("+listaFlc.get(iflc).getname()+"_No);\n"; se�alCrisp=false; ise�al=iflc; } iflc++; } } for(int z=0;z<set_de_crisps.getBlocks().length;z++){ String aux=set_de_crisps.getBlocks()[z].getLabel(); if(aux.equalsIgnoreCase(crisp.getname())){ funcion_crisp= set_de_crisps.getBlocks()[z].getFunctionName();} } if(se�alCrisp&&interna){ //listaCrisp.get(ise�al).getNo() es la salida de un m�dulo //crisp.getNo() es la entrada del siguiente m�dulo if(funcion_crisp.equalsIgnoreCase("select")&& entrada==0){ asignaEntrada+="\ts_" + crisp.getname()+"_in" + (entrada + 1)+" <= s_"+listaCrisp.get(ise�al).getname()+"_out" + "("+listaCrisp.get(ise�al).getname()+"_No);\n"; }else{ if(listaCrisp.get(ise�al).getNo()==crisp.getNo()){ asignaEntrada+="\ts_" + crisp.getname()+"_in" + (entrada + 1)+" <= s_"+listaCrisp.get(ise�al).getname()+"_out;\n"; }else if(listaCrisp.get(ise�al).getNo()>crisp.getNo()){ asignaEntrada+="\ts_" + crisp.getname()+"_in" + (entrada + 1)+" <= s_"+listaCrisp.get(ise�al).getname()+"_out" + "("+listaCrisp.get(ise�al).getNo()+" downto "+listaCrisp.get(ise�al).getNo()+"-"+crisp.getname()+"_No+1);\n"; }else if(listaCrisp.get(ise�al).getNo()<crisp.getNo()){ asignaEntrada+="\ts_" + crisp.getname()+"_in" + (entrada + 1)+" <= s_"+listaCrisp.get(ise�al).getname()+"_out &\""; for(int i=1; i <= (crisp.getNo()-listaCrisp.get(ise�al).getNo()) ;i++) asignaEntrada+="0"; asignaEntrada+="\";\n"; } } }else if(!se�alCrisp&&interna){ //listaFlc.get(ise�al).getNo() es la salida de un m�dulo //crisp.getNo() es la entrada del siguiente m�dulo if(funcion_crisp.equalsIgnoreCase("select")&& entrada==0){ asignaEntrada+="\ts_" + crisp.getname()+"_in" + (entrada + 1)+" <= s_"+listaFlc.get(ise�al).getname()+"_out" + "("+listaFlc.get(ise�al).getname()+"_No);\n"; }else{ if(listaFlc.get(ise�al).getNo()==crisp.getNo()){ asignaEntrada+="\ts_" + crisp.getname()+"_in" + (entrada + 1)+" <= s_"+listaFlc.get(ise�al).getname()+"_out;\n"; }else if(listaFlc.get(ise�al).getNo()>crisp.getNo()){ asignaEntrada+="\ts_" + crisp.getname()+"_in" + (entrada + 1)+" <= s_"+listaFlc.get(ise�al).getname()+"_out" + "("+listaFlc.get(ise�al).getNo()+" downto "+listaFlc.get(ise�al).getNo()+"-"+crisp.getname()+"_No+1);\n"; }else if(listaFlc.get(ise�al).getNo()<crisp.getNo()){ asignaEntrada+="\ts_" + crisp.getname()+"_in" + (entrada + 1)+" <= s_"+listaFlc.get(ise�al).getname()+"_out &\""; for(int i=1; i <= (crisp.getNo()-listaFlc.get(ise�al).getNo()) ;i++) asignaEntrada+="0"; asignaEntrada+="\";\n"; } } } if(interna){ res+="s_" + crisp.getname()+"_in" + (entrada + 1); if(!se�alesjerarquia.contains("signal s_"+crisp.getname()+"_in" + (entrada + 1))){ if(funcion_crisp.equalsIgnoreCase("select")&& entrada==0){ se�alesjerarquia+=" signal s_"+crisp.getname()+"_in1 : std_logic;\n"; }else se�alesjerarquia+=" signal s_"+crisp.getname()+"_in" + (entrada + 1) + " : std_logic_vector("+crisp.getname()+"_No downto 1);\n"; } } return res; } /**@param listaFlc lista de todos los m�dulos de inferencia del * sistema jer�rquico. * @param listaCrisp lista de todos los m�dulos crisp del * sistema jer�rquico. * @return C�digo VHDL del nivel de la jerarqu�a del sistema jer�rquico.*/ public String generaJerarquia(ArrayList<XfvhdlFLC> listaFlc, ArrayList<XfvhdlCrisp> listaCrisp){ ArrayList<String> listaVblesSistema=new ArrayList<String>(), listaEntradasSistema=new ArrayList<String>(); ArrayList<String> listaSe�alesInternas=new ArrayList<String>(); String conectaAsalida; int entradasSistema=spec.getSystemModule().getInputs().length; for (int i=0;i<entradasSistema;i++){ listaVblesSistema.add(spec.getSystemModule().getInputs()[i].getName()); listaEntradasSistema.add(spec.getSystemModule().getInputs()[i].getName()); } for (int i=0;i<spec.getSystemModule().getOutputs().length;i++){ listaVblesSistema.add(spec.getSystemModule().getOutputs()[i].getName()); } ArrayList<XfvhdlFLC> flcs=listaflc; String jerarquia=""; String cadena_WORK=""; String constantes_crisp=""; String inputs="",outputs="",componentes="", entradasComponent, modulosPortMap="", inputsPortMap; //Esta lista contendr� todas las salidas del sistema para //poder conectarla a la se�al interna que le corresponda String[] outsSystem=new String[listaVblesSistema.size()-entradasSistema];; for (int i=0;i<listaflc.size();i++){ cadena_WORK+="use WORK."+listaflc.get(i).getname()+"_Constants.all;\n"; } for(int i=0;listaCrisp!=null && i<listaCrisp.size();i++){ constantes_crisp+="\tconstant "+listaCrisp.get(i).getname()+"_No : integer := "+listaCrisp.get(i).getNo()+";\n"; } if((listaflc.size()+listacrisp.size())==1) return null; for(int i=0;i<listaVblesSistema.size();i++){ if(i<entradasSistema) inputs+="\t\t"+listaVblesSistema.get(i)+" : in std_logic_vector("+maximoBitsEntradaDeSistema(listaVblesSistema.get(i),spec.getSystemModule().getModuleCalls(),listaFlc,listaCrisp)+" downto 1); -- Input "+(i+1)+" signal.\n"; else{ outputs+="\t\t"+listaVblesSistema.get(i)+" : out std_logic_vector("+bitsSalidaSistema(listaVblesSistema.get(i),spec.getSystemModule().getModuleCalls(),listaFlc,listaCrisp)+" downto 1); -- Output "+(i-entradasSistema+1)+" signal.\n"; outsSystem[i-entradasSistema]=listaVblesSistema.get(i); } } //recorremos los modulescall ModuleCall[] llamadas=spec.getSystemModule().getModuleCalls(); int iflc=0,icrisp=0; String variable; String funcion_crisp=""; boolean pipelineConectado=false; String conexionPipeline=" pipeline => pipeline);\n\n"; for (int i=0;i<llamadas.length;i++){ entradasComponent=""; inputsPortMap=""; if(llamadas[i] instanceof RulebaseCall){//Modulo de inferencia for(int j=0;j<llamadas[i].getNumberOfInputs();j++){ boolean interna=true; //Ayoma for(int k=0;k<listaVblesSistema.size();k++){//�Es una variable interna? if(llamadas[i].getInputVariables()[j].getName().equals(listaVblesSistema.get(k))) interna=false; } XfvhdlFLC flc=listaFlc.get(iflc); entradasComponent+=" in"+(j+1)+" : in std_logic_vector("+flcs.get(iflc).getname()+"_N downto 1);\n"; variable=llamadas[i].getInputVariables()[j].getName(); String tamDownto="", tam=""; if(interna){ //tam=tamSalidaModuloConectada(variable,llamadas,listaFlc,listaCrisp); //tamDownto+=minimoBitsNoN(variable,llamadas,listaFlc,listaCrisp,listaFlc.get(iflc).getN())+")"; }else{ tam=String.valueOf(maximoBitsEntradaDeSistema(variable,llamadas,listaFlc,listaCrisp)); tamDownto+=" downto ("+maximoBitsEntradaDeSistema(variable,llamadas,listaFlc,listaCrisp) +"-"+flcs.get(iflc).getname()+"_N+1))"; } //flcs.get(iflc) String conectaAentrada=conectarAEntrada(flc,j,llamadas,listaEntradasSistema,listaFlc,listaCrisp); inputsPortMap+=" in"+(j+1)+" => " + conectaAentrada +(!conectaAentrada.startsWith("s_")?(tam+tamDownto):"") +",\n"; //inputsPortMap+=" in"+(j+1)+" => " // +conectarAEntrada(flcs.get(iflc),j,llamadas,listaEntradasSistema,listaFlc,listaCrisp) // +tam // +tamDownto+",\n"; } iflc++; }else{//Bloque crisp for(int j=0;j<llamadas[i].getNumberOfInputs();j++){ boolean interna=true; for(int k=0;k<listaVblesSistema.size();k++){//�Es una variable interna? if(llamadas[i].getInputVariables()[j].getName().equals(listaVblesSistema.get(k))) interna=false; } XfvhdlCrisp crisp=listaCrisp.get(icrisp); entradasComponent+=" in"+(j+1)+" : in std_logic_vector("+llamadas[i].getName()+"_No downto 1);\n"; variable=llamadas[i].getInputVariables()[j].getName(); String tamDownto="", tam=""; if(interna){ //tam=tamSalidaModuloConectada(variable,llamadas,listaFlc,listaCrisp); //tamDownto+=minimoBitsNoN(variable,llamadas,listaFlc,listaCrisp,listaCrisp.get(icrisp).getNo())+")"; }else{ tam=String.valueOf(maximoBitsEntradaDeSistema(variable,llamadas,listaFlc,listaCrisp)); tamDownto+=" downto (" + maximoBitsEntradaDeSistema(variable,llamadas,listaFlc,listaCrisp) +"-"+crisp.getname()+"_No+1))"; } String conectaAentrada=conectarAEntrada(crisp,j,llamadas,listaEntradasSistema,listaFlc,listaCrisp); inputsPortMap+=" in"+(j+1)+" => " + conectaAentrada +(!conectaAentrada.startsWith("s_")?(tam+tamDownto):"") +",\n"; } for(int z=0;z<set_de_crisps.getBlocks().length;z++){ String aux=set_de_crisps.getBlocks()[z].getLabel(); if(aux.equalsIgnoreCase(llamadas[i].getName())){ funcion_crisp= set_de_crisps.getBlocks()[z].getFunctionName();} } if(funcion_crisp.equalsIgnoreCase("select")){ funcion_crisp="selector";//select es una palabra reservada en VHDL } //add2, diff2, prod //Comprobamos si est� o no conectado a la salida conectaAsalida=null; for(int l=0;l<outsSystem.length;l++){ if(llamadas[i].getOutputVariables()[0].equals(outsSystem[l])) conectaAsalida=outsSystem[l]; } modulosPortMap+=" "+XfvhdlProperties.name_outputfiles+"_" + llamadas[i].getName()+" : "+funcion_crisp+"\n" + " generic map (\n" + " No => "+llamadas[i].getName()+"_No)\n" + " port map (\n" + inputsPortMap+ " out1 => s_"+llamadas[i].getName()+"_out);\n\n" + (conectaAsalida!=null ? " " + conectaAsalida + " <= s_"+llamadas[i].getName()+"_out;\n\n" :""); if(!se�alesjerarquia.contains("s_"+llamadas[i].getName()+"_out")) se�alesjerarquia+=" signal s_"+llamadas[i].getName()+"_out : " + "std_logic_vector("+llamadas[i].getName()+"_No downto 1);\n"; ; icrisp++; } String cadenapipebits=""; if(llamadas[i] instanceof RulebaseCall){ cadenapipebits=" generic(\n"+ " "+llamadas[i].getName()+"_pipe: integer;\n"+ " "+llamadas[i].getName()+"_bits: integer);\n"; componentes+=" component "+llamadas[i].getName()+"\n\n"+ cadenapipebits+ " port (\n"+ " clk : in std_logic;\n"+ " reset : in std_logic;\n"+ entradasComponent+ " out1 : out std_logic_vector("+llamadas[i].getName()+"_No downto 1);\n"+ " pipeline : out std_logic);\n\n"+ " end component;\n\n" ; } String auxpipebits=""; if(llamadas[i] instanceof RulebaseCall){ //Comprobamos si est� o no conectado a la salida conectaAsalida=null; if(pipelineConectado) conexionPipeline=" pipeline => s_pipeline);\n\n"; for(int l=0;l<outsSystem.length;l++){ if(llamadas[i].getOutputVariables()[0].equals(outsSystem[l])) conectaAsalida=outsSystem[l]; } auxpipebits+=" generic map(\n"+ " "+llamadas[i].getName()+"_pipe => max_pipe,\n"+ " "+llamadas[i].getName()+"_bits => max_bits)\n"; modulosPortMap+=" "+XfvhdlProperties.name_outputfiles+"_"+llamadas[i].getName()+": "+llamadas[i].getName()+"\n"+ auxpipebits+ " port map(\n"+ " clk => clk,\n"+ " reset => reset,\n"+ inputsPortMap+ " out1 => s_"+llamadas[i].getName()+"_out,\n"+ conexionPipeline + (conectaAsalida!=null ? " " + conectaAsalida + " <= s_"+llamadas[i].getName()+"_out;\n\n" :""); if(!se�alesjerarquia.contains("s_pipeline")) se�alesjerarquia+=" signal s_pipeline : " + "std_logic;\n"; if(!se�alesjerarquia.contains("s_"+llamadas[i].getName()+"_out")) se�alesjerarquia+=" signal s_"+llamadas[i].getName()+"_out : " + "std_logic_vector("+llamadas[i].getName()+"_No downto 1);\n"; pipelineConectado=true; } } componentes+=" constant max_pipe: integer:="+XfvhdlProperties.pipemax+";\n"+ " constant max_bits: integer:="+XfvhdlProperties.bitsmax+";\n"; //recorremos los modulescall jerarquia+= "---------------------------------------------------------------------------\n"+ "-- Entity description --\n"+ "---------------------------------------------------------------------------\n\n"+ "library IEEE;\n"+ "use IEEE.std_logic_1164.all;\n"+ "use IEEE.std_logic_arith.all;\n"+ "use IEEE.std_logic_unsigned.all;\n\n" + "library XfuzzyLib;\n" + "use XfuzzyLib.Entities.all;\n\n" + cadena_WORK+ "\n" + "entity "+XfvhdlProperties.name_outputfiles+" is\n\n" + " port(\n" + " clk : in std_logic; -- Clock signal.\n" + " reset : in std_logic; -- Reset signal.\n" + inputs+ outputs+ " pipeline : out std_logic); -- Pipeline signal\n\n" + "end "+XfvhdlProperties.name_outputfiles+";\n\n" + "---------------------------------------------------------------------------\n"+ "-- Architecture description --\n"+ "---------------------------------------------------------------------------\n\n"+ "architecture FPGA of "+XfvhdlProperties.name_outputfiles+" is\n\n" + constantes_crisp+ componentes+ se�alesjerarquia+"\n" + "begin\n\n" + asignaEntrada + "\n" + modulosPortMap+ "\n\n"+ "end FPGA;\n" ; return jerarquia; } public void addToPrjCrispFunction(XfvhdlPrjFile prjFile){ ModuleCall[] llamadas=spec.getSystemModule().getModuleCalls(); for(int i=0; i<llamadas.length;i++){ if(llamadas[i] instanceof CrispBlockCall){//Bloque crisp CrispBlockCall crispB= (CrispBlockCall) llamadas[i]; prjFile.addFile("vhdl XfuzzyLib \"" + XfvhdlProperties.libraryDirectory + XfvhdlProperties.fileSeparator+crispB.getCrispBlock().getFunctionName()+".vhd\""); } } } }