9. Aplicaciones de prueba

9.1. WB_RAM

9.1.1. Descripción general

Esta aplicación implementa una memoria dentro del FPGA. Se pueden realizar lecturas y escrituras a esta, utilizando el rango de direcciones asignado a BAR1 del core PCI.

bloques_wbram.jpg

Fue utilizada mayormente para desarrollar el driver y realizar las primeras pruebas del core PCI.

9.1.2. Descripción funcional

La aplicación usa una instancia del core PCITWBM para 2 BARs, BAR0 para los registros de traslación de direcciones y BAR1 para la memoria WB_RAM dentro del FPGA.

La memoria WB_RAM tiene ancho de palabra 32bits y una capacidad de 2048 bytes (512 DWORD).
Los accesos de lectura y escritura deben de ser de 32 bits de ancho, no permite escritura de a byte.

La aplicación es la encargada de conectarlos utilizando sus interfaces Wishbone.

9.1.3. Archivos requeridos

El diseño requiere de:

9.1.3.1. pcitwbm

Parámetros de la instancia:

 pcitwbm_top0: pcitwbm_top
     GENERIC MAP(vendor_id    =>  X"1172",
               device_id      =>  X"ABBA",
               subsystem_id   =>  X"10E9", 
               subsystem_vid  =>  X"10E9",
               NUMBER_OF_BARS => 2,  
               BAR_0_SIZE     => 64,
               BAR_0_LOW_NIBBLE => 0,
               BAR_1_SIZE     => 2048, -- mapero wb_ram de 2048 bytes
               BAR_1_LOW_NIBBLE => 0,
               FIFO_NUMWORDS  => 14,
               LAT_TIMER_INITIAL_VALUE => 7)

9.1.3.2. wb_ram

El componente wb_ram tiene el siguiente interfaz:

  COMPONENT wb_ram_interface IS
  GENERIC (RAM_WIDTH : integer := 32; 
            RAM_ADDRESS_WIDTH : integer := 7);
   PORT(
      --WB signals
      RST_I    : IN  STD_LOGIC;
      CLK_I    : IN  STD_LOGIC;
      DAT_I    : IN  STD_LOGIC_VECTOR(RAM_WIDTH-1 downto 0);
      DAT_O    : OUT STD_LOGIC_VECTOR(RAM_WIDTH-1 downto 0);
      ACK_O    : OUT STD_LOGIC;
      ADR_I    : IN  STD_LOGIC_VECTOR(RAM_ADDRESS_WIDTH-1 downto 0);
      CYC_I    : IN  STD_LOGIC;
      STB_I    : IN  STD_LOGIC;
      WE_I     : IN  STD_LOGIC;
      CTI_I    : IN STD_LOGIC_VECTOR(2 downto 0) -- Cycle type identifier
      );
   END component;

Internamente, wb_ram esta compuesta por una lpm_ram_dp y una máquina de estados para manejar el interfaz wishbone. La lpm_ram_dp es provista por la librería lpm.

LIBRARY lpm;
USE lpm.lpm_components.ALL;

Parámetros utilizados:

wb_ram0: wb_ram_interface 
GENERIC MAP (RAM_WIDTH => 32, 
     RAM_ADDRESS_WIDTH => 11)

9.1.4. Síntesis

Utilizando el Synplify PRO 7.0.1, se creó un archivo de tipo EDIF a partir de la descripción VHDL. Luego, utilizando el MAX+Plus II se sintetizó para el FPGA de la placa IIE-PCI.

Resultados de la síntesis:

FPGA Memoria Interna (bits) Celdas Lógicas fmax (MHz)
EP1K100QC208-2 17568 (35%) 1105 (22%) 35.21
EP1K100QC208-1 17568 (35%) 1105 (22%) 49.01

La asignación de pines utilizada es la incluida en el manual de usuario del core PCITWBM.

Obs: Para realizar las simulaciones de lectura y escritura, previamente deben incluirse los ciclos que inicializan el espacio de configuración del core PCITWBM, cómo lo haría el sistema al arrancar. Es necesario asignar una dirección de comienzo al BAR0 y BAR1, realizando un ciclo PCI de configuración.

9.1.5. Pruebas

Se escribió la memoria con el contenido de un archivo cualquiera y se volvió a leer su valor, comparándolo para verificar que las escrituras y lecturas se estuviesen realizando correctamente.
Para esto se utilizaron los utilitarios woff.pl y roff.pl, junto con el comando de unix cmp para realizar la comparación.

Se transcribe la secuencia de comandos:

