Quartus 平台 FPGA 片内 RAM 使用
本文将以 Quartus 自带的 RAM:2-PORT 为例,介绍 EP4CE6E22C8 On Chip Memory 的使用
一、在 IP Catalog 搜索 RAM
位于 On Chip Memory 下有两个 RAM IP 核
分别是单端口 RAM 和双端口 RAM:
单端口RAM只有一组地址线,这组地址线控制着写数据端口和读数据端口,
而双端口RAM具有两组地址线,这两组地址线分别控制着写数据端口和读数据端口,
双端口 RAM 可以帮助我们更容易地实现的同时读写和双缓存(个人暂时的理解)
这里双击打开 RAM:2-PORT
二、配置
(1)设置双地址线
(2)根据需求设置 memory 大小以及数据总线宽度
(3)时钟线的分配
将输入输出 clock 给入不同的时钟,可以实现写入读取速度不对等的应用(个人暂时的理解)
(4)时钟使能、异步清除功能的开关
(5)对相同地址同时读写时,数据输出的状态
(6)RAM 内容初始化
(7)Finish 生成模块文章来源:https://www.toymoban.com/news/detail-435469.html
三、读写测试 逻辑实现
(1)端口 a 作为写端口,端口 b 作为读端口
(2)一个时钟周期可以完成一次读操作或者写操作
下面代码实现的是,周期性的对同一地址写入同上一个数据 + 1 的值,然后周期性的读出该地址的数据,串口周期性的发送该数据:文章来源地址https://www.toymoban.com/news/detail-435469.html
module FPGA_RAM (
input clk,
input rst_n,
input uart_rx,
output uart_tx
);
reg uart_send_valid;
wire uart_send_ready;
reg [31:0] counter = 32'd0;
parameter state_wait = 4'd0;
parameter state_send = 4'd1;
reg [3:0] state = state_wait;
reg [7:0] data_len = 8'd0;
always@(posedge clk_200M or negedge rst_n) begin
if(!rst_n) begin
uart_send_valid <= 0;
counter <= 32'd0;
state <= state_wait;
data_len <= 8'd0;
end
else begin
case (state)
state_wait: begin
counter <= counter + 32'd1;
if(counter >= 32'd4999999) begin
counter <= 32'd0;
state <= state_send;
end
end
state_send: begin
if(uart_send_ready && data_len <= 8'd0) begin
uart_send_valid <= 1;
data_len <= data_len + 8'd1;
end
else begin
uart_send_valid <= 0;
data_len <= 8'd0;
state <= state_wait;
end
end
endcase
end
end
uart uart0 (
.clk_clk (clk_200M), // clk.clk
.reset_reset_n (rst_n), // reset.reset_n
// .rs232_0_from_uart_ready (<connected-to-rs232_0_from_uart_ready>), // rs232_0_avalon_data_receive_source.ready
// .rs232_0_from_uart_data (<connected-to-rs232_0_from_uart_data>), // .data
// .rs232_0_from_uart_error (<connected-to-rs232_0_from_uart_error>), // .error
// .rs232_0_from_uart_valid (<connected-to-rs232_0_from_uart_valid>), // .valid
.rs232_0_to_uart_data (data_read), // rs232_0_avalon_data_transmit_sink.data
// .rs232_0_to_uart_error (<connected-to-rs232_0_to_uart_error>), // .error
.rs232_0_to_uart_valid (uart_send_valid), // .valid
.rs232_0_to_uart_ready (uart_send_ready), // .ready
.rs232_0_UART_RXD (uart_rx), // rs232_0_external_interface.RXD
.rs232_0_UART_TXD (uart_tx) // .TXD
);
reg [7:0] data_write = 8'd00;
reg [7:0] address_write = 8'h00;
reg write_en = 0;
wire [7:0] data_read;
reg [7:0] address_read = 8'h00;
reg read_en = 0;
reg [31:0] counter_ram = 32'd0;
parameter state_ram_wait = 4'd0;
parameter state_ram_write = 4'd1;
parameter state_ram_wait_read = 4'd2;
parameter state_ram_read = 4'd3;
reg [3:0] state_ram = state_ram_wait;
reg [7:0] state_ram_delay = 8'd0;
parameter delay = 8'd0;
always@(posedge clk_200M or negedge rst_n) begin
if(!rst_n) begin
data_write <= 8'd0;
write_en <= 0;
read_en <= 0;
counter_ram <= 32'd0;
state_ram <= state_ram_wait;
end
else begin
case (state_ram)
state_ram_wait: begin
counter_ram <= counter_ram + 32'd1;
if(counter_ram >= 32'd49999999) begin
counter_ram <= 32'd0;
state_ram <= state_ram_write;
end
end
state_ram_write: begin
if(write_en) begin
write_en <= 0;
state_ram <= state_ram_wait_read;
data_write <= data_write + 8'd1;
end
else begin
write_en <= 1;
end
end
state_ram_wait_read: begin
counter_ram <= counter_ram + 32'd1;
if(counter_ram >= 32'd49999999) begin
counter_ram <= 32'd0;
state_ram <= state_ram_read;
end
end
state_ram_read: begin
if(read_en) begin
read_en <= 0;
state_ram <= state_ram_wait;
end
else begin
read_en <= 1;
end
end
endcase
end
end
ram ram0 (
.data (data_write),
.wraddress (address_write),
.wren (write_en),
.rdaddress (address_read),
.rden (read_en),
.clock (clk_200M),
.q (data_read)
);
wire clk_200M;
pll pll0 (
.inclk0 (clk),
.c0 (clk_200M)
);
endmodule
到了这里,关于Quartus 平台 FPGA 片内 RAM 使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!