Fue utilizada mayormente para desarrollar el driver y realizar las primeras pruebas del core PCI.
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.
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)
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)
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.
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
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.
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)
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
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.
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.
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
La aplicación está compuesta por:
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.
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)
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.
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;
Resultados de la síntesis:
FPGA | Memoria Interna (bits) | Celdas Lógicas | fmax (MHz) |
---|---|---|---|
EP1K100QC208-1 | 1216 (2%) | 1772 (35%) | 34.48 |
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