head -c 2048 *archivo* > test.bin
./woff.pl -c 2048 /dev/rw_bar1 < test.bin
./roff.pl -c 2048 /dev/rw_bar1 > mem.bin
cmp test.bin mem.bin


Para 10 lecturas y escrituras, realizadas con el FPGA de velocidad -1, las estadísticas son las siguientes:

--------- IEEPCI Stats - HZ :  512 - loops_per_jiffy:   778240 -------

--------- W R I T E  --  M E M C O P Y -------------------------------
          |   KB/sec     |     bytes    | microseconds | tsc loops
----------+--------------+--------------+--------------+--------------
TOTAL     |         32253|         20480|           620|        247083
BAR1 TOTAL|         32253|         20480|           620|        247083
BAR2 TOTAL|             0|             0|             0|             1
BAR3 TOTAL|             0|             0|             0|             1
LAST WRITE|         32463|           512|            15|          6137
--------- R E A D  --  M E M C O P Y ---------------------------------
          |   KB/sec     |     bytes    | microseconds | tsc loops
----------+--------------+--------------+--------------+--------------
TOTAL     |          6739|         25600|          3709|       1478108
BAR1 TOTAL|          6739|         25600|          3709|       1478108
BAR2 TOTAL|             0|             0|             0|             1
BAR3 TOTAL|             0|             0|             0|             1
LAST READ |          7586|           512|            65|         26260

9.2. WB_SDRAM

9.2.1. Descripción general

Para realizar pruebas sobre la memoria SDRAM de la placa se desarrolló esta aplicación, que esta compuesta por el core PCITWBM, un core controlador SDRAM desarrollado por Jimena Saporiti y Agustin Villavedra y las señales de interconexión necesarias.

bloques_wbsdram.jpg

9.2.2. Descripción funcional

La aplicación usa una instancia del core PCITWBM para 2 BARs, BAR0 para los registros de traslación de direcciones y BAR1 para la memoria SDRAM de la placa IIE-PCI.

La memoria SDRAM tiene ancho de palabra 32bits y una capacidad de 16MB y es manejada por un controlador SDRAM con interfaz Wishbone.

La aplicación es la encargada de conectarlos utilizando sus interfaces Wishbone.

9.2.3. Archivos requeridos

El diseño requiere de:

9.2.3.1. pcitwbm

Parámetros de la instancia:

pcitwbm_top0: pcitwbm_top
GENERIC MAP(vendor_id    =>  X"1172",
               device_id      =>  X"ABBA",
               subsystem_id   =>  X"10E9", 
               subsystem_vid  =>  X"10E9",
               NUMBER_OF_BARS => 2,  
               BAR_0_SIZE     => 64,
               BAR_0_LOW_NIBBLE => 0,
               BAR_1_SIZE     => 16777216, -- 16MBytes
               BAR_1_LOW_NIBBLE => 0,
               FIFO_NUMWORDS  => 14,
               LAT_TIMER_INITIAL_VALUE => 7)

9.2.3.2. wb_sdram

El componente tiene la siguiente interfaz:

COMPONENT principal
   PORT(
            --Puertos de comunicación con el host según el protocolo wishbone:
      clk_i      :IN STD_LOGIC;
      rst_i      :IN STD_LOGIC;
      cyc_i      :IN STD_LOGIC;
      stb_i      :IN STD_LOGIC;
      we_i      :IN STD_LOGIC;
      ack_o      :OUT STD_LOGIC;
      dat_i      :IN STD_LOGIC_VECTOR(ancho_palabra-1 downto 0);  
      sel_i       :IN STD_LOGIC_VECTOR(3 downto 0);             
      dat_o      :OUT STD_LOGIC_VECTOR(ancho_palabra-1 downto 0);
      adr_i       :IN STD_LOGIC_VECTOR(num_dir-1 downto 0);
            --Puertos de comunicación con la memoria:
      dqm         :OUT STD_LOGIC_VECTOR(granos-1 downto 0);              
      dq         :INOUT STD_LOGIC_VECTOR(ancho_palabra-1 downto 0);
      comandos   :OUT STD_LOGIC_VECTOR(3 downto 0);
      dir_mem      :OUT STD_LOGIC_VECTOR(num_mem-1 downto 0);
      dir_banco   :OUT STD_LOGIC_VECTOR(num_banco-1 downto 0)
      );
END COMPONENT;

Los parámetros de configuración son constantes dentro de la librería del componente. Más información sobre el componente puede encontrarse en: http://iie.fing.edu.uy/ense/asign/dlp/proyectos/2003/sdram/index.htm

