Mostrando entradas con la etiqueta simulación. Mostrar todas las entradas
Mostrando entradas con la etiqueta simulación. Mostrar todas las entradas

lunes, 23 de febrero de 2009

Hola Mundo con octave y c++

Requisitos:
Tener instalado octave, octave-headers y build-essential

En nuestro editor de texto predilecto (vim) escribimos lo siguiente


#include <octave/oct.h>
DEFUN_DLD(miHolaMundo, args, ,
"Sirve para imprimir un N Holas Mundo " )
{
unsigned int N = args(0).int_value(); //El argumento 0 lo convertimos a entero y
//se lo almacenamos en N

for(int i = 0; i<N;i++)
octave_stdout<<"Hola Mundo"<<endl;

return octave_value(0);
}

En la primera línea incluimos las cabeceras de octave y el la segunda definimos que nombre tendrá nuestra función. Guardamos el archivo con el mismo nombre de la función (miHolaMundo.cc) y compilamos

mkoctfile miHolaMundo.cc

Esto nos va a generar dos archivos:

miHolaMundo.o miHolaMundo.oct

donde miHolaMundo.oct es la función que acabamos de hacer.

Inicamos el octave y probamos:

octave:1> help miHolaMundo
Sirve para imprimir un Hola Mundo /home/s/proyectos/c/octave/miHolaMundo.oct

