SRAM(静态随机存储器) 它是一种具有静止存取功能的内存,不需要刷新电路即能保存它内部存储的数据。一种很简单的操作是:将片选信号CE_n和输出使能信号OE_n直接拉低,在读/写SRAM的时候只要对写使能信号WE_n操作就可以了.

   读操作:只需将要读出数据的地址放在地址总线上,拉高WE_n写使能信号,延时一段时间(具体延时多长时间可以看datasheet),就可以读出相应的数据了。

 写操作:送地址和数据,同时拉低WE_n写使能信号,延时一段时间,然后拉高WE_n,这样就可将要写入的数据写到SRAM的相应地址中。

 

 

//程序实现的功能:往SRAM中写一个字节的数据,然后读出这个数据送给四位LED灯; 
module sram
      (
        clk,
        rst_n,
        sram_cs_n,
        sram_we_n,
        sram_oe_n,
        sram_addr,
        sram_data,
        led_out  
      );
      
input       clk;         //系统时钟 50MHZ;
input       rst_n;       //复位信号,低电平有效;
output      sram_cs_n;   //芯片使能信号,低电平有效;
output      sram_we_n;   //写选通信号,低电平有效;
output      sram_oe_n;   //输出使能信号,低电平有效;
output[18:0]sram_addr;   //SRAM地址总线;
inout[7:0] sram_data;    //数据总线;
output[3:0] led_out;     //四位LED灯;


reg[19:0] time_cnt ;
always @ (posedge clk or negedge rst_n)
 begin
       if(!rst_n)
        time_cnt<=20'd0;
       else
        time_cnt<=time_cnt+1'b1;       //延时0.2s;
 end 

assign  sram_cs_n=1'b0;
assign  sram_oe_n=1'b0;

wire wr_req;     //SRAM写请求信号;
wire rd_req;     //SRAM读请求信号;

assign wr_req=(time_cnt==20'd10000);  // 产生写请求信号; 
assign rd_req=(time_cnt==20'd20000);  //产生读求信号;

reg[2:0] cnt;
always @ (posedge clk or negedge rst_n)
  begin
       if(!rst_n)
          cnt<=3'd0;
       else if(cstate==IDLE)
          cnt<=3'd0;
       else   
          cnt<=cnt+1'b1;  
  end
  
`define DELAY_60NS        (cnt==3'd2)

parameter IDLE=4'd0;
parameter WR0=4'd1;
parameter WR1=4'd2;
parameter RD0=4'd3;
parameter RD1=4'd4;

reg[3:0] cstate;
reg[3:0] nstate;
always @ (posedge clk or negedge rst_n)
  begin
      if(!rst_n)
        cstate<=IDLE;
      else 
        cstate<= nstate; 
     
  end

always @ (*)
  begin 
       case(cstate)
          IDLE : if(wr_req) nstate=WR0;       //写数据时:先送地址和数据,同时将sram_we_n拉低,然后延时60ns后,拉高sram_we_n,这样就将数据写到相应的地址里了;
                 else if(rd_req) nstate=RD0;  //读数据时:只要将需要读出的地址放到SRAM的地址总线上,拉高sram_we_n,然后延时60ns时间后就可以读出SRAM中的数据了;
                 else   nstate=IDLE;
          WR0  : if(`DELAY_60NS)  nstate=WR1;
                 else  nstate=WR0;
          WR1  :  nstate=IDLE;
          RD0  :  if(`DELAY_60NS)  nstate=RD1;
                  else  nstate=RD0;
          RD1  :  nstate=IDLE; 
          default : nstate=IDLE;
          endcase            
                          
 end 

reg sd_link ;
always @ (posedge clk or negedge rst_n)
  begin
        if(!rst_n)
          sd_link<=1'b0;
        else
          begin
              case(cstate)
                  IDLE   : if(wr_req) sd_link<=1'b1;
                          else if(rd_req) sd_link<=1'b0;
                          else sd_link<=1'b0;
                  WR0    : sd_link<=1'b1;
                  default: sd_link<=1'b0;
              endcase           
          end  
  end 
  
assign  sram_addr=19'd0;  
assign  sram_data=sd_link ? 8'hFA: 8'hzz;   //当sd_link=1时,将FAH写入SRAM中;
assign  sram_we_n=~sd_link;                

reg [3:0] led_r;
always @ (posedge clk or negedge rst_n)
  begin
      if(!rst_n)
         led_r<=4'b1111;
       else if(cstate==RD1)
         led_r<=sram_data[3:0];      //  读出数据;
  end
  
assign led_out=led_r;
 
endmodule