9.2.4. Síntesis

Utilizando el Synplify PRO 7.0.1, se creó un archivo de tipo EDIF a partir de la descripción VHDL. Luego, utilizando el MAX+Plus II se sintetizó para el FPGA de la placa IIE-PCI.

Resultados de la síntesis:

FPGA Memoria Interna (bits) Celdas Lógicas *fmax (MHz) *
EP1K100QC208-1 17568 (35%) 1105 (22%) 35.21

La asignación de pines utilizada es la incluida en el manual de usuario del core PCITWBM.

Obs: Para realizar las simulaciones de lectura y escritura, previamente deben incluirse los ciclos que inicializan el espacio de configuración del core PCITWBM, cómo lo haría el sistema al arrancar. Es necesario asignar una dirección de comienzo al BAR0 y BAR1, realizando un ciclo PCI de configuración.

9.2.5. Pruebas

Se escribió la memoria con el contenido de un archivo cualquiera y se volvió a leer su valor, comparándolo para verificar que las escrituras y lecturas se estuviesen realizando correctamente.
Para esto se utilizaron los utilitarios woff.pl y roff.pl, junto con el comando de unix cmp -l para realizar la comparación.

Las pruebas se realizaron de igual forma que para la aplicación que usa la WB_RAM.
Se pudo constatar diferencias entre los archivos escritos y los datos leídos. El problema esta en las escrituras a la SDRAM, no en las lecturas, ya los valores leídos son siempre iguales. Las diferencias entre lo escrito y lo leído se presentan en forma de ráfagas.
Esto se atribuye a que el diseño del controlador SDRAM no utiliza salidas y entradas registradas, haciendo que las salidas estén conmutando continuamente.

En la siguiente simulación se puede ver que las direcciones de selección de la columna no están estables en el flanco de reloj.

sdram_error_columna.gif

Para 10 lecturas y escrituras, realizadas con el FPGA de velocidad -1, las estadísticas son las siguientes:

--------- IEEPCI Stats - HZ :  512 - loops_per_jiffy:   778240 -------

--------- W R I T E  --  M E M C O P Y -------------------------------
          |   KB/sec     |     bytes    | microseconds | tsc loops
----------+--------------+--------------+--------------+--------------
TOTAL     |         32236|         20480|           620|        247208
BAR1 TOTAL|         32236|         20480|           620|        247208
BAR2 TOTAL|             0|             0|             0|             1
BAR3 TOTAL|             0|             0|             0|             1
LAST WRITE|         32453|           512|            15|          6139
--------- R E A D  --  M E M C O P Y ---------------------------------
          |   KB/sec     |     bytes    | microseconds | tsc loops
----------+--------------+--------------+--------------+--------------
TOTAL     |          5566|         25600|          4491|       1789575
BAR1 TOTAL|          5566|         25600|          4491|       1789575
BAR2 TOTAL|             0|             0|             0|             1
BAR3 TOTAL|             0|             0|             0|             1
LAST READ |          5555|           512|            90|         35862

9.3. WB_DAC

9.3.1. Descripción general

Como demostración para la presentación del proyecto, y como prueba de interconexión de múltiples bloques Wishbone desarrollados por diferentes personas, se realizó un reproductor de archivos de audio.

bloques_wbdac.jpg

La aplicación está compuesta por:

9.3.2. Descripción funcional

La aplicación usa una instancia del core PCITWBM para 3 BARs, BAR0 para los registros de traslación de direcciones, BAR1 para los registros de control y BAR2 para la memoria SDRAM, donde se escriben las muestras de audio a ser reproducidas por el DAC.
La memoria SDRAM tiene una capacidad de 16MBytes.

La aplicación puede estar en tres posibles estados, reproduciendo, en pausa o detenida.
Esto se controla mediante los dos bits menos significativos del registro de control ubicado en la dirección 0 de BAR1.
Si bit[0]=0, la aplicación está en el estado detenida. Pueden escribirse y leerse datos a la memoria.
Si bit[1:0]=01, la aplicación reproduce el contenido de la memoria. La memoria solo puede ser accedida por WB_DAC. Para volver a utilizar la memoria desde el PCI, debe pasarse al estado detenida.
Si bit[1:0]=11, la aplicación esta en estado de pausa. Cuando se vuelve al estado de reproducción se continua desde la última dirección de memoria reproducida.

Se utiliza el codec de la placa de expansión Xsten Board V1.3 de XESS.

9.3.3. Archivos requeridos

9.3.3.1. pcitwbm

