//--------------------------------------------------------------------------------//
// 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. //
//--------------------------------------------------------------------------------//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// HERRAMIENTA DE S�NTESIS: XFVHDL
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
package xfuzzy.xfvhdl;
import xfuzzy.*;
import xfuzzy.lang.*;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.ArrayList;
import javax.swing.tree.DefaultMutableTreeNode;
/**
* Clase principal de la herramienta de s�ntesis Xfvhdl
*
* @author Lidia Lavinia Delgado Carretero
*
*/
public class Xfvhdl {
//ATRIBUTOS DE LA CLASE
/**
* Atributo que apunta al objeto Xfuzzy, siempre y cuando
* se ejecute desde Xfuzzy y no desde consola.
*/
public static Xfuzzy xfuzzy = null;
/** Aqu� se guarda el contenido del fichero con extensi�n .prj*/
private XfvhdlPrjFile prjFile = new XfvhdlPrjFile();
/** Atributo encargado de mostrar mensajes en la interfaz gr�fica
* de Xfuzzy*/
XfvhdlMessage msg = new XfvhdlMessage(xfuzzy);
/** Lista que almacena todos los m�dulos de inferencia del sistema
* jer�rquico.*/
private ArrayList<XfvhdlFLC> listaFlc;
/** Lista que almacena todos los m�dulos crisp del sistema
* jer�rquico.*/
private ArrayList<XfvhdlCrisp> listaCrisp;
/**
* Atributo que hace de bandera para cerrar la ventana de la
* herramienta en el caso de que se produzca alg�n fallo que
* requiera su cierre.
*/
public static boolean cerrarWindow;
/**
* M�todo constructor de la clase. A partir de una especificaci�n
* XFL y el �rbol del sistema difuso, inicializa las variables est�ticas
* definidas en XfvhdlProperties, y que sirven de variables globales
* para todo el paquete. Es tambi�n aqu� donde se crean la mayor�a de
* ficheros de salida y donde se llaman a las herramientas de s�ntesis
* e implementaci�n si es necesario.
* @param spec Especificaci�n XFL
* @param top �rbol del sistema difuso
*/
public Xfvhdl(Specification spec, DefaultMutableTreeNode top) throws IOException {
listaCrisp=new ArrayList<XfvhdlCrisp>();
listaFlc=new ArrayList<XfvhdlFLC>();
// Dependiendo del m�todo de defuzzificaci�n se incluir�
// una etapa de salida simplificada
XfvhdlProperties.simplified_division = false;
if (XfvhdlProperties.defuzzification_type.equalsIgnoreCase("MaxLabel")) {
XfvhdlProperties.simplified_division = true;
}
if (XfvhdlProperties.defuzzification_type.equalsIgnoreCase("FuzzyMean")
&& XfvhdlProperties.simplifiedComponents == true) {
XfvhdlProperties.simplified_division = true;
}
// Crea e inicializa un objeto error
XfvhdlError error = new XfvhdlError();
String state = new String("Done");
// Activa el log si se est� ejecutando desde la ventana gr�fica
if (XfvhdlProperties.inWindow == true)
msg.setXfuzzy(xfuzzy);
//Codigo nuevo
String aux="";
XfvhdlFLC nodeflc=null;
int n = top.getChildCount();
cerrarWindow = false;
for (int i = 0; i < n && !cerrarWindow ; i++) {
DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) top
.getChildAt(i);
aux = genera_texto_rama(dmtn, spec);
if(aux.startsWith("error")){
cerrarWindow = true;
int numError= Integer.valueOf(aux.substring(6, 8));
new XfvhdlError(numError, aux.substring(8) + ".");
}
}
if(!cerrarWindow){
XfvhdlLeerXfl xfl = new XfvhdlLeerXfl(spec);
xfl.inicializarFLCs();
xfl.addToPrjCrispFunction(prjFile);
prjFile.addLibBlocks(listaFlc);
String jerarquia=xfl.generaJerarquia(listaFlc,listaCrisp);
String testBenchJerarquia="";
XfvhdlTestBenchFile tbj=new XfvhdlTestBenchFile();
if (jerarquia!=null){//Devuelve null cuando s�lo hay un m�dulo de inferencia
prjFile.addFile("vhdl work \""+XfvhdlProperties.name_outputfiles+".vhd\"");
new XfvhdlCreateFile(
XfvhdlProperties.name_outputfiles+".vhd",
jerarquia);
msg.addMessage(
"\n>>>> Generating file: "
+ XfvhdlProperties.name_outputfiles
+ ".vhd");
if (error.hasErrors())
state = "With error";
msg.addMessage(" ......... " + state);
msg.show();
//Ahora se genera el test bench del nivel jer�rquico
testBenchJerarquia=tbj.createTestBenchSource(spec, null,listaFlc,listaCrisp);
new XfvhdlCreateFile(
XfvhdlProperties.name_outputfiles+"_tb.vhd",
testBenchJerarquia);
msg.addMessage(
"\n>>>> Generating file: "
+ XfvhdlProperties.name_outputfiles
+ "_tb.vhd");
if (error.hasErrors())
state = "With error";
msg.addMessage(" ......... " + state);
msg.show();
}
// ****************************************************************
// ************** Creando el fichero prj **************************
// ****************************************************************
// *** Este fichero se genera cuando la herramienta de s�ntesis
// *** es Xilinx XST
// ****************************************************************
if (XfvhdlProperties.synthesisTool.equals((String) "XILINX_XST")) {
msg.addMessage(
">>>> Generating file: "
+ XfvhdlProperties.name_outputfiles
+ ".prj");
// Crea el fichero .prj.
new XfvhdlCreateFile(
XfvhdlProperties.name_outputfiles + ".prj",
prjFile.getPrj());
if (error.hasErrors())
state = "With error";
msg.addMessage(" ......... " + state);
msg.show();
}
// ************* !! Fichero .prj creado �� ************************
// ****************************************************************
// ************** Creando el fichero de script XST ****************
// ****************************************************************
// *** Este fichero se genera cuando la herramienta de s�ntesis
// *** es Xilinx XST
// ****************************************************************
if (XfvhdlProperties.synthesisTool.equals((String) "XILINX_XST")) {
msg.addMessage(
">>>> Generating file: "
+ XfvhdlProperties.name_outputfiles
+ "Script.xst");
XfvhdlScriptXstFile ScriptXstFile = new XfvhdlScriptXstFile();
// Crea el fichero de script
new XfvhdlCreateFile(
XfvhdlProperties.name_outputfiles + "Script.xst",
ScriptXstFile.createScriptXstSource());
if (error.hasErrors())
state = "With error";
msg.addMessage(" ......... " + state);
msg.show();
}
// ************* !! Fichero de script XST creado �� **************
// ****************************************************************
// ************** Creando el fichero de script FST ****************
// ****************************************************************
// *** Este fichero se genera cuando la herramienta de s�ntesis
// *** es una de las herramientas de synopsys
// ****************************************************************
if (XfvhdlProperties.synthesisTool.equals((String) "FPGA_Express")
|| XfvhdlProperties.synthesisTool.equals(
(String) "FPGA_Compiler_2")) {
msg.addMessage(
">>>> Generating file: "
+ XfvhdlProperties.name_outputfiles
+ "Script.fst");
XfvhdlScriptFile ScriptFile = new XfvhdlScriptFile();
// Crea el fichero de script
new XfvhdlCreateFile(
XfvhdlProperties.name_outputfiles + "Script.fst",
ScriptFile.createScriptSource());
if (error.hasErrors())
state = "With error";
msg.addMessage(" ......... " + state);
msg.show();
}
// ************* !! Fichero de script FST creado �� **************
//XfvhdlProperties.simplifiedComponents = false;
//XfvhdlProperties.complementaryFiles = false;
}
}
/**M�todo que genera los ficheros de extensi�n .vhd correspondientes
* a los m�dulos de inferencia y a los m�dulos crisp, tambi�n genera
* los ficheros de test bench de estos m�dulos.
* @param node Nodo padre a partir del cual recorremos el sistema jer�rquico.
* @param spec Especificaci�n XFL.*/
public String genera_texto_rama(DefaultMutableTreeNode node, Specification spec) throws IOException {
// Crea e inicializa un objeto error
XfvhdlError error = new XfvhdlError();
String state = new String("Done");
// contiene la informaci�n a escribir en el archivo .vhd
String code = "";
String testBench="";
String res;
int n = node.getChildCount();
for (int i = 0; i < n; i++) {
DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) node
.getChildAt(i);
Object o = dmtn.getUserObject();
if (o instanceof XfvhdlFLC) {
XfvhdlFLC f1 = (XfvhdlFLC) o;
if(f1.compruebaPbAdecuado()==false)
return "error" + " " + 39 + f1.getname();
}
}
String nombre_i="";
int regla_i=-1;
for (int i = 0; i < n; i++) {
DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) node
.getChildAt(i);
Object o = dmtn.getUserObject();
if (o instanceof XfvhdlFLC) {
regla_i++;
XfvhdlFLC f1 = (XfvhdlFLC) o;
nombre_i=f1.getname();
// ****************************************************************
// ************ Creando el fichero vhd de cada flc ****************
// ****************************************************************
// *** Este fichero se genera siempre, independientemente de la
// *** opci�n elegida para implementar la memoria
// ****************************************************************
f1.generaVHDL(spec,nombre_i);
code = f1.getVHDL();
new XfvhdlCreateFile(
f1.getname()+".vhd",
code);
msg.addMessage(
">>>> Generating file: "
+ f1.getname()+".vhd");
if (error.hasErrors())
state = "With error";
msg.addMessage(" ......... " + state);
msg.show();
if (XfvhdlProperties.complementaryFiles == true) {
msg.addMessage(
">>>> Generating rules memory's "
+ "complementary files ");
f1.generaComplementarios(nombre_i);
if (error.hasErrors())
state = "With error";
msg.addMessage(" ......... " + state);
msg.show();
}
// ****************************************************************
// ************** Creando los testbench ****************************
// ****************************************************************
// *** Este fichero se genera siempre, independientemente de la
// *** opci�n elegida para implementar la memoria
// ****************************************************************
testBench=f1.getTestBench(spec);
new XfvhdlCreateFile(
f1.getname()+"_tb.vhd",
testBench);
msg.addMessage(
">>>> Generating file: "
+ f1.getname()+"_tb.vhd");
if (error.hasErrors())
state = "With error";
msg.addMessage(" ......... " + state);
msg.show();
listaFlc.add(f1);
} else if (o instanceof XfvhdlCrisp) {
XfvhdlCrisp c1 = (XfvhdlCrisp) o;
c1.generaVHDL();
code += c1.getVHDL();
listaCrisp.add(c1);
}
}
res = code;
XfvhdlError err = new XfvhdlError();
// System.out.println(err.hasErrors());
if (err.hasErrors() || err.hasWarnings()) {
msg.addMessage(err.getMessages());
msg.show();
err.resetAll();
}
return res;
}
/**Este m�todo es el m�todo principal de la clase, aunque s�lo es
* llamado cuando lanzamos la aplicaci�n desde un terminal de comandos.*/
public static void main(String[] args) throws IOException {
// Trata los par�metros que se pasan desde la l�nea de comandos
XfvhdlParameter param = new XfvhdlParameter(args);
param.loadParameter();
// A partir de aqu� depende si la aplicaci�n se ejecuta desde la
// consola o desde una ventana
if (XfvhdlProperties.inWindow == false) {
// EJECUTAMOS DESDE LA CONSOLA
// Lee el fichero XFL y le pasa el parser
XflParser xflparser = new XflParser();
XfvhdlMessage msg2 = new XfvhdlMessage(xfuzzy);
msg2.addMessage(">>>> File Syntax Analysis:");
msg2.show();
Specification spec = xflparser.parse(XfvhdlProperties.ficheroXFL);
DefaultMutableTreeNode top = new DefaultMutableTreeNode(spec.getName());
msg2.addMessage(" Correct File Syntax.\n");
msg2.show();
XfvhdlWindow window;
if(spec!=null){
window = new XfvhdlWindow(null,spec);
window.setVisible(false);
if(XfvhdlProperties.synthesis)
window.generateVHDLCodeAndSynthetize();
else if(XfvhdlProperties.implementation)
window.generateVHDLCodeAndImplement();
else
window.generateVHDLCode();
}else{//Ha dado fallo al cargar la especificaci�n
XfvhdlError err = new XfvhdlError(6);
err.show();
System.exit(-1);
}
} else {
// EJECUTAMOS DESDE UNA VENTANA
XflParser xflparser = new XflParser();
String ruta=XfvhdlProperties.ficheroXFL;
Specification sp = xflparser.parse(XfvhdlProperties.ficheroXFL);
if(sp!=null){
XfvhdlWindow window = new XfvhdlWindow(null,sp);
window.setVisible(true);}
else{//Ha dado fallo al cargar la especificaci�n
XfvhdlError err = new XfvhdlError(6);
err.show();
System.exit(-1);
}
}
}
/**Este m�todo es llamado siempre que se lanza la herramienta, aunque si
* es llamado cuando hemos lanzado la herramienta desde un terminal,
* hay que leer los par�metros pasados por el usuario desde consola.*/
public static void inConsoleExecution(Specification spec, DefaultMutableTreeNode top,String args[])
throws IOException {
// Aunque estamos dentro de la ejecuci�n desde consola, en verdad,
// este m�todo se ejecuta siempre,la diferencia es que si antes hemos
// mostrado la ventana gr�fica, ahora hay que leer los par�metros
// que se pasan desde ella
XfvhdlMessage msg2 = new XfvhdlMessage(xfuzzy);
// Saca la informaci�n necesaria del conjunto de operadores,
// tales como el m�todo de defuzzificaci�n y la operaci�n AND.
Operatorset[] opset = spec.getOperatorsets();
String opAnd = opset[0].and.getFunctionName();
String defuzMethod = opset[0].defuz.getFunctionName();
if (opAnd.equalsIgnoreCase("min") || opAnd.equalsIgnoreCase("prod"))
XfvhdlProperties.operationAnd = opAnd;
else {
XfvhdlError err = new XfvhdlError();
err.newWarning(28);
}
XfvhdlProperties.defuzzification_type = defuzMethod;
// Llama al constructor de la clase con la espeficicaci�n del sistema
new Xfvhdl(spec,top);
// Muestra por pantalla los errores que se han producido
XfvhdlError error = new XfvhdlError();
error.show();
if(cerrarWindow){
//XfvhdlError err4 = new XfvhdlError(39,""+"");
//err4.show();
return;
}
// Lanza la herramienta de s�ntesis -si procede-
if (XfvhdlProperties.synthesis == true) {
//No puede haber errores
if (error.hasErrors()) {
XfvhdlError err4 = new XfvhdlError(24);
err4.show();
return;
}
String command1 = new String();
//Depende de la herramienta que se haya indicado
if (XfvhdlProperties.synthesisTool.equals((String) "XILINX_XST")) {
// Crea una cadena con la ruta del directorio que necesita
// crear, y luego lo crea
String hola =
new String(
""
+ XfvhdlProperties.outputDirectory
+ XfvhdlProperties.fileSeparator
+ XfvhdlProperties.name_outputfiles
+ "_synthesis");
File temp = new File(hola);
temp.mkdirs();
msg2.addMessage("\n\n>>>> Running Xilinx XST\n");
command1 =
"xst -ifn "
+ XfvhdlProperties.outputDirectory
+ "/"
+ XfvhdlProperties.name_outputfiles
+ "Script.xst -ofn "
+ XfvhdlProperties.outputDirectory
+ "/"
+ XfvhdlProperties.name_outputfiles
+ ".log";
} else if (
XfvhdlProperties.synthesisTool.equals(
(String) "FPGA_Express")) {
msg2.addMessage("\n\n>>>> Running Synopsys FPGA Express\n");
command1 =
"fe_shell -oem xilinx -f "
+ XfvhdlProperties.outputDirectory
+ "/"
+ XfvhdlProperties.name_outputfiles
+ "Script.fst";
} else if (
XfvhdlProperties.synthesisTool.equals(
(String) "FPGA_Compiler_2")) {
msg2.addMessage("\n\n>>>> Running Synopsys FPGA Compiler 2\n");
command1 =
"fc2_shell -f "
+ XfvhdlProperties.outputDirectory
+ "/"
+ XfvhdlProperties.name_outputfiles
+ "Script.fst | tee "
+ XfvhdlProperties.outputDirectory
+ "/"
+ XfvhdlProperties.name_outputfiles
+ ".log";
} else {
XfvhdlError err5 = new XfvhdlError(0);
err5.show();
return;
}
//Muestra un mensaje de informaci�n
msg2.show();
// Ejecuta la herramienta externa, mostrando por pantalla
// la salida de dicha herramienta
try {
String line;
msg2.addMessage("\n Executing...<" + command1 + ">");
msg2.show();
Process p = Runtime.getRuntime().exec(command1);
BufferedReader input =
new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
// Escribe la salida por pantalla, pero ojo,
// todo ser� escrito por la consola, por lo que
// si la aplicaci�n fue lanzada desde Xfuzzy, la
// salida NO es mostrada en el log de �ste, sino
// en la consola
System.out.println(line);
}
input.close();
} catch (Exception err) {
// Se ha producido un error en la ejecuci�n
XfvhdlError err5 = new XfvhdlError(25);
err5.show();
return;
}
}
// Lanza la herramienta de implementaci�n -si procede-
if (XfvhdlProperties.implementation == true) {
//No puede haber errores
if (error.hasErrors()) {
XfvhdlError err7 = new XfvhdlError(27);
err7.show();
return;
}
String command1 = new String();
String command2 = new String();
//Muestra un mensaje de informaci�n
msg2.addMessage("\n\n>>>> Running Xilinx Xflow \n");
msg2.show();
//Depende de la herramienta que se haya indicado
if (XfvhdlProperties.synthesisTool.equals((String) "XILINX_XST")) {
command1 =
"xflow -implement balanced.opt -wd "
+ XfvhdlProperties.outputDirectory
+ "/"
+ XfvhdlProperties.name_outputfiles
+ "_implement "
+ XfvhdlProperties.outputDirectory
+ "/"
+ XfvhdlProperties.name_outputfiles
+ "_synthesis/"
+ XfvhdlProperties.name_outputfiles
+ ".ngc";
} else {
command1 =
"xflow -implement balanced.opt �wd "
+ XfvhdlProperties.name_outputfiles
+ "_implement "
+ XfvhdlProperties.name_outputfiles
+ "_synthesis/FLC.edf";
}
command2 =
"xflow -config bitgen.opt -wd "
+ XfvhdlProperties.outputDirectory
+ XfvhdlProperties.fileSeparator
+ XfvhdlProperties.name_outputfiles
+ "_implement "
+ XfvhdlProperties.outputDirectory
+ XfvhdlProperties.fileSeparator
+ XfvhdlProperties.name_outputfiles
+ "_implement/"
+ XfvhdlProperties.name_outputfiles
+ ".ncd";
// Ejecuta la herramienta externa, mostrando por pantalla
// la salida de dicha herramienta
try {
String line;
msg2.addMessage("\n Executing...<" + command1 + ">");
msg2.show();
Process p = Runtime.getRuntime().exec(command1);
BufferedReader input =
new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
} catch (Exception err) {
XfvhdlError err5 = new XfvhdlError(25);
err5.show();
return;
}
try {
String line;
msg2.addMessage("\n Executing...<" + command2 + ">");
msg2.show();
Process p = Runtime.getRuntime().exec(command2);
BufferedReader input =
new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
System.out.println(line);
}
input.close();
} catch (Exception err) {
XfvhdlError err5 = new XfvhdlError(25);
err5.show();
return;
}
}
// Termina la aplicaci�n.
}
} // FIN DE LA CLASE Xfvhdl.