手上有一块sram需要验证下功能是否正常,我门通过fpga来进行读写测试。
1.首先看下芯片手册,我们重点关注时序部分
总结下,就是读写时间不能小于10nS,也就是最高频率100M,所以我们程序设计按100M时钟速率进行设计。注意,读写时,控制信号按下表进行设计。
2.我们大概画下时序图,整理下思路。我们使用timegen软件。
设计一个循环计数器,在999时刻写入一个数,在1999时刻读出来,在2999时刻进行对比,如果写入值和读出值一样,则led灯灭,否则led灯亮。
我们按照时序设计进行代码编写如下:
module TQSR8M16SN(
// intput
input clk_50,
input rst_n,
// output
output[18: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
);parameter IDLE =4'd0;
parameter WDATA =4'd1;
parameter RDATA =4'd2;reg [03:00] state_c;
reg [03:00] state_n;
wire idle2wd_start;
wire idle2rd_start;reg[15:0] wr_data;
reg[15:0] rd_data;
reg[18:0] addr_r;
wire sram_wr_req;
wire sram_rd_req;
reg led_r;
wire clk_100;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 availablepll pll_inst (.areset ( !rst_n ),.inclk0 ( clk_50 ),.c0 ( clk_100 ));reg[11:0] delay;
always@(posedge clk_100 or negedge rst_n)if(!rst_n)delay <= 12'd0;elsedelay <= delay+1'b1;always@(posedge clk_100 or negedge rst_n)if(!rst_n)wr_data <= 12'b0;else if(delay == 12'd2999)wr_data <= wr_data+1'b1;always@(posedge clk_100 or negedge rst_n)if(!rst_n)addr_r <= 19'b0;else if(delay == 12'd2999)addr_r <= addr_r+1'b1;
assign sram_addr =addr_r; always@(posedge clk_100 or negedge rst_n)if(!rst_n)led_r <= 1'b0;else if(delay == 12'd2999)beginif(wr_data == rd_data)led_r <= 1'b0;elseled_r <= 1'b1;endassign led = led_r; assign sram_wr_req = (delay == 12'd999);
assign sram_rd_req = (delay == 12'd1999); //将读写分为三个状态,idle 写和读 always@(posedge clk_100 or negedge rst_n)if(!rst_n)state_c <= IDLE;elsestate_c <=state_n;always@(*)begincase(state_c)IDLE: beginif(idle2wd_start)state_n = WDATA;else if(idle2rd_start)state_n = RDATA;elsestate_n = state_c;endWDATA: beginstate_n = IDLE; end RDATA: beginstate_n = IDLE;end default:beginstate_n = IDLE;endendcaseend
//三段设置转移条件 assign idle2wd_start = (state_c == IDLE) && sram_wr_req; assign idle2rd_start = (state_c == IDLE) && sram_rd_req; //四段设计输出信号 // 锁存数据
reg sdlink; //SRAM地址总线控制信号
always@(posedge clk_100 or negedge rst_n)if(!rst_n)rd_data <= 16'b0;else if(state_c == RDATA)rd_data <= sram_data;always@(posedge clk_100 or negedge rst_n)if(!rst_n)sdlink <= 1'b0;else if(state_c == IDLE)if(sram_wr_req)sdlink <= 1'b1;else sdlink <= 1'b0;elsesdlink <= 1'b0;assign sram_data = sdlink ? wr_data:16'hzzzz;
assign sram_wr_n = ~sdlink; endmodule
时序图中读写时间都为一个时钟周期也就是10NS,我们使用芯片的极限速率。
3.modelsim中验证下程序波形和我们预先设计的是否一致。
我们可以看到,在计数器delay分别计数到999 1999和2999时刻进行了写入,读出和比较。
4.我们进行上板测试看下
可以看到,写入数据和读出数据一致,并且led一直为低。这里就对sram进行了验证。