FPGA访问SRAM

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  :                                                   //
// Date    :                                                   //
// 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

猜你喜欢

转载自blog.csdn.net/fzhykx/article/details/80774891