GENERIC MAP(vendor_id    =>  X"1172",
               device_id      =>  X"ABBE",
               subsystem_id   =>  X"10E9", 
               subsystem_vid  =>  X"10E9",
               NUMBER_OF_BARS => 3,  
               BAR_0_SIZE     => 64,
               BAR_0_LOW_NIBBLE => 0,
               BAR_1_SIZE     => 64, -- mapero registro
               BAR_1_LOW_NIBBLE => 0,
               BAR_2_SIZE     => 16777216, -- mapero SDRAM
               BAR_2_LOW_NIBBLE => 0,
               FIFO_NUMWORDS  => 14,
               LAT_TIMER_INITIAL_VALUE => 7)

9.3.3.2. wb_register

El interfaz del registro es:

COMPONENT wb_register_interface IS
   GENERIC (data_width: POSITIVE);
   PORT(
      --WB signals
        RST_I      : IN   STD_LOGIC;
      CLK_I      : IN   STD_LOGIC;
      DAT_I    : IN   STD_LOGIC_VECTOR(data_width-1 downto 0);
      DAT_O    : OUT   STD_LOGIC_VECTOR(data_width-1 downto 0);
      ACK_O      : OUT   STD_LOGIC;
      CYC_I      : IN   STD_LOGIC;
      STB_I      : IN   STD_LOGIC;
      --register output signals
      Q        : OUT   STD_LOGIC_VECTOR(data_width-1 downto 0)
      );
END component;

Se utiliza con un ancho de 32 bits, data_width=32.

9.3.3.3. wb_dac

El codec de la placa Xstend se controla con el bloque WB_DAC. Actúa como master Wishbone, leyendo datos de la memoria SDRAM y enviándolos al codec.

El interfaz del módulo es:

component wb_dac_interface IS
      generic
      (
         XSTEND_V1_2  : boolean  := false; -- XSTEND board model
         DAC_WIDTH: positive := 20;
         CLK_DIV_WIDTH : positive := 1
      );
      PORT(
      --WB signals
      RST_I    : IN  STD_LOGIC;
      CLK_I    : IN  STD_LOGIC;
      DAT_I    : IN  STD_LOGIC_VECTOR(DAC_WIDTH-1 downto 0); 
      ACK_I    : IN  STD_LOGIC;
      CYC_O    : OUT STD_LOGIC;
      RTY_I    : IN  STD_LOGIC; 
      SEL_O    : OUT STD_LOGIC_VECTOR(3 downto 0);
      STB_O    : OUT STD_LOGIC;
      WE_O     : OUT STD_LOGIC;
      CTI_O    : OUT STD_LOGIC_VECTOR(2 downto 0); 
      --codec_signals
      mclk: out std_logic;
      lrck: out std_logic;
      sclk: out std_logic;
      sdout: in std_logic;
      sdin: out std_logic
      );
   END component;

9.3.4. Síntesis

Utilizando el Synplify PRO 7.0.1, se creó un archivo de tipo EDIF a partir de la descripción VHDL. Luego, utilizando el MAX+Plus II se sintetizó para el FPGA de la placa IIE-PCI.

Resultados de la síntesis:

FPGA Memoria Interna (bits) Celdas Lógicas fmax (MHz)
EP1K100QC208-1 1216 (2%) 1772 (35%) 34.48

9.3.5. Pruebas

La frecuencia de reproducción de muestras del codec es:
 fs = \frac{CLK\_I}{512 \times 2^{CLK\_DIV\_WID} }

Debido a la limitación de no poder utilizar dos fuentes de reloj simultáneas en la placa, la frecuencia fs más cercana al estándar de 44.1KHz utilizado por audio fue de 32.226KHz.Con un programa de edición de archivos WAV, se generó un archivo de audio remuestreado a esta frecuencia. Los primeros 4096 bytes de los archivos WAV forman parte del cabezal y no contienen información de audio. En caso de ser un archivo WAV de 16 bits estéreo, se alternan las muestras izquierda y derecha, que es la misma secuencia utilizada por el codec, por lo que puede ser cargado directamente en la memoria con el siguiente comando:

./roff.pl -o 4096 -c 16777216 archivodeaudio.wav | ./woff -c 16777216 /dev/rw_bar2

Para iniciar, pausar y detener la reproducción se utilizan los siguientes comandos:

echo -n 01 > ./woff.pl -x /dev/rw_bar1
echo -n 03 > ./woff.pl -x /dev/rw_bar1
echo -n 00 > ./woff.pl -x /dev/rw_bar1