//--------------------------------------------------------------------------------//
// 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 xfuzzy.*;
import xfuzzy.lang.*;
/**
* Clase que genera el c�digo de las memorias de antecedentes
* del m�dulo de inferencia
*
* @author Lidia Delgado Carretero
*
*/
public class XfvhdlAntecedentMemFiles {
// El siguiente atributo se usa para mostrar los mensajes por pantalla
//private XfvhdlMessage msg;
/***/
XfvhdlError error;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// CONSTRUCTOR DE LA CLASE
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/** Constructor de la clase
*/
XfvhdlAntecedentMemFiles() {
error = new XfvhdlError();
}
/**
* M�todo que crea la cadena que ser� escrita en la zona de
* antecedentes en memoria, siempre y cuando se sinteticen en ROM.
* @param spec Especificaci�n XFL.
* @param flc M�dulo de inferencia.
* @return Devuelve la cadena que ser� escrita en el fichero VHDL
* del m�dulo de inferencia, en la zona de antecedentes en memoria.
*/
public String createMemorySourceROM(Specification spec, XfvhdlFLC flc) {
Variable[] var = spec.getSystemModule().getInputs();
String code="", alphasport="", elesport="";
XfvhdlProperties.dir_regl=0;
for(int i=1;i<=flc.getmfcs().size();i++){
XfvhdlUniverse u = new XfvhdlUniverse();
XfvhdlDiscretizeUniverse disc = new XfvhdlDiscretizeUniverse();
u = disc.discretizeUniverse(var[i-1], flc, (i-1));
int bitswhen=(int)Math.ceil(Math.log(Integer.valueOf(flc.getmfcs().get(i-1).getn_fp()))/Math.log(2));
flc.addBits_var(bitswhen);
XfvhdlProperties.dir_regl+=bitswhen;
alphasport="\t\talpha_1 : out std_logic_vector("+flc.getname()+"_grad downto 1);\n"
+ "\t\talpha_2 : out std_logic_vector("+flc.getname()+"_grad downto 1);\n";
elesport="\t\tL_1 : out std_logic_vector("+flc.getname()+"_MFC"+i+"_bits downto 1);\n"
+ "\t\tL_2 : out std_logic_vector("+flc.getname()+"_MFC"+i+"_bits downto 1));\n";
code+="---------------------------------------------------------------------------\n"
+ "-- "+flc.getname()+"_AntecedentMem"+i+" --\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"
+ "use WORK."+flc.getname()+"_Constants.all;\n"
+ "\n"
+ "entity "+flc.getname()+"_AntecedentMem"+i+" is\n\n"
+ "\tport(\n"
+ "\t\tpipe\t: in std_logic;\n"
+ "\t\taddr\t: in std_logic_vector("+flc.getname()+"_N-1 downto 0);\n"
+ alphasport
+ elesport
+ "\n"
+ "end "+flc.getname()+"_AntecedentMem"+i+";\n"
+ "\n"
+ "\n"
+ "---------------------------------------------------------------------------\n"
+ "-- Architecture description --\n"
+ "---------------------------------------------------------------------------\n"
+ "\n"
+ "architecture FPGA of " + flc.getname() + "_AntecedentMem" + i + " is\n\n"
+ "signal s_addr : std_logic_vector(" + flc.getname() + "_N-1 downto 0);\n"
+ "signal s_data : std_logic_vector(2*" + flc.getname() + "_grad+" + flc.getname() + "_MFC"+i+"_bits downto 1);\n\n"
+ "\tsubtype ROM_WORD is std_logic_vector(2*" + flc.getname() + "_grad+" + flc.getname() + "_MFC" + i + "_bits-1 downto 0);\n"
+ "\ttype ROM_TABLE is array (0 to 2**" + flc.getname() + "_N-1) of ROM_WORD;\n"
+ "\tconstant ROM : ROM_TABLE := ROM_TABLE'(\n";
XfvhdlBinaryDecimal converter = new XfvhdlBinaryDecimal();
String val1 = new String();
String val2 = new String();
for (int j = 0; j < u.getLength() - 1; j++) {
val1 =
converter.toBinaryInRange(
u.getXUniversePoint(j).getVal1(),
0.0,
1.0,
flc.getgrad());
val2 =
converter.toBinaryInRange(
u.getXUniversePoint(j).getVal2(),
0.0,
1.0,
flc.getgrad());
code += "\t\tROM_WORD'(\""
+ converter.toBinary(
(u.getXUniversePoint(j).getEtiq()) - 1,
(int) Math.ceil(
Math.log(Double.valueOf(flc.getmfcs().get(i-1).getn_fp()))
/ Math.log((double) 2)))
+ val1
+ val2
+ "\"),\n";
}
// La �ltima l�nea es especial porque hay que ponerle un
// parentesis al final
val1 =
converter.toBinaryInRange(
u.getXUniversePoint(u.getLength() - 1).getVal1(),
0.0,
1.0,
flc.getgrad());
val2 =
converter.toBinaryInRange(
u.getXUniversePoint(u.getLength() - 1).getVal2(),
0.0,
1.0,
flc.getgrad());
code += "\t\tROM_WORD'(\""
+ converter.toBinary(
(u.getXUniversePoint(u.getLength() - 1).getEtiq()) - 1,
(int) Math.ceil(
Math.log(Double.valueOf(flc.getmfcs().get(i-1).getn_fp()))
/ Math.log((double) 2)))
+ val1
+ val2
+ "\"));\n";
code += "begin\n\n"
+ "\t\ts_addr <= addr when rising_edge(pipe);\n"
+ "\t\ts_data <= ROM(conv_integer(s_addr));\n"
+ "\t\tL_1 <= s_data(2*"+flc.getname()+"_grad+"+flc.getname()+"_MFC"+i+"_bits downto (2*"+flc.getname()+"_grad)+1);\n"
+ "\t\tL_2 <= s_data(2*"+flc.getname()+"_grad+"+flc.getname()+"_MFC"+i+"_bits downto (2*"+flc.getname()+"_grad)+1) + '1';\n"
+ "\t\talpha_1 <= s_data(2*"+flc.getname()+"_grad downto "+flc.getname()+"_grad+1);\n"
+ "\t\talpha_2 <= s_data("+flc.getname()+"_grad downto 1);\n"
+ "end FPGA;\n\n";
}
return code;
}
/**
* M�todo que crea la cadena que ser� escrita en la zona de
* antecedentes en memoria, siempre y cuando se sinteticen en
* bloques l�gicos.
* @param spec Especificaci�n XFL.
* @param flc M�dulo de inferencia.
* @return Devuelve la cadena que ser� escrita en el fichero VHDL
* del m�dulo de inferencia, en la zona de antecedentes en memoria.
*/
public String createMemorySourceLB(Specification spec, XfvhdlFLC flc) {
Variable[] var = spec.getSystemModule().getInputs();
String code="", alphasport="", elesport="";
String others = "";
XfvhdlProperties.dir_regl=0;
for(int i=1;i<=flc.getmfcs().size();i++){
XfvhdlUniverse u = new XfvhdlUniverse();
XfvhdlDiscretizeUniverse disc = new XfvhdlDiscretizeUniverse();
u = disc.discretizeUniverse(var[i-1], flc, (i-1));
int bitswhen=(int)Math.ceil(Math.log(Integer.valueOf(flc.getmfcs().get(i-1).getn_fp()))/Math.log(2));
flc.addBits_var(bitswhen);
XfvhdlProperties.dir_regl+=bitswhen;
others = "";
for(int j=0;j<(2*flc.getgrad()+bitswhen);j++){
others+= "-";
}
alphasport="\t\talpha_1 : out std_logic_vector("+flc.getname()+"_grad downto 1);\n"
+ "\t\talpha_2 : out std_logic_vector("+flc.getname()+"_grad downto 1);\n";
elesport="\t\tL_1 : out std_logic_vector("+flc.getname()+"_MFC"+i+"_bits downto 1);\n"
+ "\t\tL_2 : out std_logic_vector("+flc.getname()+"_MFC"+i+"_bits downto 1));\n";
code+="---------------------------------------------------------------------------\n"
+ "-- "+flc.getname()+"_AntecedentMem"+i+" --\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"
+ "use WORK."+flc.getname()+"_Constants.all;\n"
+ "\n"
+ "entity "+flc.getname()+"_AntecedentMem"+i+" is\n\n"
+ "\tport(\n"
+ "\t\tpipe\t: in std_logic;\n"
+ "\t\taddr\t: in std_logic_vector("+flc.getname()+"_N-1 downto 0);\n"
+ alphasport
+ elesport
+ "\n"
+ "end "+flc.getname()+"_AntecedentMem"+i+";\n"
+ "\n"
+ "\n"
+ "---------------------------------------------------------------------------\n"
+ "-- Architecture description --\n"
+ "---------------------------------------------------------------------------\n"
+ "\n"
+ "architecture FPGA of "+flc.getname()+"_AntecedentMem"+i+" is\n"
+ " signal s_addr : std_logic_vector("+flc.getname()+"_N-1 downto 0);\n\n"
+ " signal s_data : std_logic_vector(2*"+flc.getname()+"_grad+"+flc.getname()+"_MFC"+i+"_bits downto 1);\n\n"
+ "begin\n"
+ " s_addr <= addr when rising_edge(pipe);\n\n"
+ " Read_mem : process(s_addr)\n"
+ " begin\n\n"
+ " case s_addr is\n";
XfvhdlBinaryDecimal converter = new XfvhdlBinaryDecimal();
String val1 = new String();
String val2 = new String();
String val = new String();
for (int j = 0; j < u.getLength(); j++) {
val = converter.toBinary(j, flc.getN());
val1 =
converter.toBinaryInRange(
u.getXUniversePoint(j).getVal1(),
0.0,
1.0,
flc.getgrad());
val2 =
converter.toBinaryInRange(
u.getXUniversePoint(j).getVal2(),
0.0,
1.0,
flc.getgrad());
code +=" when \""
+ val
+ "\" => s_data <= \""
+ converter.toBinary(
(u.getXUniversePoint(j).getEtiq()) - 1,
(int) Math.ceil(
Math.log(Double.valueOf(flc.getmfcs().get(i-1).getn_fp()))
/ Math.log((double) 2)))
+ val1
+ val2
+ "\";\n";
}
code +=" when others => s_data <= \""
+ others + "\";\n"
+ " end case;\n"
+ " end process Read_mem;\n\n"
+ " L_1 <= s_data(2*"+flc.getname()+"_grad+"+flc.getname()+"_MFC"+i+"_bits downto (2*"+flc.getname()+"_grad)+1);\n"
+ " L_2 <= s_data(2*"+flc.getname()+"_grad+"+flc.getname()+"_MFC"+i+"_bits downto (2*"+flc.getname()+"_grad)+1) + '1';\n"
+ " alpha_1 <= s_data(2*"+flc.getname()+"_grad downto "+flc.getname()+"_grad+1);\n"
+ " alpha_2 <= s_data("+flc.getname()+"_grad downto 1);\n\n"
+ "end FPGA;\n\n";
}
return code;
}
} // Fin de la clase