[笔记] 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

`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
原文地址:https://www.cnblogs.com/spartan/p/2258208.html