在特权同学《
FPGA/CPLD边学边练》一书中的SRAM读写测试实验,程序如下:module sram_test( clk,rst_n,led,
sram_addr,sram_wr_n,sram_data
);
input clk; // 50MHz
input rst_n; //低电平复位
output led; // LED1
// CPLD与SRAM外部接口
output[14:0] sram_addr; // SRAM地址总线
output sram_wr_n; // SRAM写选通
inout[7:0] sram_data; // SRAM数据总线
//-------------------------------------------------------
reg[25:0] delay; //延时计数器
always @ (posedge clk or negedge rst_n)
if(!rst_n) delay <= 26'd0;
else delay <= delay+1; //不断计数,周期约为1.28s
//-------------------------------------------------------
reg[7:0] wr_data; // SRAM写入数据总线
reg[7:0] rd_data; // SRAM读出数据
reg[14:0] addr_r; // SRAM地址总线
wire sram_wr_req; // SRAM写请求信号
wire sram_rd_req; // SRAM读请求信号
reg led_r; // LED寄存器
assign sram_wr_req = (delay == 26'd9999); //产生写请求信号
assign sram_rd_req = (delay == 26'd19999); //产生读请求信号
always @ (posedge clk or negedge rst_n)
if(!rst_n) wr_data <= 8'd0;
else if(delay == 26'd29999) wr_data <= wr_data+1'b1; //写入数据每1.28s自增1
always @ (posedge clk or negedge rst_n)
if(!rst_n) addr_r <= 15'd0;
else if(delay == 26'd29999) addr_r <= addr_r+1'b1; //写入地址每1.28s自增1
always @ (posedge clk or negedge rst_n)
if(!rst_n) led_r <= 1'b0;
else if(delay == 26'd20099) begin //每1.28s比较一次同一地址写入和读出的数据
if(wr_data == rd_data) led_r <= 1'b1; //写入和读出数据一致,LED点亮
else led_r <= 1'b0; //写入和读出数据不同,LED熄灭
end
assign led = led_r;
//-------------------------------------------------------
`define DELAY_80NS (cnt==3'd7)
reg[2:0] cnt; //延时计数器
always @ (posedge clk or negedge rst_n)
if(!rst_n) cnt <= 3'd0;
else if(cstate == IDLE) cnt <= 3'd0;
else cnt <= cnt+1'b1;
//------------------------------------
parameter IDLE = 4'd0,
WRT0 = 4'd1,
WRT1 = 4'd2,
REA0 = 4'd3,
REA1 = 4'd4;
reg[3:0] cstate,nstate;
always @ (posedge clk or negedge rst_n)
if(!rst_n) cstate <= IDLE;
else cstate <= nstate;
always @ (cstate or sram_wr_req or sram_rd_req or cnt)
case (cstate)
IDLE: if(sram_wr_req) nstate <= WRT0; //进入写状态
else if(sram_rd_req) nstate <= REA0; //进入读状态
else nstate <= IDLE;
WRT0: if(`DELAY_80NS) nstate <= WRT1;
else nstate <= WRT0; //延时等待160ns
WRT1: nstate <= IDLE; //写结束,返回
REA0: if(`DELAY_80NS) nstate <= REA1;
else nstate <= REA0; //延时等待160ns
REA1: nstate <= IDLE; //读结束,返回
default: nstate <= IDLE;
endcase
//-------------------------------------
assign sram_addr = addr_r; // SRAM地址总线连接
//-------------------------------------
reg sdlink; // SRAM数据总线控制信号
always @ (posedge clk or negedge rst_n)
if(!rst_n) rd_data <= 8'd0;
else if(cstate == REA1) rd_data <= sram_data; //读出数据
always @ (posedge clk or negedge rst_n)
if(!rst_n) sdlink <=1'b0;
else
case (cstate)
IDLE: 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 : 8'hzz; // SRA数据总线连接
assign sram_wr_n = ~sdlink;
endmodule
我有一处不明, “else if(cstate == REA1) rd_data <= sram_data; ”这句说的是读出数据,但是此时 sdlink为0, sram_data应为高阻态(8‘hzz),所以rd_data怎么会等于wr_data??求大神解答~~~
sdlink=0时,sram_data高阻态,作为输入端,起到读ram的作用。
额 原来是这样~ 之前我还以为data_in和data_out是指同一条路径,现在看来应该是两条不同的路径,但由同一个IO口控制而已......谢谢
一周热门 更多>