前面一文中,我们已经对SDRAM的上电初始化、自动刷新以及突发读写进行了学习。
本文跟着大佬学习SDRAM中的仲裁模块。
仲裁机制
仲裁(arbit):在FPGA中,当多个source源同时发出请求,容易导致操作冲突,因此我我们需要根据相应的优先级来响应哪一个source,这个过程就叫仲裁。
对于SDRAM控制器来说,其中包含上电初始化、自动刷新以及突发读写模块,由于SDRAM在一个clk中只执行一个操作,因此当4个模块中的两个及以上模块同时发出操作命令的时候,就会出现操作冲突,从而导致SDRAM工作出错,因此这里就需要引入仲裁机制,仲裁机制根据优先级对4个模块发出来的操作请求统一管理。
四个模块的仲裁总框图如下:

仲裁模块的输入信号
仲裁模块的输入信号主要就是4个模块的输出信号。
其中四个小模块的使能信号是由仲裁模块发出的,初始化模块由于上电后自动工作,因此仲裁模块实质是控制3个模块。
可看到仲裁模块发出刷新使能、读写使能信号,根据这三个使能信号,来控制小模块的独立工作,避免操作冲突。

除了四个模块的输出信号作为仲裁模块的输入信号,以及三个使能信号作为仲裁模块的输出之外,仲裁模块的端口信号中还包含时钟复位信号以及SDRAM芯片物理接口:
module sdram_arbit
(
input wire arbit_clk , //系统时钟
input wire arbit_rst_n , //复位信号
//sdram_init
input wire [3:0] init_cmd , //初始化阶段命令
input wire init_end , //初始化结束标志
input wire [1:0] init_bank , //初始化阶段Bank地址
input wire [12:0] init_addr , //初始化阶段数据地址
//sdram_auto_ref
input wire atref_req , //自刷新请求
input wire atref_end , //自刷新结束
input wire [3:0] atref_cmd , //自刷新阶段命令
input wire [1:0] atref_bank , //自动刷新阶段Bank地址
input wire [12:0] atref_addr , //自刷新阶段数据地址
//sdram_write
input wire wr_req , //写数据请求
input wire [1:0] wr_bank , //写阶段Bank地址
input wire wr_end , //一次写结束信号
input wire [3:0] wr_cmd , //写阶段命令
input wire [12:0] wr_addr , //写阶段数据地址
input wire wr_sdram_en , //写数据有效
input wire [15:0] wr_sdram_data , //要写入sdram的数据
//sdram_read
input wire rd_req , //读数据请求
input wire rd_end , //一次读结束
input wire [3:0] rd_cmd , //读阶段命令
input wire [12:0] rd_addr , //读阶段数据地址
input wire [1:0] rd_bank , //读阶段Bank地址
//输出控制逻辑
output reg atref_en , //自刷新使能
output reg wr_en , //写数据使能
output reg rd_en , //读数据使能
//sdram接口
output wire sdram_cke , //SDRAM时钟使能
output wire sdram_cs_n , //SDRAM片选信号
output wire sdram_ras_n , //SDRAM行地址选通
output wire sdram_cas_n , //SDRAM列地址选通
output wire sdram_we_n , //SDRAM写使能
output reg [1:0] sdram_bank , //SDRAM Bank地址
output reg [12:0] sdram_addr , //SDRAM地址总线
inout wire [15:0] sdram_dq //SDRAM数据总线
);
最终给出仲裁模块的输入输出端口:

分析仲裁模块的工作状态
首先我们确定优先级:
上电初始化——自动刷新——写操作——读操作(先写在读,防止数据被覆盖)
根据上面的分析,得到如下的状态图:
仲裁模块:负责发出自动刷新、读写模块的使能信号 (注意优先级)
四个模块:负责发出相应操作的请求信号
这里的状态不复杂且大佬博文中也有讲解,很清晰,不再赘述

仲裁模块的verilog实现
module sdram_arbit
(
input wire arbit_clk , //系统时钟
input wire arbit_rst_n , //复位信号
//sdram_init
input wire [3:0] init_cmd , //初始化阶段命令
input wire init_end , //初始化结束标志
input wire [1:0] init_bank , //初始化阶段Bank地址
input wire [12:0] init_addr , //初始化阶段数据地址
//sdram_auto_ref
input wire atref_req , //自刷新请求
input wire atref_end , //自刷新

本文详细介绍了SDRAM控制器中仲裁模块的工作原理和实现。仲裁模块用于解决上电初始化、自动刷新、写操作和读操作之间的冲突,根据优先级进行调度。状态机分为初始化、自动刷新、写和读四种状态,并通过使能信号控制各模块的操作。Verilog代码实现了仲裁逻辑,包括状态转换和输出控制,确保SDRAM操作的正确顺序。最后,展示了顶层模块如何实例化仲裁和其他模块。

682

被折叠的 条评论
为什么被折叠?



