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