附录

使用OpenCores的SDRAM

另外这个方式使用的开源的sdram程序,不是IP核

SDRAM(Synchronous Dynamic Random Access Memory)是同步动态随机访问存储器,同步是指memory工作需要同步时钟,内部命令的发送与数据的传输都以它为基准;动态是指存储阵列需要不断地刷新以保证数据不丢失;随机访问是指数据不是线性依次读写,而是可以自由指定地址进行读/写。

SDRAM的内部有存储单元整列,给出行地址,列地址,就可以选择相应的存储单元,如下图中右侧部分所示。

图上左侧的信号,对应于顶层文件的这些接口,有部分信号芯片手册上未标明如dq。

   output wire          sdr_clk_o,
   output wire          sdr_cs_n_o,
   output wire          sdr_cke_o,
   output wire          sdr_ras_n_o,
   output wire          sdr_cas_n_o,
   output wire          sdr_we_n_o,
   output wire [1:0]    sdr_dqm_o,
   output wire [1:0]    sdr_ba_o,
   output wire [11:0]   sdr_addr_o,
   inout  wire [15:0]   sdr_dq_io,

接口说明如下:

序号 接口名 宽度(bit) 输入/输出 作用
1 ADDR 12 输入 地址线
2 CLK 1 输入 时钟
3 CKE 1 输入 时钟使能
4 RAS 1 输入 行地址选通,低有效
5 CS 1 输入 片选,低有效
6 CAS 1 输入 列地址选通,低有效
7 WE 1 输入 写使能,低有效
8 DQM 2 输入 字节选择和输出使能,低有效
9 DQ 16 双向 数据线
10 BA 2 输入 bank选择

对于SDRAM更深刻的介绍,需要很大的篇幅,由于我们并非需要直接驱动SDRAM,而只需要驱动SDRAM的控制器,所以这里就不再展开,《自己动手写CPU》中关于Flash控制器有更多的描述。这里介绍的目的是,对SDRAM有一个基本的认识即可。

这个SDRAM控制器取自于OpenCores,该SDRAM控制器:

  • 支持SDRAM的数据总线宽度可以为8,16,32
  • 支持4个Bank的SDRAM
  • 自动控制刷新
  • 支持所有标准的SDRAm功能
  • 支持 wishbone B总线

这是一个功能十分完善的控制器,根据说明,在实际使用过程中,无需修改如何源码我们只需配置如下参数就可以用了!

序号 参数名 宽度(bit) 输入/输出 作用
1 cfg_sdr_width 2 输入 SDRAM的数据总线宽度:
00 —— 32位SDRAM
01 —— 16位SDRAM
1x —— 8位SDRAM
2 cfg_sdr_en 1 输入 SDRAM控制器使能信号
3 cfg_sdr_colbits 2 输入 列地址宽度:
00 —— 8bit
01 —— 9bit
10 —— 10bit
11 —— 11bit
4 cfg_sdr_mode_reg 13 输入 模式寄存器
5 cfg_sdr_tras_d 4 输入 tRAS的值,单位是时钟周期
6 cfg_sdr_trp_d 4 输入 tRP的值,单位是时钟周期
7 cfg_sdr_trcd_d 4 输入 tRCD的值,单位是时钟周期
8 cfg_sdr_cas 3 输入 CL地值,单位是时钟周期
9 cfg_sdr_trcar_d 4 双向 tRC的值,单位是时钟周期
10 cfg_sdr_twr_d 4 输入 tWR的值,单位是时钟周期
11 cfg_sdr_rfsh 12 输入 自动刷新间隔,单位是时钟周期
12 cfg_sdr_rfmax 3 输入 每次刷新的最大行数
13 cfg_req_depth 2 输入 请求缓存的数量

SDRAM参数确定

那么接下来就是通过查阅手册来确定这些参数了:

前三个比较好确定,宽度是16,所以值是 2'b11; 使能自然是1'b1;列地址宽度是8,所以值是2'b00。

关于模式寄存器的结构如下,或者查阅芯片手册:

模式寄存器配置为 13'b0_0000_0011_0001,表示CAS延时为3个时钟周期,突发长度为2(一次16bits,两次正好32bits),突发模式是线性。

关于有关时间的参数,见下表,或者查阅芯片手册进行配置。

手册中给出的-5 -6 -7代表了不同频率的设置值,最低的也是133MHz,事实上我在下板的时候用133MHz也会报WNS违约,后来发现降低SDRAM主频也是可以工作的。

参考《自己动手写CPU》cfg_sdr_cas要比模式寄存器中的值大一,故是3'b100。

关于rfsh的配置:芯片45S16400的每个bank有4096行,此处设置每次最大的刷新行数rfmax为4,所以在64ms内要求有 4096/4 = 1024 次刷新。每次刷新的间隔即是(64/1024)ms,SOC使用的时钟频率是30MHz,计算 30 1e6 64 1e-3 / 1024 得到1875,故设置为对应的二进制 12'b011101010011。

cfg_req_depth尚不清楚有何影响,采取和《自己动手写CPU》相同设置未发现错误。

最后的参数如下:

    .cfg_req_depth(2'b11),
    .cfg_sdr_en(1'b1),
    .cfg_sdr_mode_reg(13'b0000000110001),
    .cfg_sdr_tras_d(4'b1000),
    .cfg_sdr_trp_d(4'b0010),
    .cfg_sdr_trcd_d(4'b0010),
    .cfg_sdr_cas(3'b100),
    .cfg_sdr_trcar_d(4'b1010),
    .cfg_sdr_twr_d(4'b0010),
    .cfg_sdr_rfsh(12'b011101010011),
    .cfg_sdr_rfmax(3'b100),
    .cfg_sdr_width(2'b01),
    .cfg_colbits(2'b00)

results matching ""

    No results matching ""

    results matching ""

      No results matching ""