[笔记] SRAM Controller

Abstract

  本实验实现了对SRAM每一个地址进行遍历读/写操作,然后对比读写前后的数据是否一致,最后通过一个LED灯的亮灭进行指示;

Introduction

  DE2-115上用的SRAM是IS61WV102416BL(1Mx16 High-Speed Asynchronous CMOS Static RAM With 3.3V Supply) 

  

  

  

  我们把SRAM_CE,SRAM_OE,SRAM_UB,SRAM_LB置0,这样写操作时,只需送数据和地址,同时把SRAM_WE拉低,然后延时Twc时间在把SRAM_WE拉高,这时就把数据写入相应的地址;读数据时,只需把需要读出的地址放到SRAM的地址总线上,然后延迟Taa时间后就可以读出数据了.

  SRAM写时序:

  

  SRAM读时序:

  

sram_controller.v

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
`timescale 1ns/1ps
// ********************************************************************* //
// Filename: sram_controller.v                                           //
// Projects: sram_controller on DE2-115                                  //
//           without  external clock                                     //
// Function: check the wirte/read data by led,                           //
//           right:LED=1 Wrong:LED=0                                     //           
// Author  : Liu Qiang                                                   //
// Date    : 2011-11-21                                                  //
// Version : 1.0                                                         //
// Company :                                                             //
// ********************************************************************* //
 
module sram_controller(
//  intput
input clk_50,
input rst_n,
//  output
output[19:0] sram_addr,
output sram_wr_n,
output sram_ce_n,
output sram_oe_n,
output sram_ub_n,
output sram_lb_n,
output led,
//  inout
inout[15:0] sram_data
);
//
assign sram_ce_n = 1'b0;    //sram chip select always enable
assign sram_oe_n = 1'b0;    //sram output always enable
assign sram_ub_n = 1'b0;    //upper byte always available
assign sram_lb_n = 1'b0;    //lower byte always available
//
reg[25:0] delay;        //延时计数器,周期约为1.34s
always@(posedge clk_50 or negedge rst_n)
    if(!rst_n)
        delay <= 26'd0;
    else
        delay <= delay+1'b1;
//
reg[15:0] wr_data;
reg[15:0] rd_data;
reg[19:0] addr_r;
wire sram_wr_req;
wire sram_rd_req;
reg led_r;
 
assign sram_wr_req = (delay == 26'd9999);
assign sram_rd_req = (delay == 26'd19999);
 
always@(posedge clk_50 or negedge rst_n)
    if(!rst_n)
        wr_data <= 16'b0;
    else if(delay == 26'd29999)
        wr_data <= wr_data+1'b1;
         
always@(posedge clk_50 or negedge rst_n)
    if(!rst_n)
        addr_r <= 20'b0;
    else if(delay == 26'd29999)
        addr_r <= addr_r+1'b1;
     
always@(posedge clk_50 or negedge rst_n)
        if(!rst_n)
            led_r <= 1'b0;
        else if(delay == 26'd29999)
            begin
                if(wr_data == rd_data)
                    led_r <= 1'b1;
                else
                    led_r <= 1'b0;
            end
assign led = led_r;
//
`define DELAY_80NS  (cnt == 3'd7)   //80nss取决于Twc的值, cnt=7约140ns;
 
reg[3:0] cstate, nstate;
parameter   IDEL = 4'd0,
            WRT0 = 4'd1,
            WRT1 = 4'd2,
            REA0 = 4'd3,
            REA1 = 4'd4;
             
reg[2:0] cnt;
always@(posedge clk_50 or negedge rst_n)
    if(!rst_n)
        cnt <= 3'b0;
    else if(cstate == IDEL)
        cnt <= 3'b0;
    else
        cnt <= cnt+1'b1;
//  两段式状态机写法,时序逻辑      
always@(posedge clk_50 or negedge rst_n)
    if(!rst_n)
        cstate <= IDEL;
    else
        cstate <= nstate;
//  两段式状态机写法,组合逻辑          
always@(posedge clk_50 or negedge rst_n)
    case(cstate)
        IDEL:   if(sram_wr_req)
                    nstate <= WRT0;
                else if(sram_rd_req)
                    nstate <= REA0;
                else
                    nstate <= IDEL;
        WRT0:   if(`DELAY_80NS)
                    nstate <= WRT1;
                else
                    nstate <= WRT0;
        WRT1:   nstate <= IDEL;
        REA0:   if(`DELAY_80NS)
                    nstate <= REA1;
                else
                    nstate <= REA0;
        REA1:   nstate <= IDEL;
        default:nstate <= IDEL;
    endcase
     
assign sram_addr =addr_r;
//  锁存数据
reg sdlink;     //SRAM地址总线控制信号
always@(posedge clk_50 or negedge rst_n)
    if(!rst_n)
        rd_data <= 16'b0;
    else if(cstate == REA1)
        rd_data <= sram_data;
         
always@(posedge clk_50 or negedge rst_n)
    if(!rst_n)
        sdlink <= 1'b0;
    else
        case(cstate)
            IDEL:   if(sram_wr_req)
                        sdlink <= 1'b1;
                    else if(sram_rd_req)
                        sdlink <= 1'b0;
                    else
                        sdlink <= 1'b0;
            WRT0:   sdlink <= 1'b1;
            default:sdlink <= 1'b0;
        endcase
     
assign sram_data = sdlink ? wr_data:16'hzzzz;
assign sram_wr_n = ~sdlink;
 
endmodule

 

posted on   LiangXuan  阅读(4015)  评论(2编辑  收藏  举报

编辑推荐:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
阅读排行:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
< 2011年11月 >
30 31 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 1 2 3
4 5 6 7 8 9 10

导航

统计

点击右上角即可分享
微信分享提示