Additional help for built-in functions and operators is
available in the on-line version of the manual. Use the command
`doc ' to search the manual index.

Help and information about Octave is also available on the WWW
at http://www.octave.org and via the help@octave.org
mailing list.
octave:2>
octave:2> miHolaMundo(1)
Hola Mundo
ans = 0
octave:3> miHolaMundo(4)
Hola Mundo
Hola Mundo
Hola Mundo
Hola Mundo
ans = 0
octave:4>


El que sigue es parte del código para probar una Memoria RAM que esta dentro de un FPGA, lo recorte sólo para mostrar, como se usan Complejos y como se retorna a octave una o más variables. Esta función tiene como parametros de entrada un Vector Complejo, tamaño de la palabra y tamaño de la parte fraccional para convertir a punto fijo los valores del vector comlejo.



#include <octave/oct.h>
#include <iostream>
#include <fstream>
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <oct-rand.h>
#include <oct-cmplx.h>

//inline void dec2bin(unsigned int a,unsigned int width_word,char * cadena);
inline int to_fixed(double data_in, unsigned int QW,unsigned int QF);
inline double f2d(int Dfixed,unsigned QF);

DEFUN_DLD (MemTest,args, ,
"Probar RAM FPGA via RS232\n")
{

ComplexColumnVector Data = args(0).complex_column_vector_value();
int len = Data.length();
ComplexColumnVector DataF=Data;
ComplexColumnVector DataR=Data;
unsigned int QW=args(1).int_value();
unsigned int QF=args(2).int_value();

for (int i = 0; i<len;i++) {
real(DataF(i))=f2d(to_fixed(real(Data(i)),QW,QF),QF);
imag(DataF(i))=f2d(to_fixed(imag(Data(i)),QW,QF),QF);
};

octave_value_list retval;

retval(0) = octave_value(DataF);
retval(1) = octave_value(DataR);
return retval;
}

inline int to_fixed(double data_in, unsigned int QW,unsigned int QF)
{
int x_0=0,j=1;
//we need to convert to double to QW and QF because oct.h only have pow(double,double)
if(data_in<0){ int x_0=pow(2.0,double(QW)); };
return int(x_0+pow(2.0,double(QF))*data_in);
}
inline double f2d(int Dfixed,unsigned QF)
{
return double(Dfixed)/(pow(2.0,double(QF)));
}

Compilamos con mkoctfile y probamos

octave:1> x=randn(4,1)+j*randn(4,1)
x =

-0.80972 + 3.54049i
-0.38686 - 0.35778i
-0.45699 + 0.05577i
-0.48280 + 1.01243i

octave:2> MemTest(x,13,10)
ans =

-0.80957 + 3.54004i
-0.38672 - 0.35742i
-0.45605 + 0.05566i
-0.48242 + 1.01172i

octave:3> [y z]=MemTest(x,13,10)
y =

-0.80957 + 3.54004i
-0.38672 - 0.35742i
-0.45605 + 0.05566i
-0.48242 + 1.01172i

z =

-0.80972 + 3.54049i
-0.38686 - 0.35778i
-0.45699 + 0.05577i
-0.48280 + 1.01243i



Como se puede ver, el primer resultado que nos regresa nuestra función es equivalente en punto fijo de 13 bits de los cuales 10 bits son para la parte fraccional y 1 para el signo.

viernes, 1 de febrero de 2008

GHDL con las librerías UNISIM de Xilinx

¿Porqué usar ghdl?. En primer lugar surgió de la necesidad de poder realizar simulaciones de mi código de VHDL en linux debido a que el simulador del ISEWebPACK 9.1 y 9.2 de Xilinx no se digna en trabajar, siempre me manda el error 607 el cual si no es mi culpa, como lo puedo demostrar, pues fácilmente, abrí el ISE e inicié un nuevo proyecto pero en esta ocasión que fueran esquemáticos y no vhdl, hice una "and" y lo traté de simular y me arrojó el mismo error. Conclusión no es error mío es de la herramienta, ellos mismos está diciendo que no saben como construir una "and", jejejeje.

En segundo lugar, tenía que utilizar las librerías unisim:

Library UNISIM;
use UNISIM.vcomponents.all;

Voy a suponer que tenemos instalado en nuestro sistema alguna de las dos versiones anteriores del ISEWebPACK.

Desde la consola primero nos creamos una carpeta para ubicar nuestro código vhdl y dentro de ella crearemos una carpeta llamada unisim.

$ mkdir vhdl
$ mkdir vhdl/unisim

Ahora copiamos el contenido de la carpeta vhdl/src/unisims en el directorio del ISEWebPack, que en mi caso se encuentra en /opt/Xilinx92i/vhdl/src/unisims/, al directorio unisim que acabamos de crear.

$ cp /opt/Xilinx92i/vhdl/src/unisims/* vhdl/unisim/

Ahora nos movemos a la carpeta vhdl/unisim/

$ cd vhdl/unism

y compilamos estas librerías con

~/vhdl/unisim$ ghdl -a --work=unisim --ieee=synopsys -fexplicit unisim_VCOMP.vhd
~/vhdl/unisim$ ghdl -a --work=unisim --ieee=synopsys -fexplicit unisim_SMODEL.vhd
~/vhdl/unisim$ ghdl -a --work=unisim --ieee=synopsys -fexplicit unisim_VPKG.vhd

~/vhdl/unisim$ ghdl -a --work=unisim --ieee=synopsys -fexplicit --warn-no-vital-generic unisim_VITAL.vhd
unisim_VITAL.vhd:150533:18:warning: universal integer bound must be numeric literal or attribute
unisim_VITAL.vhd:176564:57: variable "write_a_write_b" is not visible here
unisim_VITAL.vhd:176565:57: variable "read_a_write_b" is not visible here
unisim_VITAL.vhd:176566:57: variable "write_a_read_b" is not visible here
unisim_VITAL.vhd:176567:57: variable "write_b_write_a" is not visible here
unisim_VITAL.vhd:176568:57: variable "read_b_write_a" is not visible here
unisim_VITAL.vhd:176569:57: variable "write_b_read_a" is not visible here
/usr/lib/ghdl/bin/ghdl: compilation error
Observamos que nos manda un error, pero no es de preocuparse es solo cuestion de abrir el archivo unisim_VITAL.vhd y comentar las líneas que nos indica (176564,176565,176566,176567,176568,176569).
Las líneas en cuestion son:
variable Write_A_Write_B : memory_collision_type := Write_A_Write_B;
variable Read_A_Write_B : memory_collision_type := Read_A_Write_B;
variable Write_A_Read_B : memory_collision_type := Write_A_Read_B;
variable Write_B_Write_A : memory_collision_type := Write_B_Write_A;
variable Read_B_Write_A : memory_collision_type := Read_B_Write_A;
variable Write_B_Read_A : memory_collision_type := Write_B_Read_A;

En este punto si volvieramos a tratar de compilar nos arrojaría el mismo error sólo que en líneas distintas.

unisim_VITAL.vhd:188630:57: variable "write_a_write_b" is not visible here
unisim_VITAL.vhd:188631:57: variable "read_a_write_b" is not visible here
unisim_VITAL.vhd:188632:57: variable "write_a_read_b" is not visible here
unisim_VITAL.vhd:188633:57: variable "write_b_write_a" is not visible here
unisim_VITAL.vhd:188634:57: variable "read_b_write_a" is not visible here
unisim_VITAL.vhd:188635:57: variable "write_b_read_a" is not visible here

Por lo tanto sería buena idea comentarlas también, ya sea que busquemos en el archivo por "variable Write_A_Write_B : memory_collision_type := Write_A_Write_B;" , comentar esta línea y las subsecuentes o movernos hasta la línea indicada que sería la 188630 y comentarlas.

Hecho lo anterior volvemos a compilar con:
ghdl -a --work=unisim --ieee=synopsys -fexplicit --warn-no-vital-generic unisim_VITAL.vhd

Ya compilado nos retachamos a la carpeta vhdl ($ cd ..) para empezar a realizar nuestras pruebas, en donde compilaremos nuestros proyectos con:

ghdl -a --ieee=synopsys -Punisim -fexplicit