Está en la página 1de 3

////////////////////////////// EJERCICIO 1 DE ENERO DEL 2020 //////////////////////////////////

// Queremos implementar un filtro FIR de 100 etapas. No se puede cambiar la interface.


// Los coeficientes están almacenados en una memoria ROM de simple puerto que se puede leer
// una vez por ciclo de reloj.
// Los datos de entrada se almacenan en una memoria RAM de simple puerto que se puede leer
// una vez por ciclo de reloj.
// Asumiremos que los operadores aritméticos son combinacionales y lo suficientemente rápidos.
// Completar el código C y añadir los pragmas que estiméis oportunos para que la función
// tarde menos de 90 ciclos de reloj utilizando el mínimo número de recursos.
// Todas las variables tienen que declararse con su tipo. La salida es los 12 bits más
// significativos del filtro.
// Indicar además:
// 1) el número de ciclos de reloj necesarios para realizar la operación
// 2) el número de sumadores y multiplicadores utilizados.
// 3) el número y el tipo de memorias utilizadas.

// #include "fir.h"
// #define N 100
// void fir (ap_int<12>*y, ap_int<10> x)
/// {
// constant ap_int<16> c[N]=#include "coeff.h";
// #pragma HLS RESOURCE variable=c core=ROM_1P_1S latency=1
// constant ap_int<10> xv[N];
// #pragma HLS RESOURCE variable=xv core=RAM_1P_1S latency=1
// }

///////////////////////////////////////// CODIGO ///////////////////////////////////////////////

#include "fir.h"
#define N 100

void fir (ap_int<12>*y, ap_int<10> x)


{
constant ap_int<16> c[N]=#include "coeff.h";
#pragma HLS RESOURCE variable=c core=ROM_1P_1S latency=1
constant ap_int<10> xv[N];
#pragma HLS RESOURCE variable=xv core=RAM_1P_1S latency=1

// Creo un acumulador de 33 bits

ap_int<33> acc=0;

// Calculo de los bits del acumulador:


// x:10 bits + coef: 16 bits = 26 bits (x*c)
// 100 etapas -> log2(100)= 7 bits
// acc = 33 bits

// pretendo partir ambas memorias de 100 bloques en dos de 50 para reducir los ciclos de operación
(+ rápido)
// usar el block y el cyclic da igual en este caso
// el block te divide por la mitad y cyclic te divide en pares e impares

#pragma HLS array_partition variable=c cyclic factor=2 dim=1 // factor 2 para que sea la mitad
#pragma HLS array_partition variable=xv cyclic factor=2 dim=1 // dimension 1 porque es un vector y
no una matriz
ap_int<10> data; // variable auxiliar de la entrada

// Declaración de punteros
int cont = N - 1;

// Muy IMP poner loop

xv[cont] = x; // Escribimos nuevo x en la RAM


acc += (ap_int<33>)c[0] * (ap_int<33>) xv[cont];

#pragma HLS unroll factor=2


// Esto junto con el array_partition debería permitir ejecutar el loop en la mitad de ciclos

loop: for (int i=1; i<N; i++) {


if (cont==0){
cont = N - 1;
}
else {
cont = cont - 1;
}
acc += (ap_int<33>)c[i] * (ap_int<33>) xv[cont];
}
*y = acc<32:21>; // 12 bits mas significativos del filtro es la salida
}
// Tardaría 50 ciclos + la latencia del sumador + la latencia del multiplicador
// Utiliza 1 sumador y 1 multiplicador.
// Se utilizan 2 RAM de xv y 2 ROM de c.
////////////////////////////// EJERCICIO 2 DE SEPTIEMBRE DEL 2018 //////////////////////////////////

// El código siguiente representa un filtro FIR.


// La variable shift_reg se tiene que implementar con un registro de
// desplazamiento debido a la codificación utilizada.
// Modificar el código C para que se pueda implementar en una RAM.
// Para ello solo se podrá escribir en una sola posición por llamada a la función.
// No hay restricciones en cuanto a las lecturas.

///////////////////////////////////////// CODIGO /////////////////////////////////////////////////

#include "fir.h"
#define N 100

void fir (data_t*y, data_t x)


{
static data_t shift_reg[N];
constant static coef_t c[N] = #include "coeff.h"
acc_t acc;
data_t data;
int i;
acc = 0;
int cont = N-1;
shift_reg[cont] = x;

Loop: for (i=0; i<N; i++)


{
if (cont==0){
cont = N - 1;
}
else
{
cont = cont - 1;
}
acc += (ap_int<33>)c[i] * (ap_int<33>) shift_reg[cont];
}
*y = acc;
}

También podría gustarte