prescaler - Mejor manera de codificar una memoria RAM en Verilog
verilog libro pdf (5)
Ambas formas son válidas, según el tipo de canalización que desee. Siempre recomiendo seguir las pautas de codificación de Xilinx RAM: es una buena manera de garantizar que el código se sintetice en las construcciones FGPA adecuadas.
Por ejemplo, su ejemplo 1 se sintetizaría en BRAM de Xilinx (es decir, Ram de bloque dedicado), ya que es una lectura síncrona, y su ejemplo 2 se sintetizaría en Ram distribuido de Xilinx (ya que es lectura asíncrona).
Consulte las pautas de codificación en el documento UG901 de Xilinx (Guía de usuario de Vivado Design Suite), en la sección Técnicas de codificación de RAM HDL. También tiene una buena descripción de la diferencia entre lectura síncrona y lectura asíncrona para RAM.
¿Qué código es mejor para escribir una memoria RAM?
asignando
data_out
dentro del bloquealways
:module memory( output reg [7:0] data_out, input [7:0] address, input [7:0] data_in, input write_enable, input clk ); reg [7:0] memory [0:255]; always @(posedge clk) begin if (write_enable) begin memory[address] <= data_in; end data_out <= memory[address]; end endmodule
asignando
data_out
usando la declaración deassign
:module memory( output [7:0] data_out, input [7:0] address, input [7:0] data_in, input write_enable, input clk ); reg [7:0] memory [0:255]; always @(posedge clk) begin if (write_enable) begin memory[address] <= data_in; end end assign data_out = memory[address]; endmodule
¿Alguna recomendación?
Depende de sus necesidades.
Esto registra su salida de memoria. Si está sintetizando esto en puertas, tendrá 16 flip-flops más que en el caso 2. Eso significa que usa un poco más de área. También significa que su salida tendrá menos retardo de propagación en relación con el reloj que en el caso 2. Además, los datos de salida no estarán disponibles hasta el siguiente ciclo de reloj.
Sus datos de salida estarán disponibles dentro del mismo ciclo de reloj que se escribió, aunque con un retardo de propagación más largo en relación con el reloj.
Debe decidir cuál usar en función de sus requisitos.
Una tercera opción es usar una RAM generada, que es una macro dura. Esto debería tener ventajas de área, potencia y posiblemente de temporización tanto en el caso 1 como en el 2.
En el segundo programa, habría un error de compilación ya que no podemos ''Asignar'' un valor a ''Reg''. Se emitirá un error que dice: '' Registrarse es ilegal en el lado izquierdo de la asignación continua ''
módulo mem_try (clk, // señal de control para hacer RAM sincrónica addr, // dirección desde donde se deben buscar los datos data_in, // datos de entrada rd, wr, // control de escritura de señales a alto, leído a bajo; // rst , // señal de control de entrada // rd_count, // wr_count, data_out // lectura de datos);
parameter addr_length=32,data_width=32,ram_depth= 1 << addr_length;
input [data_width-1:0]data_in;
input clk,rd,wr;
input [addr_length-1:0]addr;
output reg [data_width-1:0]data_out;
reg[data_width-1:0]ram[ram_depth-1:0];//ram variable decalaration
assign write_only =wr&~rd ;
assign read_only =~wr&rd ;
always@(posedge clk) begin
if(write_only) begin
ram[addr]<=data_in;
end
if(read_only) begin
data_out<=ram[addr];
end
end
endmódulo
Escribí este código para el ram 32x32 y esperaba que el ram del bloque se infiera en el diseño. Sin embargo, el vivado lo trata como un ram distribuido.
para agregar a la respuesta de toolic: si utiliza el método de lectura asíncrono (caso 2), no se asignará a un bloque de RAM en un FPGA, ya que los bloques de RAM en todas las arquitecturas principales que conozco tienen una lectura síncrona.