//--------------------------------------------------------------------------------//
// 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.Date;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import java.security.acl.Group;
import java.util.ArrayList;
import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.border.Border;
import xfuzzy.lang.RulebaseCall;
import xfuzzy.lang.Specification;
import xfuzzy.lang.Variable;
import xfuzzy.util.XConstants;
import xfuzzy.util.XLabel;
import xfuzzy.util.XTextForm;
import xfuzzy.xfsg.XfsgOutData;
/**
* Clase que implementa la interfaz XvhdlBlock. Se utiliza para almacenar la
* informaci�n relativa a una base de reglas.
*
* @author Lidia Delgado Carretero
*/
public class XfvhdlFLC implements XfvhdlBlock {
private static final long serialVersionUID = -4981662902071901357L;
/**Nombre del FLC.*/
private String name = "";
/**Grupo para arithmetic o memory.*/
ButtonGroup group1;
/**RadioButton para arithmetic.*/
JRadioButton arithmetic;
/**RadioButton para memory.*/
JRadioButton memory;
/**N� bits entrada.*/ // Bitsize of input
private int N;
/**N� bits grado de pertenencia.*/ // Bitsize of membership degree /
private int grad;
/**N� bits para la pendiente.*/ // Bitsize of MF slope /
private int P;
/**N� bits salida.*/ // Bitsize of output
private int No;
/**N� bits para el peso de defuzzificaci�n.*/ // Bits for defuzzification weight
private int W;
/**Array de mfcs*/
private ArrayList<MFC> mfcs;
/**Lista de enteros de bits asociados a las reglas de cada entrada.*/
private ArrayList<Integer> bits_var;
/**Base de reglas.*/ // Rule Base
private ArrayList<XfsgOutData> RB;
/**Conectivo de antecedentes.*/
private String connective;
/**Atributo que indica si el usuario nos ha proporcionado todos los
* datos relativos al m�dulo de inferencia.*/
private boolean todo_relleno;
/**M�todo de defuzzificaci�n.*/
private String defuzzy;
/**Almacena la secci�n "Bitsize information"*/
XTextForm[] numBitsInformation;
/**N�mero de entradas.*/
private int inputs;
/**N�mero de salidas.*/
private int outputs;
/**Grados de certeza de las reglas.*/
String grados;
/**Contiene la llamada a la base de reglas.*/
RulebaseCall rbc;
/**Cadena que almacena el c�digo VHDL asociado al FLC.*/
String vhdl;
/**Bot�n para se�alar si la MFC se implementa con ROM.*/
JRadioButton MFC_ROM;
/**Bot�n para se�alar si la MFC se implementa con RAM.*/
JRadioButton MFC_RAM;
/**Bot�n para se�alar si la MFC se implementa con bloque l�gico.*/
JRadioButton MFC_logicBlock;
/**Bot�n para se�alar si la RB se implementa con ROM.*/
JRadioButton RB_ROM;
/**Bot�n para se�alar si la RB se implementa con RAM.*/
JRadioButton RB_RAM;
/**Bot�n para se�alar si la RB se implementa con bloque l�gico.*/
JRadioButton RB_logicBlock;
/**Booleano que indica si la base de reglas es completa.*/
boolean complete;
/**Booleano que nos ayuda a bloquear Bits for Membership Function Slope.*/
boolean flag_arith;
/**XfvhdlUniverse que sirve para saber si las entradas est�n o no normalizadas.*/
XfvhdlUniverse u;
/**XfvhdlDiscretizeUniverse que sirve para saber si las entradas est�n o no normalizadas.*/
XfvhdlDiscretizeUniverse disc;
/**Especificaci�n XFL.*/
Specification spec;
/**Booleano que indica si se han de calcular pesos.*/
boolean calculateWeights;
/**Booleano que indica si las entradas no est�n normalizadas porque el
* solapamiento es menor que 1.*/
boolean entradasNoNormalizadasMenor1;
///**Booleano que indica si el m�todo de defuzzificaci�n es o no simplificado.*/
boolean simplificado;//se inicializa cuando empezamos a generar codigo vhdl
private boolean init;
// ----------------------------------------------------------------------------//
// CONSTRUCTOR //
// ----------------------------------------------------------------------------//
/**Constructor de la clase.*/
public XfvhdlFLC(String name, RulebaseCall rbc, Specification spec) {
this.name = name;
this.spec=spec;
N = 0;
grad = 0;
P = 0;
No = 0;
W = 0;
mfcs = new ArrayList<MFC>();
bits_var=new ArrayList<Integer>();
RB = new ArrayList<XfsgOutData>();
connective = "";
grados = "";
defuzzy = "";
todo_relleno = false;
inputs = 0;
outputs = 0;
this.rbc = rbc;
//botones que se agrupar�n en group 1
//Si las entradas no est�n normalizadas,
//memory estar� marcado y adem�s no te dejar� marcar arithmetic
arithmetic = new JRadioButton("Arithmetic");
arithmetic.setSelected(true);
arithmetic.setActionCommand("arithmetic");
memory = new JRadioButton("Memory");
memory.setActionCommand("memory");
flag_arith=true;
//botones que se agrupar�n en group 2
MFC_ROM = new JRadioButton("ROM");
MFC_ROM.setSelected(true);
MFC_ROM.setActionCommand("ROM");
MFC_RAM = new JRadioButton("RAM");
MFC_RAM.setActionCommand("RAM");
MFC_logicBlock = new JRadioButton("Logic Block");
MFC_logicBlock.setActionCommand("logic");
//botones que se agrupar�n en group 2
RB_ROM = new JRadioButton("ROM");
RB_ROM.setActionCommand("ROM");
RB_ROM.setSelected(true);
RB_RAM = new JRadioButton("RAM");
RB_RAM.setActionCommand("RAM");
RB_logicBlock = new JRadioButton("Logic Block");
RB_logicBlock.setActionCommand("logic");
RB = new ArrayList<XfsgOutData>();
//Inicializaciones por defecto de atributos de ayuda
u = new XfvhdlUniverse();
disc = new XfvhdlDiscretizeUniverse();
calculateWeights=false;
entradasNoNormalizadasMenor1=false;
}
// M�TODOS GET
/**
*
* @return calcula pesos o no.
*/
public boolean getCalculateWeights(){
return calculateWeights;
}
/**
*
* @return N� bits entrada.
*///Bitsize of input
public int getN() {
return N;
}
/**
*
* @return N� bits grado de pertenencia.
*/ //Bitsize of membership degree
public int getgrad() {
return grad;
}
/**
*
* @return N� bits de la pendiente.
*/ //Bitsize of MF slope
public int getP() {
return P;
}
/**
*
* @return N� bits salida.
*/ // Bitsize of output
public int getNo() {
return No;
}
/**
*
* @return Indica si es arithmetic o memory.
*/
public boolean getMFC_arithmetic() {
return arithmetic.isSelected();
}
/**
*
* @return MFC con ROM, RAM o bloque l�gico.
*/
public String getMFC_memory() {
String ret;
if(MFC_ROM.isSelected())
ret="ROM";
else if(MFC_RAM.isSelected())
ret="RAM";
else
ret="logic";
return ret;
}
/**
*
* @return RB con ROM, RAM o bloque l�gico.
*/
public String getRB_memory() {
String ret;
if(RB_ROM.isSelected())
ret="ROM";
else if(RB_RAM.isSelected())
ret="RAM";
else
ret="logic";
return ret;
}
/**
*
* @return El nombre del FLC.
*/
public String getname() {
return name;
}
/**
*
* @return Bits para el peso de defuzzification.
*/
public int getW() {
return W;
}
/**
*
* @return El array de mfcs del flc.
*/
public ArrayList<MFC> getmfcs() {
return mfcs;
}
/**
*
* @return Base de reglas
*/
public ArrayList<XfsgOutData> getRB() {
return RB;
}
/**
* @return Conectivo de antecedentes.
*/
public String getconnective() {
return connective;
}
/**
* @return todo_relleno.
*/
public boolean gettodo_relleno() {
return todo_relleno;
}
/**
* @return M�todo de defuzzificaci�n.
*/
public String getdeffuzy() {
return defuzzy;
}
/**
* @return El n�mero de entradas.
*/
public int getinputs() {
return inputs;
}
/**
*
* @return El n�mero de salidas.
*/
public int getoutputs() {
return outputs;
}
/**
* @return Grados de certeza de las reglas.*/
public String getgrados() {
return grados;
}
/**@return Indica si el m�todo de defuzzificaci�n es simplificado.*/
public boolean getSimplificado(){
return simplificado;
}
/**@return C�digo VHDL del flc.*/
public String getVHDL(){
return vhdl;
}
/**
* @return Un booleano indicando si la base de reglas es completa o no.
*/
public boolean getcomplete() {
return complete;
}
/**@return Array de n� de bits necesarios para la parte entera,
* necesario para cuando m�todo de defuzzificaci�n es Takagi-Sugeno.*/
public int[] getBitsParteEnteraTakSug(){
int[] bitsPE=new int[mfcs.size()+1];
int longitud=RB.get(0).getvalues2().length;
//double mayor1=0, mayor2=0, mayor3=0;
double[] mayor=new double[mfcs.size()+1];
boolean[] hayNegativo=new boolean[mfcs.size()+1];
//boolean hayNegativo1=false,hayNegativo2=false,hayNegativo3=false;
for(int i=0;i<mfcs.size()+1;i++){
mayor[i]=0;
hayNegativo[i]=false;
}
for (int i=0;i<longitud;i++){
for(int j=0;j<mfcs.size()+1;j++){
if(RB.get(0).getvalues2()[i][j]<0&&!hayNegativo[j])
hayNegativo[j]=true;
if(mayor[j]<Math.abs(RB.get(0).getvalues2()[i][j]))
mayor[j]=Math.abs(RB.get(0).getvalues2()[i][j]);
}
}
for(int i=0;i<mfcs.size()+1;i++){
bitsPE[i]=(int)Math.ceil(Math.log(Math.ceil(mayor[i]))/Math.log(2));
if(hayNegativo[i])
bitsPE[i]++;
if(bitsPE[i]<2)
bitsPE[i]=2;
}
return bitsPE;
}
/**@param bitsTotales N� de bits para codificar el par�metro del m�todo
* de defuzzificaci�n Takagi-Sugeno.
* @return Lista de cadenas que representan los par�metros de Takagi-Sugeno.*/
public String[][] getTakSugBinario(int bitsTotales) throws IOException{
int longitud=RB.get(0).getvalues2().length;
String[][] res=new String[longitud][mfcs.size()+1];
int[] BitsParteEntera=new int[mfcs.size()+1];
int[] BitsParteDecimal=new int[mfcs.size()+1];
BitsParteEntera= getBitsParteEnteraTakSug();
for(int i=0;i<mfcs.size()+1;i++){
BitsParteDecimal[i]=bitsTotales-BitsParteEntera[i];
}
XfvhdlBinaryDecimal converter=new XfvhdlBinaryDecimal();
RB.get(0).getvalues2();
for (int i=0;i<longitud;i++){
for(int j=0;j<mfcs.size()+1;j++){
res[i][j]=converter.toCA2(RB.get(0).getvalues2()[i][j],
bitsTotales,BitsParteDecimal[j]);
}
}
return res;
}
/**@param spec Especificaci�n XFL.
* @return C�digo del fichero de test bench del m�dulo de inferencia.*/
public String getTestBench(Specification spec){
String res="";
XfvhdlTestBenchFile testBench=new XfvhdlTestBenchFile();
res=testBench.createTestBenchSource(spec, this,null,null);
return res;
}
// M�TODOS SET
/**@param calculateWeights true si queremos que calcule los pesos.*/
public void setCalculateWeights(boolean calculateWeights){
this.calculateWeights=calculateWeights;
}
/**
*
* @param N N� bits entrada
*/ //Bitsize of input
public void setN(int N) {
this.N = N;
}
/**
*
* @param grad N� bits grado del pertenencia
*/ //Bitsize of membership degree
public void setgrad(int grad) {
this.grad = grad;
}
/**
*
* @param P N� bits de las pendientes
*/ //Bitsize of MF slope
public void setP(int P) {
this.P = P;
}
/**
*
* @param No N� bits salida
*/ //Bitsize of output
public void setNo(int No) {
this.No = No;
}
/**
*
* @param arith Opci�n MFC memory (arithmetic or memory).
*/
public void setMFC_arithmetic(boolean arith) {
if (arith){
flag_arith=true;
memory.setSelected(false);
arithmetic.setSelected(true);
}
else{
flag_arith=false;
arithmetic.setSelected(false);
memory.setSelected(true);
}
}
/**
*
* @param memory Opci�n MFC memory (ROM, RAM or logic block).
*/
public void setMFC_memory(String mem) {
if (mem.equals("ROM")){
MFC_RAM.setSelected(false);
MFC_logicBlock.setSelected(false);
MFC_ROM.setSelected(true);
}
else if(mem.equals("RAM")){
MFC_logicBlock.setSelected(false);
MFC_ROM.setSelected(false);
MFC_RAM.setSelected(true);
}else{
MFC_ROM.setSelected(false);
MFC_RAM.setSelected(false);
MFC_logicBlock.setSelected(true);
}
}
/**
*
* @param memory Opci�n RB memory (ROM, RAM or logic block).
*/
public void setRB_memory(String mem) {
if (mem.equals("ROM")){
RB_RAM.setSelected(false);
RB_logicBlock.setSelected(false);
RB_ROM.setSelected(true);
}
else if(mem.equals("RAM")){
RB_logicBlock.setSelected(false);
RB_ROM.setSelected(false);
RB_RAM.setSelected(true);
}else{
RB_ROM.setSelected(false);
RB_RAM.setSelected(false);
RB_logicBlock.setSelected(true);
}
}
/**
*
* @param name Nombre del FLC
*/
public void setname(String name) {
this.name = name;
}
/**
*
* @param K Bits para el peso de defuzzification.
*/
public void setW(int W) {
this.W = W;
}
/**
*
* @param RB Base de reglas.
*/
public void setRB(ArrayList<XfsgOutData> RB) {
this.RB = RB;
}
/**
*
* @param connective Conectivo de antecedentes.
*/
public void setconnective(String connective) {
this.connective = connective;
}
/**@param todo_relleno Indicador de completitud en configuraci�n.
* */
public void settodo_relleno(boolean todo_relleno) {
this.todo_relleno = todo_relleno;
}
/**
*
* @param deffuzy M�todo de defuzzificaci�n.
*/
public void setdefuzzy(String deffuzy) {
this.defuzzy = deffuzy;
}
/**
*
* @param inputs N�mero de entradas.
*/
public void setinputs(int inputs) {
this.inputs = inputs;
}
/**
*
* @param outputs N�mero de salidas.
*/
public void setoutputs(int outputs) {
this.outputs = outputs;
}
/**@param grados Grados de certeza de la regla.*/
public void setgrados(String grados) {
this.grados = grados;
}
/**@param complete Indica si la base de reglas es completa,*/
public void setcomplete(boolean complete) {
this.complete = complete;
}
/**@paramn b Indica si las entradas no est�n normalizadas
* porque el solapamiento es menor que 1 */
public void setEntradasNoNormalizadasMenor1(boolean b){
entradasNoNormalizadasMenor1=b;
}
/**M�todo que le da el valor que le corresponde al atributo simplificado,
* a partir de la especificaci�n XFL.
* @param Especificaci�n XFL.
* */
public void setSimplificado(Specification spec){
if(getdeffuzy().equals("MaxLabel")||
((getdeffuzy().equals("TakagiSugeno")
||getdeffuzy().equals("FuzzyMean"))&&
!entradasNoNormalizadasMenor1&&
XfvhdlProperties.simplifiedComponents==true
)){
if(getdeffuzy().equals("MaxLabel")||
(getinputs()>1&&getconnective().equalsIgnoreCase("prod")))//simplificado
{
simplificado=true;
}else if (getinputs()>1&&!getconnective().equalsIgnoreCase("prod")){//no simpl
simplificado=false;
}else{//simplificado, caso de 1 entrada
simplificado=true;
}
}else{//no simplificado
simplificado=false;
}
}
// M�TODOS PROPIOS DE LA CLASE
/**@param a N� de bits asociados a las reglas de la siguiente entrada.
*/
public void addBits_var(int a){
bits_var.add(a);
}
/**A�ade un nuevo MFC a la lista mfcs.
* @param n_fp N�mero de funciones de pertenencia.
* @param _a Cadena que representa los puntos del MFC.
* @param slopes Cadena que se representa con las pendientes del MFC.
* @param listaPuntos Lista de puntos del MFC.
* @param listaPendientes Lista de pendientes del MFC.*/
public void create_addMFC(String n_fp, String _a, String slopes, ArrayList<Double> listaPuntos, ArrayList<Double> listaPendientes) {
MFC m = new MFC(n_fp, _a, slopes, listaPuntos, listaPendientes);
mfcs.add(m);
}
/**A�ade una nueva base de reglas al atributo RB.
* @param rb Base de reglas.*/
public void addRB(XfsgOutData rb) {
this.RB.add(rb);
}
/**@return Nombre del flc.*/
public String toString() {
return name;
}
/**Define la interfaz gr�fica de usuario asociada al
* m�dulo de inferencia.*/
public Box gui() {
if(entradasNoNormalizadasMayor1(spec)){
return null;
}else if(this.getoutputs()>1){
new XfvhdlError(14, name);
return null;
}else if (this.defuzzy.equalsIgnoreCase("TakagiSugeno")
&& this.getinputs()>2){
new XfvhdlError(9, name);
return null;
}
// Define los botones asociados para la secci�n "Bitsize
// information"
String numBitsInformationLabels[] = { "Bits for Input",
"Bits for Output", "Bits for membership degree",
"Bits for membership function slope ",
"Bits for defuzzification weight" };
// Crea la secci�n "Bitsize information"
numBitsInformation = new XTextForm[5];
for (int i = 0; i < numBitsInformation.length; i++) {
numBitsInformation[i] = new XTextForm(numBitsInformationLabels[i]);
numBitsInformation[i].setEditable(true);
numBitsInformation[i].setFieldWidth(5);
}
XTextForm.setWidth(numBitsInformation);
// Escribe los valores por defecto
Integer intTmp = new Integer(N);
numBitsInformation[0].setText(intTmp.toString());
intTmp = new Integer(No);
numBitsInformation[1].setText(intTmp.toString());
intTmp = new Integer(grad);
numBitsInformation[2].setText(intTmp.toString());
intTmp = new Integer(P);
numBitsInformation[3].setText(intTmp.toString());
intTmp = new Integer(W);
numBitsInformation[4].setText(intTmp.toString());
if(!flag_arith){
numBitsInformation[3].setEditable(false);
numBitsInformation[3].setFieldEnabled(false);
numBitsInformation[3].setLabelEnabled(false);
}
Box evolbox = new Box(BoxLayout.Y_AXIS);
//evolbox.add(Box.createVerticalStrut(10));
Box aux = new Box(BoxLayout.X_AXIS);
Box bitinfo = new Box(BoxLayout.Y_AXIS);
bitinfo.add(new XLabel("Variables for Rulebase: " + name));
bitinfo.add(new XLabel("Bitsize information"));
for (int i = 0; i < numBitsInformation.length; i++)
bitinfo.add(numBitsInformation[i]);
aux.add(bitinfo);
// Define los botones asociados para la secci�n "Kinds of
// memory"
Box retbox = new Box(BoxLayout.Y_AXIS);
retbox.setPreferredSize(new Dimension (250,50));
retbox.add(new XLabel("Kinds of memory"));
group1 = new ButtonGroup();
group1.add(arithmetic);
group1.add(memory);
ActionListener al = new VoteActionListener();
arithmetic.addActionListener(al);
memory.addActionListener(al);
ButtonGroup group2 = new ButtonGroup();
group2.add(MFC_ROM);
group2.add(MFC_RAM);
group2.add(MFC_logicBlock);
ButtonGroup group3 = new ButtonGroup();
group3.add(RB_ROM);
group3.add(RB_RAM);
group3.add(RB_logicBlock);
Box subBox1 = new Box(BoxLayout.X_AXIS);
subBox1.add(arithmetic);
subBox1.add(memory);
Box subBox2 = new Box(BoxLayout.X_AXIS);
subBox2.add(MFC_ROM);
subBox2.add(MFC_RAM);
subBox2.add(MFC_logicBlock);
Box subBoxMFC= new Box(BoxLayout.Y_AXIS);
subBoxMFC.add(new XLabel("MFC's"));
subBoxMFC.add(subBox1);
subBoxMFC.add(subBox2);
Box subRB=new Box(BoxLayout.X_AXIS);
subRB.add(RB_ROM);
subRB.add(RB_RAM);
subRB.add(RB_logicBlock);
Box RB=new Box(BoxLayout.Y_AXIS);
RB.add(new XLabel("Rule Base"));
RB.add(subRB);
retbox.add(subBoxMFC);
retbox.add(RB);
aux.add(retbox);
evolbox.add(aux);
//MFC'S
entradasNoNormalizadasMenor1(spec);
for (int k = 0; k < mfcs.size(); k++) {
evolbox.add(Box.createVerticalStrut(5));
evolbox.add(new XLabel("MFC" + (k + 1)));
String MFCInformationLabels[] = { "N. Membership Functions",
"Breakpoints", "Slopes" };
// Crea la secci�n "MFCj Information"
XTextForm[] MFCInformation = new XTextForm[3];
for (int j = 0; j < MFCInformation.length; j++) {
MFCInformation[j] = new XTextForm(MFCInformationLabels[j]);
MFCInformation[j].setEditable(false);
MFCInformation[j].setFieldWidth(100);
}
MFC mfc_aux = mfcs.get(k);
MFCInformation[0].setText(mfc_aux.getn_fp());
MFCInformation[1].setText(mfc_aux.get_a());
MFCInformation[2].setText(mfc_aux.getslopes());
XTextForm.setWidth(MFCInformation);
for (int l = 0; l < MFCInformation.length; l++) {
evolbox.add(MFCInformation[l]);
}
}
if(entradasNoNormalizadasMenor1){
setMFC_arithmetic(false);
numBitsInformation[3].setEditable(false);
numBitsInformation[3].setFieldEnabled(false);
numBitsInformation[3].setLabelEnabled(false);
memory.setEnabled(false);
arithmetic.setEnabled(false);
}
// Crea la secci�n "Rulebase Information"
for (int i = 0; i < this.RB.size(); i++) {
evolbox.add(Box.createVerticalStrut(5));
evolbox.add(new XLabel("RB" + (i + 1)));
JTextArea jta = new JTextArea();
jta.append(this.RB.get(i).getRB());
jta.setEditable(false);
jta.setBackground(XConstants.textbackground);
evolbox.add(jta);
}
evolbox.setVisible(true);
return evolbox;
}
/**Pb, es la posici�n de la coma, si esta es < 0, error,
* necesitamos m�s bits para representar el dato.*/
public boolean compruebaPbAdecuado(){
for(int i=0;i<mfcs.size();i++){
if(P-mfcs.get(i).pbi()<0 && arithmetic.isSelected()){
return false;
}
}
return true;
}
/**Genera la cabecera del fichero VHDL asociado al FLC.*/
public String generaCabecera(){
String user="";
String so="";
String vmachine="";
String separator="";
Date now = new Date();
String date = now.toString();
if(init!=true){
try {
so = System.getProperty("os.name", "not specified");
so += " ver. ";
so += System.getProperty("os.version", "not specified");
vmachine = System.getProperty("java.version", "not specified");
user = System.getProperty("user.name", "not specified");
separator = System.getProperty("file.separator", "\\");
} catch (Exception e) {
}
init = true;
}
String res="--\n" +
"-- Automatically generated by Xfvhdl\n" +
"--\n" +
"-- output:: "+name+".vhd\n" +
"-- source:: "+XfvhdlProperties.ficheroXFL+"\n" +
"-- for "+user+", "+date+"\n" +
"-- in "+so+ " with VM "+ vmachine+ "\n" +
"--\n" +
"\n" +
"---------------------------------------------------------------------------\n" +
"-- "+name+"_Constants --\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";;
return res;
}
/**Genera el c�digo VHDL de la zona de constants del fichero VHDL
* asociado al FLC.*/
public String generaConstantes(Specification spec){
String MFCi="";
String auxRBRAM=name+"_MFC1_bits";
int mfci_bits;
int maxFuncPert=0;
for(int i=0;i<mfcs.size();i++){
if(Integer.valueOf(mfcs.get(i).getn_fp())>maxFuncPert)
maxFuncPert=(int)(Integer.valueOf(mfcs.get(i).getn_fp()));
}
int pipe=(int) Math.pow((double) 2,(double) mfcs.size());
if(arithmetic.isSelected())
pipe=Math.max(pipe, maxFuncPert);
if (!simplificado)
pipe=Math.max(pipe, No+1);
int bits=(int)Math.ceil((Math.log(pipe)/Math.log(2)));
if(XfvhdlProperties.pipemax<pipe){
XfvhdlProperties.pipemax=pipe;
XfvhdlProperties.bitsmax=bits;
}
String res="package "+name+"_Constants is\n\n" +
" constant "+name+"_inputs : integer := "+inputs+"; -- Inputs to the fuzzy system\n" +
" constant "+name+"_N : integer := "+N+"; -- Bitsize of input\n" +
" constant "+name+"_grad : integer := "+grad+"; -- Bitsize of membership degree\n" +
" constant "+name+"_W : integer := "+W+"; -- Bitsize of deffuz. parameter\n" +
" constant "+name+"_P : integer := "+P+"; -- Bitsize of MF slope\n" +
" constant "+name+"_No : integer := "+No+"; -- Bitsize of output\n"
;
for(int i=0;i<mfcs.size();i++){
auxRBRAM+=i<(mfcs.size()-1)?"+"+name+"_MFC"+(i+2)+"_bits":"";
mfci_bits=(int) Math.ceil(
Math.log(Double.valueOf(mfcs.get(i).getn_fp()))
/ Math.log((double) 2));
MFCi=" --\n" +
" constant "+name+"_MFC"+(i+1)+"_nfp : integer := "+mfcs.get(i).getn_fp()+"; -- Number of membership functions\n" +
(arithmetic.isSelected()?" constant "+name+"_MFC"+(i+1)+"_Pb : integer := "+(P-mfcs.get(i).pbi())+"; -- Binary point for MF slope\n":"") +
" constant "+name+"_MFC"+(i+1)+"_bits : integer := "+mfci_bits+"; -- Bitsize of label\n";
res+=MFCi;
}
if(RB_RAM.isSelected()){
res+=" --\n" +
" constant "+name+"_a_bits : integer := "+auxRBRAM+"; -- Bitsize of address bus rules memory\n" +
" constant "+name+"_d_bits : integer := "
+ (defuzzy.equalsIgnoreCase("TakagiSugeno")?""+(mfcs.size()+1)+"*":
((defuzzy.equalsIgnoreCase("WeightedFuzzyMean")||defuzzy.equalsIgnoreCase("Quality")||defuzzy.equalsIgnoreCase("GammaQuality"))?name+"_W + ":""))
+name+"_No; -- Bitsize of data bus rules memory -- Rows for rules memory\n" +
" --\n"
;
}
res+=" --\n" +
" constant pipe_"+name+" : integer := "+pipe+"; -- Pipeline cycles\n" +
" constant bits_"+name+" : integer := "+bits+"; -- ceil(log2(j_pipe))\n" +
" --\n"
;
if(defuzzy.equalsIgnoreCase("TakagiSugeno")){
int[] partesEnteras=getBitsParteEnteraTakSug();
res+=" constant "+name+"_Pc : integer := "+(No-partesEnteras[0])+"; -- Binary point for Takagi Sugeno \"c\" parameter (decimal)\n"
;
for(int i=1;i<=mfcs.size();i++){
res+=" constant "+name+"_Pa"+i+" : integer := "+(No-partesEnteras[i])+"; -- Binary point for Takagi Sugeno \"a"+i+"\" parameter (decimal)\n";
}
res+=" --\n";
}
if(!simplificado)
res+=" constant "+name+"_bitsn : integer := "+name+"_No+"+name+"_grad+"+name+"_inputs"+
((defuzzy.equalsIgnoreCase("WeightedFuzzyMean")||defuzzy.equalsIgnoreCase("Quality")||defuzzy.equalsIgnoreCase("GammaQuality"))?"+"+name+"_W":"")+
"; -- Bitsize of accumulator numerator\n\n" ;
res+="end "+name+"_Constants;\n\n";
return res;
}
/**Genera el c�digo VHDL dependiente de que las entradas sean
* de tipo arithmetic, del fichero VHDL
* asociado al FLC.*/
public String generaEntradasAritmeticas(){
String str_aux = "";
String others;
String tipoAntecedent="ArithMem";
//if(!arithmetic.isSelected())
// tipoAntecedent="AntecedentMem";
String librerias="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" +
"use WORK."+name+"_Constants.all;\n\n";
String res="";
for(int i=0;i<mfcs.size();i++){
res+="---------------------------------------------------------------------------\n" +
"-- "+name+"_"+tipoAntecedent+(i+1)+" --\n" +
"---------------------------------------------------------------------------\n\n" +
librerias +
"entity "+name+"_"+tipoAntecedent+(i+1)+" is\n\n" +
" generic(\n" +
" "+name+"_bits : integer);\n" +
" port(\n" +
" addr : in std_logic_vector("+name+"_bits-1 downto 0); --Address buss\n" +
" MFC_a : out std_logic_vector("+name+"_N-1 downto 0); -- Breakpoint\n" +
" MFC_m : out std_logic_vector("+name+"_P-1 downto 0)); -- Slope\n\n" +
"end "+name+"_"+tipoAntecedent+(i+1)+";\n\n" +
"architecture FPGA of "+name+"_"+tipoAntecedent+(i+1)+" is\n\n" +
" signal s_addr : std_logic_vector("+name+"_MFC"+(i+1)+"_bits-1 downto 0);\n" +
" signal s_data : std_logic_vector(("+name+"_N+"+name+"_P) downto 1);\n\n\n";
if(MFC_logicBlock.isSelected()){
res+="begin\n\n" +
" s_addr <= addr("+name+"_MFC"+(i+1)+"_bits-1 downto 0) when (addr <= "+name+"_MFC"+(i+1)+"_nfp-1) else\n" +
" std_logic_vector(conv_unsigned("+name+"_MFC"+(i+1)+"_nfp-1, "+name+"_MFC"+(i+1)+"_bits));\n\n" +
" Read_mem : process(s_addr)\n" +
" begin\n" +
" case s_addr is\n";
XfvhdlBinaryDecimal converter=new XfvhdlBinaryDecimal();
str_aux="";
double punto;
double pendiente;
for (int j=0;j<Integer.valueOf(mfcs.get(i).getn_fp());j++){
String punto_pendiente="";
String antecedente=converter.toBinary(j, bits_var.get(i));
if(j==Integer.valueOf(mfcs.get(i).getn_fp())-1){
pendiente=0;
}else{
pendiente=mfcs.get(i).getPendiente(j);
}
punto=mfcs.get(i).getPunto(j);
punto_pendiente+=converter.toBinaryInRange(punto, 0, 1, N);
punto_pendiente+=converter.toBinaryInRange(pendiente, 0, Math.pow(2, mfcs.get(i).pbi()), P);
str_aux+=" when \""+antecedente+"\" => s_data <= \""+punto_pendiente+"\";\n" ;//Aqui hay que llamar a alguna funcion
}
others="";
for(int j=0;j<N+P;j++){
others+="-";
}
res+= str_aux +
" when others => s_data <= \""+others+"\";\n" +
//Hay que meter el numero exacto de rayas-----------
" end case;\n" +
" end process Read_mem;\n\n" ;
}
else if(MFC_ROM.isSelected()){
res+=" subtype ROM_WORD is std_logic_vector(("+name+"_N+"+name+"_P-1) downto 0);\n" +
" type ROM_TABLE is array (0 to "+name+"_MFC"+(i+1)+"_nfp-1) of ROM_WORD;\n" +
" constant ROM : ROM_TABLE := ROM_TABLE'(\n";
XfvhdlBinaryDecimal converter=new XfvhdlBinaryDecimal();
str_aux="";
double punto;
double pendiente;
for (int j=0;j<Integer.valueOf(mfcs.get(i).getn_fp());j++){
String punto_pendiente="";
String antecedente=converter.toBinary(j, bits_var.get(i));
if(j==Integer.valueOf(mfcs.get(i).getn_fp())-1){
pendiente=0;
}else{
pendiente=mfcs.get(i).getPendiente(j);
}
punto=mfcs.get(i).getPunto(j);
punto_pendiente+=converter.toBinaryInRange(punto, 0, 1, N);
punto_pendiente+=converter.toBinaryInRange(pendiente, 0, Math.pow(2, mfcs.get(i).pbi()), P);
str_aux+=" ROM_WORD'(\""+punto_pendiente+"\")" ;//Aqui hay que llamar a alguna funcion
if (j<Integer.valueOf(mfcs.get(i).getn_fp())-1) {
str_aux+=",\n";
}
else {
str_aux+=");\n\n";
}
}
res+= str_aux +
"begin\n\n" +
" s_addr <= addr("+name+"_MFC"+(i+1)+"_bits-1 downto 0) when (addr <= "+name+"_MFC"+(i+1)+"_nfp-1) else\n" +
" std_logic_vector(conv_unsigned("+name+"_MFC"+(i+1)+"_nfp-1, "+name+"_MFC"+(i+1)+"_bits));\n\n" +
" s_data <= ROM(conv_integer(s_addr));\n\n";
}
res+=
" MFC_a <= s_data(("+name+"_N+"+name+"_P) downto ("+name+"_P+1));\n" +
" MFC_m <= s_data("+name+"_P downto 1);\n\n" +
"end FPGA;\n\n\n";
}
return res;
}
/**Genera el c�digo VHDL dependiente de que la base de reglas sea
* de tipo Logic Block, del fichero VHDL
* asociado al FLC.*/
public String generaRulesMemLB(Specification spec, String nombre_i) throws IOException{
String res="";
String others;
String librerias="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" +
"use WORK."+name+"_Constants.all;\n\n";
String suma=name+"_MFC1_bits ";
for(int i=1;i<mfcs.size();i++)
suma+="+ "+name+"_MFC"+(i+1)+"_bits";
XfvhdlRulesMemLB calcular=new XfvhdlRulesMemLB();
String whenrules;
if(defuzzy!="TakagiSugeno")
whenrules=calcular.createRulesMemSource(spec, nombre_i, bits_var,null, calculateWeights, No, W);
else
whenrules=calcular.createRulesMemSource(spec, nombre_i, bits_var,getTakSugBinario(No), calculateWeights, No, W);
others="";
for(int j=0;j<No;j++){
if(defuzzy=="TakagiSugeno")
others+="---";
else
others+="-";
}
if(defuzzy=="WeightedFuzzyMean"||defuzzy=="Quality"||defuzzy=="GammaQuality"){
for(int i=0;i<W;i++)
others+="-";
}
res+="---------------------------------------------------------------------------\n" +
"-- "+name+"_RulesMem --\n" +
"---------------------------------------------------------------------------\n\n" +
librerias +
"entity "+name+"_RulesMem is\n\n" +
" port(\n" +
" addr : in std_logic_vector(("+suma+")-1 downto 0); -- Address bus\n" +
" do : out std_logic_vector("+ (defuzzy.equalsIgnoreCase("TakagiSugeno")?""+(mfcs.size()+1)+"*":
((defuzzy.equalsIgnoreCase("WeightedFuzzyMean")||defuzzy.equalsIgnoreCase("Quality")||defuzzy.equalsIgnoreCase("GammaQuality"))?(name+"_W + "):""))
+name+"_No downto 1)); -- Data bus\n\n" +
"end "+name+"_RulesMem;\n\n\n" +
"architecture FPGA of "+name+"_RulesMem is\n\n" +
" signal s_data : std_logic_vector("+ (defuzzy.equalsIgnoreCase("TakagiSugeno")?""+(mfcs.size()+1)+"*":
((defuzzy.equalsIgnoreCase("WeightedFuzzyMean")||defuzzy.equalsIgnoreCase("Quality")||defuzzy.equalsIgnoreCase("GammaQuality"))?name+"_W + ":""))
+name+"_No downto 1);\n\n" +
"begin\n\n" +
" Read_mem : process(addr)\n" +
" begin\n" +
" case addr is\n" +
whenrules +
" when others => s_data <= \""+others+"\";\n"+
" end case;\n" +
" end process Read_mem;\n\n" +
" do <= s_data;\n\n" +
"end FPGA;\n\n";
return res;
}
/**Genera el c�digo VHDL dependiente de que la base de reglas sea
* de tipo ROM, del fichero VHDL
* asociado al FLC.*/
public String generaRulesMemROM(Specification spec, String nombre_i) throws IOException{
String res="";
String librerias="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" +
"use WORK."+name+"_Constants.all;\n\n";
String suma=name+"_MFC1_bits ";
for(int i=1;i<mfcs.size();i++)
suma+="+ "+name+"_MFC"+(i+1)+"_bits";
XfvhdlRulesMemROM calcular=new XfvhdlRulesMemROM();
String whenrules="";
if(defuzzy!="TakagiSugeno")
whenrules=calcular.createRulesMemSource(spec, nombre_i, bits_var,null, calculateWeights, No, W);
else
whenrules=calcular.createRulesMemSource(spec, nombre_i, bits_var,getTakSugBinario(No), calculateWeights, No, W);
res+="---------------------------------------------------------------------------\n"
+ "-- "+name+"_RulesMem --\n"
+ "---------------------------------------------------------------------------\n\n"
+ librerias
+ "entity "+name+"_RulesMem is\n\n"
+ " port(\n"
+ " addr : in std_logic_vector(("+suma+")-1 downto 0); -- Address bus\n"
+ " do : out std_logic_vector("
+ (defuzzy.equalsIgnoreCase("TakagiSugeno")?""
+ (mfcs.size()+1)+"*":
((defuzzy.equalsIgnoreCase("WeightedFuzzyMean")
||defuzzy.equalsIgnoreCase("Quality")
||defuzzy.equalsIgnoreCase("GammaQuality"))?(name
+"_W + "):"")) +name+"_No downto 1)); -- Data bus\n\n"
+ "end "+name+"_RulesMem;\n\n\n"
+ "architecture FPGA of "+name+"_RulesMem is\n\n"
+ " subtype ROM_WORD is std_logic_vector("
+ (defuzzy.equalsIgnoreCase("TakagiSugeno")?""
+ (mfcs.size()+1)+ "*":
((defuzzy.equalsIgnoreCase("WeightedFuzzyMean")
|| defuzzy.equalsIgnoreCase("Quality")
|| defuzzy.equalsIgnoreCase("GammaQuality"))?name
+ "_W + " : "")) + name + "_No -1 downto 0);\n"
+ " type ROM_TABLE is array (0 to 2 ** (" + suma+ ")-1) of ROM_WORD;\n"
+ " constant ROM : ROM_TABLE := ROM_TABLE'(\n"
+ whenrules
+ "end FPGA;\n\n";
return res;
}
/**Genera el tramo final del c�digo VHDL.
* @param spec Especificaci�n XFL.*/
private String generaFinFLC(Specification spec){
String res="";
String puertosin="";
String componentesin="";
String suma_MFC_bits=name+"_MFC1_bits";
String[] MFC_bits=new String[mfcs.size()];
String arithmetic_signal;
String arithmetic_map="";
String tipoAntecedent;
String componentRulesMem="";
String BloqueRulMem;
String[] BloqueMemoriaAntecedente=new String[mfcs.size()];
String BloqueArithAntecedente="";
if(!arithmetic.isSelected())
tipoAntecedent="AntecedentMem";
else{
if(MFC_RAM.isSelected())
tipoAntecedent="ArithMem_RAM";
else
tipoAntecedent="ArithMem";
}
String librerias="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" +
"use WORK."+name+"_Constants.all;\n\n";
if(arithmetic.isSelected()){
if(MFC_RAM.isSelected())
arithmetic_signal="-- Internal signals (ArithMem_RAM)\n\n";
else
arithmetic_signal="-- Internal signals (Arithmetic)\n\n";
}else{
arithmetic_signal="-- Internal signals (AntecedentMem)\n\n";
}
for(int i=0;i<mfcs.size();i++){
puertosin+=" in"+(i+1)+" : in std_logic_vector("+name+"_N downto 1); -- Input "+(i+1)+" signal.\n";
if(!MFC_RAM.isSelected()){
if(arithmetic.isSelected())
componentesin+=" component "+name+"_"+tipoAntecedent+(i+1)+"\n" +
" generic(\n" +
" "+name+"_bits : integer);\n" +
" port(\n" +
" addr : in std_logic_vector("+name+"_bits-1 downto 0);\n" +
" MFC_a : out std_logic_vector("+name+"_N-1 downto 0);\n" +
" MFC_m : out std_logic_vector("+name+"_P-1 downto 0));\n" +
" end component;\n\n"
;
else
componentesin+=" component "+name+"_"+tipoAntecedent+(i+1)+"\n" +
" port(\n" +
" pipe : in std_logic;\n" +
" addr : in std_logic_vector("+name+"_N-1 downto 0);\n" +
" alpha_1 : out std_logic_vector("+name+"_grad downto 1);\n" +
" alpha_2 : out std_logic_vector("+name+"_grad downto 1);\n" +
" L_1 : out std_logic_vector("+name+"_MFC"+(i+1)+"_bits downto 1);\n" +
" L_2 : out std_logic_vector("+name+"_MFC"+(i+1)+"_bits downto 1));\n" +
" end component;\n\n"
;
}
if(arithmetic.isSelected()){
arithmetic_signal+=" signal s_MFC_a"+(i+1)+" : std_logic_vector("+name+"_N downto 1);\n" +
" signal s_MFC_m"+(i+1)+" : std_logic_vector("+name+"_P downto 1);\n" +
" signal s_alpha_"+(i+1)+"1 : std_logic_vector("+name+"_grad downto 1);\n" +
" signal s_alpha_"+(i+1)+"2 : std_logic_vector("+name+"_grad downto 1);\n" +
" signal s_L_"+(i+1)+"1 : std_logic_vector("+name+"_MFC"+(i+1)+"_bits downto 1);\n" +
" signal s_L_"+(i+1)+"2 : std_logic_vector("+name+"_MFC"+(i+1)+"_bits downto 1);\n";
}else{
arithmetic_signal+=" signal s_alpha_"+(i+1)+"1 : std_logic_vector("+name+"_grad downto 1);\n" +
" signal s_alpha_"+(i+1)+"2 : std_logic_vector("+name+"_grad downto 1);\n" +
" signal s_L_"+(i+1)+"1 : std_logic_vector("+name+"_MFC"+(i+1)+"_bits downto 1);\n" +
" signal s_L_"+(i+1)+"2 : std_logic_vector("+name+"_MFC"+(i+1)+"_bits downto 1);\n"
;
}
if(arithmetic.isSelected()){
if(MFC_RAM.isSelected()){
arithmetic_signal+=" signal di"+(i+1)+" : std_logic_vector("+name+"_N+"+name+"_P downto 1);\n";
addLibrary(tipoAntecedent);//A�adimos bloque de biblioteca
BloqueMemoriaAntecedente[i]=" Mem"+(i+1)+" : "+tipoAntecedent+"\n" +
" generic map (\n" +
" bits => "+name+"_bits,\n" +
" nfp => "+name+"_MFC"+(i+1)+"_nfp\n" +
" bitl => "+name+"_MFC"+(i+1)+"_bits,\n" +
" N => "+name+"_N,\n" +
" P => "+name+"_P)\n" +
" port map(\n" +
" clk => clk,\n" +
" we => clk,\n" +
" addr => s_addr,\n" +
" di => di"+(i+1)+",\n" +
" MFC_a => s_MFC_a"+(i+1)+",\n" +
" MFC_m => s_MFC_m"+(i+1)+");\n\n"
;
}else{
BloqueMemoriaAntecedente[i]=" Mem"+(i+1)+" : "+name+"_"+tipoAntecedent+(i+1)+"\n" +
" generic map(\n" +
" "+name+"_bits => "+name+"_bits)\n" +
" port map(\n" +
" addr => s_addr,\n" +
" MFC_a => s_MFC_a"+(i+1)+",\n" +
" MFC_m => s_MFC_m"+(i+1)+");\n\n";
}
}else{//En memoria
if(MFC_RAM.isSelected()){
arithmetic_signal+=" signal di"+(i+1)+" : std_logic_vector(2*"+name+"_grad+"+name+"_MFC"+(i+1)+"_bits downto 1);\n"
;
addLibrary("Antecedent_RAM");
BloqueMemoriaAntecedente[i]=" Mem"+(i+1)+" : Antecedent_RAM\n" +
" generic map(\n" +
" N => "+name+"_N,\n" +
" grad => "+name+"_grad,\n" +
" bitl => "+name+"_MFC"+(i+1)+"_bits)\n" +
" port map(\n" +
" clk => clk,\n" +
" we => s_pipe,\n" +
" addr => in"+(i+1)+",\n" +
" di => di"+(i+1)+",\n" +
" alpha_1 => s_alpha_"+(i+1)+"1,\n" +
" alpha_2 => s_alpha_"+(i+1)+"2,\n" +
" L_1 => s_L_"+(i+1)+"1,\n" +
" L_2 => s_L_"+(i+1)+"2);\n\n"
;
}else
BloqueMemoriaAntecedente[i]=" Mem"+(i+1)+" : "+name+"_"+tipoAntecedent+(i+1)+"\n" +
" port map(\n"+
" pipe => s_pipe,\n" +
" addr => in"+(i+1)+",\n"+
" alpha_1 => s_alpha_"+(i+1)+"1,\n"+
" alpha_2 => s_alpha_"+(i+1)+"2,\n"+
" L_1 => s_L_"+(i+1)+"1,\n"+
" L_2 => s_L_"+(i+1)+"2);\n\n"
;
}
MFC_bits[i]=name+"_MFC"+(i+1)+"_bits";
if(i>0)
suma_MFC_bits+=" + "+name+"_MFC"+(i+1)+"_bits";
}
arithmetic_signal+="\n";
for(int i=0;i<mfcs.size();i++){
String subsuma1=name+"_MFC"+mfcs.size()+"_bits";
String subsuma2="1";
int restar_en_S=mfcs.size()-i-1;
for (int l=mfcs.size()-1;l>i;l--){
subsuma1+=" + "+MFC_bits[l-1];
}
for (int l=mfcs.size()-i-1;l>0;l--){
subsuma2=MFC_bits[mfcs.size()-l]+" + "+subsuma2;
}
addLibrary("Arithmetic");
BloqueArithAntecedente=" Arith"+(i+1)+" : Arithmetic\n" +
" generic map(\n" +
" N => "+name+"_N,\n" +
" P => "+name+"_P,\n" +
(arithmetic.isSelected()?" Pb => "+name+"_MFC"+(i+1)+"_Pb,\n":"") +
" n_fp => "+name+"_MFC"+(i+1)+"_nfp,\n" +
" bitl => "+name+"_MFC"+(i+1)+"_bits,\n" +
" bitc => "+name+"_bits,\n" +
" grad => "+name+"_grad)\n" +
" port map(\n" +
" clk => clk,\n" +
" pipe => s_pipe,\n" +
" x => in"+(i+1)+",\n" +
" addr => s_addr,\n" +
" MFC_a => s_MFC_a"+(i+1)+",\n" +
" MFC_m => s_MFC_m"+(i+1)+",\n" +
" alpha_1 => s_alpha_"+(i+1)+"1,\n" +
" alpha_2 => s_alpha_"+(i+1)+"2,\n" +
" L_1 => s_L_"+(i+1)+"1,\n" +
" L_2 => s_L_"+(i+1)+"2);\n\n";
addLibrary("RuleSelect");
arithmetic_map+=(arithmetic.isSelected()?BloqueArithAntecedente:"")+
(BloqueMemoriaAntecedente[i]!=null?BloqueMemoriaAntecedente[i]:"") +
" RulSel"+(i+1)+" : RuleSelect\n" +
" generic map(\n" +
" grad => "+name+"_grad,\n" +
" bitl => "+name+"_MFC"+(i+1)+"_bits)\n" +
" port map(\n" +
" alpha_1 => s_alpha_"+(i+1)+"1,\n" +
" alpha_2 => s_alpha_"+(i+1)+"2,\n" +
" L_1 => s_L_"+(i+1)+"1,\n" +
" L_2 => s_L_"+(i+1)+"2,\n" +
" S => s_addr("+name+"_inputs-"+restar_en_S+"),\n" +
" L => s_addr_R(("+subsuma1+") downto ("+subsuma2+")),\n" +
" alpha => s_alphas(("+(i+1)+" * "+name+"_grad) downto (("+i+" * "+name+"_grad) + 1)));\n\n"
;
}
String signalsDivision="-- Internal signals (Division)\n" +
" signal s_Num : std_logic_vector("+name+"_bitsn downto 1);\n" +
" signal s_Den : std_logic_vector("+name+"_bitsn-"+name+"_No downto 1);\n\n";
if(simplificado)
signalsDivision="";
if(!RB_RAM.isSelected()){
componentRulesMem=" component "+name+"_RulesMem\n" +
" port(\n" +
" addr : in std_logic_vector(("+suma_MFC_bits+")-1 downto 0); -- Address bus.\n" +
" do : out std_logic_vector("+ (defuzzy.equalsIgnoreCase("TakagiSugeno")?""+(mfcs.size()+1)+"*":
((defuzzy.equalsIgnoreCase("WeightedFuzzyMean")||defuzzy.equalsIgnoreCase("Quality")||defuzzy.equalsIgnoreCase("GammaQuality"))?name+"_W + ":""))+name+"_No downto 1)); -- Data bus.\n" +
" end component;\n\n";
BloqueRulMem=" RulMem : "+name+"_RulesMem\n" +
" port map(\n" +
" addr => s_addr_R,\n" +
" do => s_output_mem_R);\n\n";
}else{//RB_RAM selected
addLibrary("RulesMem_RAM");
BloqueRulMem=" RulMem : RulesMem_RAM\n" +
" generic map(\n" +
" a_bits => "+name+"_a_bits,\n" +
" d_bits => "+name+"_d_bits)\n\n" +
" port map(\n" +
" clk => clk,\n" +
" we => clk,\n" +
" addr => s_addr_R,\n" +
" di => s_output_mem_R,\n" +
" do => s_output_mem_R);\n"
;
}
addLibrary("Control");
res="---------------------------------------------------------------------------\n" +
" -- "+name+" --\n" +
"---------------------------------------------------------------------------\n\n" +
librerias+
"library XfuzzyLib;\n" +
"use XfuzzyLib.Entities.all;\n\n" +
"entity "+name+" is\n\n" +
" generic(\n" +
" "+name+"_pipe : integer := pipe_"+name+";\n" +
" "+name+"_bits : integer := bits_"+name+");\n" +
" port(\n" +
" clk : in std_logic; -- Clock signal.\n" +
" reset : in std_logic; -- Reset signal.\n" +
puertosin +//para cada entrada una linea aqui
" out1 : out std_logic_vector("+name+"_No downto 1); -- Output signal.\n" +
" pipeline : out std_logic); -- Pipeline signal.\n\n" +
"end "+name+";\n\n\n" +
"architecture FPGA of "+name+" is\n\n" +
(componentesin.equalsIgnoreCase("")&&
componentRulesMem.equalsIgnoreCase("")
?"":"-- Components declaration\n\n") +
componentesin +//para cada entrada un bloque component
componentRulesMem +
"-- Internal signals (Control)\n\n" +
" signal s_pipe : std_logic;\n" +
" signal s_acc : std_logic;\n" +
" signal s_addr : std_logic_vector("+name+"_bits downto 1);\n\n" +
arithmetic_signal +
"-- Internal signals (RuleSelect)\n" +
" signal s_alphas : std_logic_vector(("+name+"_inputs * "+name+"_grad) downto 1);\n" +
"-- Internal signals (RulMem)\n" +
" signal s_addr_R : std_logic_vector(" +suma_MFC_bits+" downto 1);\n"+
" signal s_output_mem_R : std_logic_vector("+ (defuzzy.equalsIgnoreCase("TakagiSugeno")?""+(mfcs.size()+1)+"*":
((defuzzy.equalsIgnoreCase("WeightedFuzzyMean")||defuzzy.equalsIgnoreCase("Quality")||defuzzy.equalsIgnoreCase("GammaQuality"))?name+"_W + ":""))+name+"_No downto 1);\n" +
"-- Internal signals ("+(connective.equalsIgnoreCase("min")?"Minimum":"Product")+")\n" +
" signal s_output_"+connective+" : std_logic_vector("+name+"_grad downto 1);\n" +
signalsDivision+
"begin\n\n" +
" pipeline <= s_pipe;\n\n" +
" Controller : Control\n" +
" generic map(\n" +
" inputs => "+name+"_inputs,\n" +
" bitc => "+name+"_bits,\n" +
" ncp => "+name+"_pipe)\n" +
" port map(\n" +
" clk => clk,\n" +
" reset => reset,\n" +
" addr => s_addr,\n" +
" pipe => s_pipe,\n" +
" acc => s_acc);\n\n" +
arithmetic_map +
BloqueRulMem +
generaConectivoYDefuzificadorFLC(spec)+
"end FPGA;\n"
;
return res;
}
/**
* Genera el c�digo VHDL asociado al FLC y lo almacena en el atributo vhdl.
* @param spec Especificaci�n XFL.
* @param nombre_i N�mero de orden del modulo de inferencia
* dentro del arbol de la especificacion.
*/
public void generaVHDL(Specification spec, String nombre_i) throws IOException{
int bitswhen;
String entradas="";
String rulesmem="";
String flc="";
XfvhdlProperties.dir_regl=0;
setSimplificado(spec);
String cabecera=generaCabecera();
String constantes=generaConstantes(spec) ;
for(int i=0;i<mfcs.size();i++){
bitswhen=(int)Math.ceil(Math.log(Integer.valueOf(mfcs.get(i).getn_fp()))/Math.log(2));
bits_var.add(bitswhen);
XfvhdlProperties.dir_regl+=bitswhen;
}
if(arithmetic.isSelected()){
if(MFC_ROM.isSelected()||MFC_logicBlock.isSelected()){
entradas+=generaEntradasAritmeticas();
}else if(MFC_RAM.isSelected()){
//no se generan las entradas
}
}
else // MFCs en memoria
{
if(MFC_ROM.isSelected()){
XfvhdlAntecedentMemFiles antecedentes=new XfvhdlAntecedentMemFiles();
entradas+=antecedentes.createMemorySourceROM(spec, this);
}else if(MFC_logicBlock.isSelected()){
XfvhdlAntecedentMemFiles antecedentes=new XfvhdlAntecedentMemFiles();
entradas+=antecedentes.createMemorySourceLB(spec, this);
}else if(MFC_RAM.isSelected()){
//no se generan las entradas
}
}
if(RB_ROM.isSelected()){
rulesmem=generaRulesMemROM(spec,nombre_i);
}else if(RB_logicBlock.isSelected()){
rulesmem=generaRulesMemLB(spec,nombre_i);
}else if(RB_RAM.isSelected()){
//No se genera la rulebase
}
flc+=generaFinFLC(spec);
vhdl=cabecera+constantes+entradas+rulesmem+flc;
}
/**Genera los ficheros complementarios si el usuario lo ha elegido as�.
* @param nombre_i N�mero de orden del modulo de inferencia
* dentro del arbol de la especificacion.*/
public void generaComplementarios(String nombre_i) throws IOException{
XfvhdlAntecedentMemComplementaryFiles amcf =
new XfvhdlAntecedentMemComplementaryFiles();
amcf.createCF(spec,this);
XfvhdlRulesMemComplementaryFile rmcf =
new XfvhdlRulesMemComplementaryFile();
if(defuzzy!="TakagiSugeno")
rmcf.createCF(spec, nombre_i, bits_var, null, calculateWeights, No, W, this);
else
rmcf.createCF(spec, nombre_i, bits_var, getTakSugBinario(No), calculateWeights, No, W, this);
}
/**Este m�todo actualiza el atributo est�tico XfvhdlProperties.listaBloquesDeBiblioteca,
* a�adi�ndole el bloque de librer�a que se le pasa por par�metro.
* @param l Nombre del bloque de librer�a.*/
private void addLibrary(String l){
if(!XfvhdlProperties.listaBloquesDeBiblioteca.contains(l))
XfvhdlProperties.listaBloquesDeBiblioteca.add(l);
}
/**M�todo que a partir de una especificaci�n XFL indica si sus entradas no
* est�n normalizadas porque el solapamiento de las funciones de pertenencia
* de alguna de ellas es mayor que 1.
* @param spec Especificaci�n XFL.
* @return No normalizadas por solapamiento > 1.*/
public boolean entradasNoNormalizadasMayor1(Specification spec){
boolean res=false;
Variable[] var = spec.getSystemModule().getInputs();
for (int i=0;i<mfcs.size()&&!res;i++){
u = disc.discretizeUniverse(var[i],this,i);
res=disc.getEntradasNoNormalizadasMayor1();
}
return res;
}
/**M�todo que a partir de una especificaci�n XFL indica si sus entradas no
* est�n normalizadas porque el solapamiento de las funciones de pertenencia
* de alguna de ellas es menor que 1.
* @param spec Especificaci�n XFL.
* @return No normalizadas por solapamiento < 1.*/
public boolean entradasNoNormalizadasMenor1(Specification spec){
boolean res=false;
boolean aux=false;
Variable[] var = spec.getSystemModule().getInputs();
for (int i=0;i<mfcs.size();i++){
u = disc.discretizeUniverse(var[i],this,i);
aux=disc.getEntradasNoNormalizadasMenor1();
if(aux){
mfcs.get(i)._a="[ ];\n";
mfcs.get(i).slopes="[ ];\n";
mfcs.get(i).listaPendientes=new ArrayList<Double>();
mfcs.get(i).listaPuntos=new ArrayList<Double>();
}
res=aux||res;
}
if(res)
setEntradasNoNormalizadasMenor1(res);
return res;
}
/**@param spec Especificaci�n XFL.
* @return C�digo VHDL del conectivo y el defuzzidicador del FLC.*/
private String generaConectivoYDefuzificadorFLC(Specification spec){
String minprod="";
String Mui=" Mui => s_alphas,\n";
String def;
if (mfcs.size()!=1){
addLibrary(connective.equalsIgnoreCase("min")?"Minimum":"Product");
minprod=(connective.equalsIgnoreCase("min")?" min : Minimum\n":" prod : Product\n") +
" generic map(\n" +
" grad => "+name+"_grad,\n" +
" inputs => "+name+"_inputs)\n" +
" port map(\n" +
" input => s_alphas,\n" +
" output => s_output_"+(connective.equalsIgnoreCase("min")?"min":"prod")+");\n\n"
;
if(connective.equalsIgnoreCase("min")){
Mui=" Mui => s_output_min,\n";
}else
Mui=" Mui => s_output_prod,\n";
}
String div=" Div : Division\n" +
" generic map(\n" +
" No => "+name+"_No,\n" +
" bitsn => "+name+"_bitsn)\n" +
" port map(\n" +
" clk => clk,\n" +
" pipe => s_pipe,\n" +
" Num => s_Num,\n" +
" Den => s_Den,\n" +
" result => out1);\n\n\n";
if(simplificado)
div="\n\n\n";
if(defuzzy.equalsIgnoreCase("FuzzyMean")){
if(!simplificado){
addLibrary("FuzzyMean");
addLibrary("Division");
def=" Defuzz : FuzzyMean\n" +
" generic map(\n" +
" No => "+name+"_No,\n" +
" grad => "+name+"_grad,\n" +
" inputs => "+name+"_inputs,\n" +
" bitsn => "+name+"_bitsn)\n" +
" port map(\n" +
" clk => clk,\n" +
" pipe => s_pipe,\n" +
" acc => s_acc,\n" +
" ci => s_output_mem_R,\n" +
Mui + //aqui hay diferencias
" Num => s_Num,\n" +
" Den => s_Den);\n\n"+
div;
}
else{
addLibrary("FuzzyMean_s");
def=" Defuzz : FuzzyMean_s\n" +
" generic map(\n" +
" No => "+name+"_No,\n" +
" grad => "+name+"_grad)\n" +
" port map(\n" +
" clk => clk,\n" +
" pipe => s_pipe,\n" +
" acc => s_acc,\n" +
" ci => s_output_mem_R,\n" +
Mui +
" result => out1);\n\n";
}
}else if(defuzzy.equalsIgnoreCase("MaxLabel")){//En este caso siempre es simplificado
addLibrary("MaxLabel");
def=" Defuzz : MaxLabel\n" +
" generic map(\n" +
" No => "+name+"_No,\n" +
" grad => "+name+"_grad)\n" +
" port map(\n" +
" clk => clk,\n" +
" pipe => s_pipe,\n" +
" acc => s_acc,\n" +
" ci => s_output_mem_R,\n" +
Mui +
" result => out1);\n\n";
}else if(defuzzy.equalsIgnoreCase("TakagiSugeno")){
String ents="";
String coefGeneric="\t\t\tPc => "+name+"_Pc,\n";
int coef1=mfcs.size()+1;
int coef2=mfcs.size();
String abc="\t\t\tc => s_output_mem_R ("+coef1+"*"+name+"_No downto "+coef2+"*"+name+"_No+1),\n";
for(int i=0;i<mfcs.size();i++){
ents+="\t\t\tx"+(i+1)+" => in"+(i+1)+",\n";
coef1--;
coef2--;
abc+="\t\t\ta"+(i+1)+" => s_output_mem_R ("+coef1+"*"+name+"_No downto "+coef2+"*"+name+"_No+1),\n";
coefGeneric+="\t\t\tPa"+(i+1)+" => "+name+"_Pa"+(i+1);
if(i<mfcs.size()-1)
coefGeneric+=",\n";
else
coefGeneric+=")\n";
}
if(connective.equalsIgnoreCase("min")){
Mui=" Mui => s_output_min,\n";
}else
Mui=" Mui => s_output_prod,\n";
if(!simplificado){
addLibrary("TakagiSugeno");
addLibrary("Division");
def=" Defuzz : TakagiSugeno\n" +
" generic map(\n" +
" No => "+name+"_No,\n" +
" N => "+name+"_N,\n" +
" grad => "+name+"_grad,\n" +
" bitsn => "+name+"_bitsn,\n" +
coefGeneric +
" port map(\n" +
" clk => clk,\n" +
" pipe => s_pipe,\n" +
" acc => s_acc,\n" +
ents +
abc+
Mui +
" Num => s_Num,\n" +
" Den => s_Den);\n\n"+
div;
}
else{
addLibrary("TakagiSugeno_s");
def=" Defuzz : TakagiSugeno_s\n" +
" generic map(\n" +
" No => "+name+"_No,\n"+
" N => "+name+"_N,\n"+
" grad => "+name+"_grad,\n"+
coefGeneric +
" port map(\n" +
" clk => clk,\n" +
" pipe => s_pipe,\n" +
" acc => s_acc,\n" +
ents +
abc +
Mui +
" result => out1);\n\n";
}
}else{//WeightedFuzzyMean, Quality o GammaQuality=>siempre con div
addLibrary("WeightedFuzzyMean");
addLibrary("Division");
def=" Defuzz : WeightedFuzzyMean\n" +
" generic map(\n" +
" No => "+name+"_No,\n" +
" grad => "+name+"_grad,\n" +
" W => "+name+"_W,\n" +
" inputs => "+name+"_inputs,\n" +
" bitsn => "+name+"_bitsn)\n" +
" port map(\n" +
" clk => clk,\n" +
" acc => s_acc,\n" +
" pipe => s_pipe,\n" +
" ci => s_output_mem_R("+name+"_No+"+name+"_W downto "+name+"_W+1),\n" +
Mui +
" Gmi => s_output_mem_R("+name+"_W downto 1),\n" +
" Num => s_Num,\n" +
" Den => s_Den);\n\n"+
div;
}
return (minprod+def);
}
/*double PasarDecimalBinario(double valor, double max, double min,
int precision) {
double max_bin;
int resultado;
max_bin = Math.pow(2.0, precision) - 1;
resultado = (int) ((max_bin * (valor - min)) / (max - min));
return (resultado);
}*/
// CLASE PRIVADA QUE REPRESENTA A LOS MFCs
/**Subclase que representa a los MFCs.*/
public class MFC {
/**N�mero de funciones de pertenencia.*/
public String n_fp;
/**Puntos de corte.*/
public String _a;
/**Pendientes.*/
public String slopes;
/**Lista de pendientes.*/
public ArrayList<Double> listaPendientes;
/**Lista de puntos de corte.*/
public ArrayList<Double> listaPuntos;
/**Constructor de la subclase MFC.*/
public MFC(String n_fp, String _a, String slopes, ArrayList<Double> listaPuntos, ArrayList<Double> listaPendientes) {
this.listaPendientes=listaPendientes;
this.n_fp = n_fp;
this._a = _a;
this.slopes = slopes;
this.listaPuntos=listaPuntos;
}
//M�TODOS GET
/**@param pos N� de la funci�n de pertenencia de la que quiero
* saber su pendiente.
* @return Pendiente.*/
public double getPendiente(int pos){
return listaPendientes.get(pos);
}
/**@return Techo del m�ximo de las pendientes del MFC.*/
private int getPendienteMayor(){
double pdte=0;
for(int i=0;i<listaPendientes.size();i++){
if (listaPendientes.get(i)>pdte)
pdte=listaPendientes.get(i);
}
return (int)Math.ceil(pdte);
}
/**@param pos N� de la orden del punto de corte.
* @return Punto de corte.*/
public double getPunto (int pos){
return listaPuntos.get(pos);
}
/**@return N� de funciones de pertenencia.*/
public String getn_fp() {
return n_fp;
}
/**@return Puntos de corte*/
public String get_a() {
return _a;
}
/**@return Pendientes.*/
public String getslopes() {
return slopes;
}
//M�TODOS DE LA CLASE
/**@return N�mero de bits de la parte entera de P*/
public int pbi(){
int bits_pbi;
int pdte_mayor=getPendienteMayor();
bits_pbi=(int)Math.ceil(Math.log(pdte_mayor)/Math.log(2));
return bits_pbi;
}
}
/**Clase privada que gestiona el hecho de que cuando el usuario elige
* generar c�digo con antecedentes en memoria, se bloquee el campo
* que captura el n� de bits para la pendiente, ya que no hace falta
* indicarlo.*/
private class VoteActionListener implements ActionListener {
public void actionPerformed(ActionEvent ex) {
String choice = group1.getSelection().getActionCommand();
if (choice=="memory"){
numBitsInformation[3].setText("0");
numBitsInformation[3].setEditable(false);
numBitsInformation[3].setFieldEnabled(false);
numBitsInformation[3].setLabelEnabled(false);
}else{
numBitsInformation[3].setEditable(true);
numBitsInformation[3].setFieldEnabled(true);
numBitsInformation[3].setLabelEnabled(true);
}
}
}
}