Directorio de artículos
Prefacio
Esta sección describe la simulación y prueba de la RAM en chip FPGA. También sabemos que la RAM es una memoria de acceso aleatorio. Como sugiere el nombre, es un módulo que almacena datos. Cuando se trata de aleatoriedad, significa que podemos acceder arbitrariamente algunos espacios de direcciones en él.los datos dentro.
Xilinx nos ha proporcionado el núcleo IP de RAM en Vivado. Solo necesitamos crear una instancia de una RAM a través del núcleo IP y escribir y leer los datos almacenados en la RAM de acuerdo con el tiempo de lectura y escritura de la RAM. En el experimento, a través del analizador lógico en línea ila integrado por VIVADO, podemos observar el tiempo de lectura y escritura de la RAM y los datos leídos de la RAM.
1. Crear y configurar proyectos
1. Crea un proyecto
Crea un nuevo proyecto ram_test
2. Agregue el núcleo IP de RAM
①. Haga clic en el catálogo de IP en la imagen a continuación , busque ram en la interfaz que aparece a la derecha, busque Block Memory Generator y haga doble clic para abrirlo.
② Configure la barra de opciones Básica como se muestra a continuación.
- Tipo de interfaz : Tipo de interfaz, seleccione Nativo
- Generalmente hay dos formas de implementar una memoria en la FPGA de XILINX: la primera es diseñarla usted mismo utilizando los recursos lógicos de la FPGA; la segunda es utilizar el generador de memoria de bloque (BMG) dedicado de XILINX . Para los formularios de recursos BRAM, XILINX proporciona dos tipos de interfaz: nativa y AXI4. Las principales características de estos dos núcleos son las siguientes.
- Generalmente hay dos formas de implementar una memoria en la FPGA de XILINX: la primera es diseñarla usted mismo utilizando los recursos lógicos de la FPGA; la segunda es utilizar el generador de memoria de bloque (BMG) dedicado de XILINX . Para los formularios de recursos BRAM, XILINX proporciona dos tipos de interfaz: nativa y AXI4. Las principales características de estos dos núcleos son las siguientes.
- Tipo de memoria: tipo de memoria, seleccione RAM de puerto dual simple
- Hay cinco tipos de memoria del puerto Nativo. Las diferencias son las siguientes:
- El tiempo de escritura de la RAM simple de doble puerto es el siguiente
- Cuando la habilitación de escritura es válida (nivel alto), los datos especificados se escriben en la dirección especificada en el flanco ascendente del reloj.
- El tiempo de lectura de la RAM simple de doble puerto es el siguiente
- Hay un cierto retraso en la lectura. Si recopilamos estos datos de salida válidos en el mismo reloj, necesitamos recopilar sus datos válidos en el siguiente ciclo.
- Hay un cierto retraso en la lectura. Si recopilamos estos datos de salida válidos en el mismo reloj, necesitamos recopilar sus datos válidos en el siguiente ciclo.
③ Configure la barra de opciones de Puerto A como se muestra a continuación.
按照这样设置,也就是说可以存储 512 个 16 位数据
- Ancho del puerto A (ancho de datos): el ancho del puerto A, aquí configuramos 16 bits de ancho
- Profundidad del puerto A (cuántos datos se pueden almacenar en la RAM): la profundidad del puerto A, la configuramos aquí en 512
- Habilitar tipo de puerto: Habilitar siempre, manténgalo habilitado para que no necesitemos controlarlo
④ Configure la barra de opciones de Puerto B como se muestra a continuación.
- Ancho del puerto B (ancho de datos): el ancho del puerto B, aquí configuramos 16 bits de ancho
- Habilitar tipo de puerto: Siempre habilitado (la habilitación del puerto B permanece activada)
- Registro de salida primitivo: desmarque, su función es agregar un registro a los datos de salida, lo que puede mejorar efectivamente el tiempo, pero los datos leídos se retrasarán dos ciclos con respecto a la dirección . En muchos casos, esta función no está habilitada y los datos se mantienen un ciclo detrás de la dirección.
Para obtener más información sobre otras configuraciones, consulte el documento oficial de XILINX " Block Memory Generator v8.4 LogiCORE IP Product Guide "
⑤ Otras opciones, simplemente mantenga la configuración predeterminada.
- Cargar archivo de inicio nos permite inicializar algunos archivos y colocarlos en la RAM, lo que significa que después de encender la FPGA, cargará los datos que haya guardado de antemano en la RAM.
⑥. Haga clic en Aceptar, luego haga clic en Generar para generar la IP de RAM
3. Agregue el núcleo IP de ILA
①. Haga clic en la barra PROJECT MANAGER a la izquierda -> Catálogo IP o Ventana -> Catálogo IP debajo de la barra de menú, luego busque ILA en la ventana Catálogo IP que aparece a la derecha, haga doble clic para seleccionar ILA en Depurar para Configuración de IP. Los pasos se muestran en la siguiente figura
②, la opción general agrega dos sondas para recopilar la dirección y los datos que leemos. Configuramos la longitud de los datos muestreados más grande, como se muestra en la siguiente figura
③. PROBE0 en Probe_Ports ( 0...7) se usa para recopilar la dirección de 9 bits y se usa PROBE1. Recopile datos de 16 bits, como se muestra en la siguiente figura
④, haga clic en Aceptar y luego haga clic en Generar para generar IP ILA.
2. Programación
Antes de escribir el programa, primero introduzcamos qué señales involucramos.
Las descripciones de los puertos del módulo RAM de puerto dual simple son las siguientes:
Nombre de la señal | dirección | ilustrar |
---|---|---|
clka | en | Entrada de reloj del puerto A |
nosotros | en | Puerto A habilitado |
addra | en | Entrada de dirección del puerto A |
innoble | en | Entrada de datos del puerto A |
clkb | en | Entrada de reloj del puerto B |
dirección | en | Entrada de dirección del puerto B |
duda | afuera | Salida de datos del puerto B |
La escritura y lectura de datos de la RAM se realizan en el flanco ascendente del reloj. Al escribir datos en el puerto A, la señal wea debe establecerse en alto y la dirección y los datos a escribir deben proporcionarse al mismo tiempo. La siguiente figura muestra el diagrama de tiempos de escritura de entrada en la RAM.
El puerto B no puede escribir datos y solo puede leer datos de la RAM. Siempre que se proporcione la dirección, generalmente se pueden recopilar datos válidos en el siguiente ciclo.
1. Cree un nuevo programa de prueba
Cree un nuevo archivo fuente ram_test.v y copie los siguientes bloques de programa en
ram_test.v
`timescale 1ns / 1ps
module ram_test(
input clk, // 50 MHz 时钟
input rst_n // 复位信号,低电平有效
);
reg [8 : 0] w_addr; // RAM PORTA 写地址
reg [15 : 0] w_data; // RAM PORTA 写数据
reg wea; // RAM PORTA 使能
reg [8 : 0] r_addr; // RAM PORTB 读地址
wire [15 : 0] r_data; // RAM PORTB 读数据
// ************************************************************************
// ** main
// ************************************************************************
// 产生RAM PORTB读地址,读的地址 + 1,模拟写的地址滞后一个周期
always @ (posedge clk or negedge rst_n) begin
if( !rst_n )
r_addr <= 9'd0;
else if( |w_addr ) // w_addr 位或,不等于 0
r_addr <= r_addr + 1'b1;
else
r_addr <= 9'd0;
end
// 产生RAM PORTA写使能信号
always @ (posedge clk or negedge rst_n) begin
if( !rst_n )
wea <= 1'b0;
else begin
if( &w_addr ) // w_addr 的 bit 位全为1,共写 512 个数据,写入完成
wea <= 1'b0;
else
wea <= 1'b1; // ram 写使能
end
end
// 产生RAM PORTA写入的地址及数据
always @ (posedge clk or negedge rst_n) begin
if( !rst_n ) begin
w_addr <= 9'd0;
w_data <= 16'd1;
end
else begin
if( wea ) begin // ram 写使能有效
if( &w_addr ) begin // w_addr 的 bit 位全为 1,共写入 512 个数据,写入完成
w_addr <= w_addr; // 将地址和数据的值保持住,只写一次 RAM
w_data <= w_data;
end
else begin
w_addr <= w_addr + 1'b1;
w_data <= w_data + 1'b1;
end
end
end
end
// 实例化 RAM
ram_ip ram_ip_instance (
.clka(clk ), // input wire clka
.wea(wea ), // input wire [0 : 0] wea
.addra(w_addr ), // input wire [8 : 0] addra
.dina(w_data ), // input wire [15 : 0] dina
.clkb(clk ), // input wire clkb
.addrb(r_addr ), // input wire [8 : 0] addrb
.doutb(r_data ) // output wire [15 : 0] doutb
);
// 实例化 ila 逻辑分析仪
ila_0 ila_0_instance (
.clk(clk), // input wire clk
.probe0(r_addr), // input wire [8:0] probe0
.probe1(r_data) // input wire [15:0] probe1
);
endmodule
2. Cree un nuevo archivo de simulación.
Cree un nuevo archivo de simulación vtf_ram_tb.v y copie los siguientes bloques de programa en
vtf_ram_tb.v
`timescale 1ns / 1ps
module vtf_ram_tb;
// Inputs
reg clk;
reg rst_n;
// Instantiate the Unit Under Test (UUT)
ram_test uut (
.clk (clk),
.rst_n (rst_n)
);
initial
begin
// Initialize Inputs
clk = 0;
rst_n = 0;
// Wait 100ns for global reset to finish
#100;
rst_n = 1;
end
always #10 clk = ~clk; // 20ns 一个周期,产生 50MHz 时钟源
endmodule
3. Realizar simulación
①. Haga clic en Ejecutar simulación -> Ejecutar simulación de comportamiento para realizar la simulación
②. Arrastre las señales relevantes en la RAM a la ventana de observación
(clocka y clockb usan el reloj del sistema, por lo que no es necesario arrastrarlas a la ventana de observación aquí)
③. Establezca una ejecución de 200 us. Siguiente
④, analice la forma de onda
Se puede ver que la información de forma de onda inicial es que la dirección de lectura está retrasada con respecto a la dirección de escritura en un ciclo de reloj, y los datos leídos son
la información de forma de onda que está retrasada con respecto al final de la dirección de escritura en un ciclo de reloj.
Aquí vemos estas señales en formato decimal formulario
Puede ver que la última dirección escrita es 511, el contenido escrito es 512, la última dirección leída es 511 y el contenido leído es 512. Puede
encontrar que nuestra escritura solo escribe primero, mientras que la lectura siempre continúa.
4. Descargar a FPGA
1. Restricciones de pines y restricciones de tiempo
rst_n -> T11
clk -> U18
Cree un nuevo archivo de restricción de pin ram.xdc, copie las siguientes declaraciones y guárdelo
set_property PACKAGE_PIN T11 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property PACKAGE_PIN U18 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
create_clock -period 20.000 -name clk -waveform {
0.000 10.000} [get_ports clk]
2. Generar archivo de bits
Haga clic en "Generar Bitstream" para generar directamente el archivo de bits.
3. Descarga el programa
Conecte el JTAG y el cable de alimentación, encienda la placa y descargue el programa.
4. El analizador lógico analiza las formas de onda.
Vea la memoria de lectura y los datos en modo decimal, establezca la condición de activación en "la dirección de lectura es 0", puede ver que los datos leídos en la dirección 0 son 1 y los datos leídos en la dirección 511 son 512. Se puede ver que se cumplan las condiciones para obtener los resultados esperados.
5. Obtenga recursos usted mismo
Experimento de prueba de lectura y escritura de RAM en chip FPGA
Mi qq: 2442391036, ¡bienvenido a comunicarnos!