/* ************************************************************************************************
// Engineer : xymbmcu@163.com
// Target Device : Altera Cyclone EP2C8Q208C8
// Clock : 50Mhz
// Create Date : 2012-12-29 20:47
// Amend Date :
// Module Name : sram_test
// Project Name : sram_test
// Tool versions : Quartus II 12.1
// Description : 实现SRAM的读写操作
// Revision : NO
// Additional Comments: 好好学学,这是FPGA学习的跳板,这或许是你真正走进FPGA大门的金钥匙,只是或许是为建模的注释 ^o^
************************************************************************************************ */
module sram_test(
Clk_50m,
Rst_n,
SramWrEn_n,
SramRdEn_n,
SramCsEn_n,
SramLbEn_n,
SramUbEn_n,
SramAddr,
SramData,
LedOut
);
/* ************************************************************************* */
input Clk_50m;
input Rst_n;
output SramWrEn_n;
output SramRdEn_n;
output SramCsEn_n;
output SramLbEn_n;
output SramUbEn_n;
output [17:0] SramAddr;
inout [15:0] SramData;
output LedOut;
/* ************************************************************************* */
//延时计时器(1S)
reg [25:0] i_DelayCount;
always @ (posedge Clk_50m or negedge Rst_n)
if(!Rst_n)
i_DelayCount <= 26'd0;
else
i_DelayCount <= i_DelayCount + 1'b1;
/* ***************************************************** */
//产生读写请求信号
wire SramRdReq_w;
wire SramWrReq_w;
assign SramWrReq_w = (i_DelayCount == 26'd9999);
assign SramRdReq_w = (i_DelayCount == 26'd19999);
/* ***************************************************** */
//采用简单的时序进行读写,只需控制SramWrEn_n!!
reg SramCsEn_nr;
reg SramRdEn_nr;
reg SramLbEn_nr;
reg SramUbEn_nr;
always @ (posedge Clk_50m or negedge Rst_n)
if(!Rst_n) begin
SramCsEn_nr <= 1'b1;
SramRdEn_nr <= 1'b1;
SramLbEn_nr <= 1'b1;
SramUbEn_nr <= 1'b1;
end
else begin
SramCsEn_nr <= 1'b0;
SramRdEn_nr <= 1'b0;
SramLbEn_nr <= 1'b0;
SramUbEn_nr <= 1'b0;
end
/* ***************************************************** */
assign SramCsEn_n = SramCsEn_nr;
assign SramRdEn_n = SramRdEn_nr;
assign SramLbEn_n = SramLbEn_nr;
assign SramUbEn_n = SramUbEn_nr;
/* ***************************************************** */
reg [15:0] SramWrData_r;
reg [15:0] SramRdData_r;
reg [17:0] SramAddr_r;
reg LedOut_r;
//遍历数据
always @ (posedge Clk_50m or negedge Rst_n)
if(!Rst_n)
SramWrData_r <= 16'b0;
else if(i_DelayCount == 26'd29999)
SramWrData_r <= SramWrData_r + 1'b1;
//遍历地址
always @ (posedge Clk_50m or negedge Rst_n)
if(!Rst_n)
SramAddr_r <= 16'b0;
else if(i_DelayCount == 26'd29999)
SramAddr_r <= SramAddr_r + 1'b1;
//用LED的显示来指示SRAM的读写是否正常
always @ (posedge Clk_50m or negedge Rst_n)
if(!Rst_n)
LedOut_r <= 1'b0;
else if(i_DelayCount == 26'd29999) begin
if(SramRdData_r == SramWrData_r)
LedOut_r <= 1'b1;
else
LedOut_r <= 1'b0;
end //end of else if
/* ***************************************************** */
assign LedOut = LedOut_r;
/* ***************************************************** */
reg [2:0] j_DelayCount;
`define Delay80ns (j_DelayCount == 3'd7)
always @ (posedge Clk_50m or negedge Rst_n)
if(!Rst_n)
j_DelayCount <= 3'd0;
else if(CurrentState_r == IDLE)
j_DelayCount <= 3'd0;
else j_DelayCount <= j_DelayCount + 1'b1;
/* ***************************************************** */
parameter IDLE = 4'd0,
WrData0 = 4'd1,
WrData1 = 4'd2,
RdData0 = 4'd3,
RdData1 = 4'd4;
reg [3:0] CurrentState_r,NextState_r;
//第一段状态机
always @ (posedge Clk_50m or negedge Rst_n)
if(!Rst_n)
CurrentState_r <= IDLE;
else
CurrentState_r <= NextState_r;
//第二段状态机
always @ (CurrentState_r or SramWrReq_w or SramRdReq_w or j_DelayCount) begin
case (CurrentState_r)
IDLE : if(SramRdReq_w) NextState_r <= WrData0;
else if(SramRdReq_w) NextState_r <= RdData0;
else NextState_r <= IDLE;
WrData0: if(`Delay80ns) NextState_r <= WrData1;
else NextState_r <= WrData0;
WrData1: NextState_r <= IDLE;
RdData0: if(`Delay80ns) NextState_r <= RdData1;
else NextState_r <= RdData0;
RdData1: NextState_r <= IDLE;
default: NextState_r <= IDLE;
endcase
end
/* ************************************************************************* */
assign SramAddr = SramAddr_r;
/* ************************************************************************* */
always @ (posedge Clk_50m or negedge Rst_n)
if(!Rst_n)
SramRdData_r <= 16'b0;
else
SramRdData_r <= SramData;
/* ************************************************************************* */
reg SramLink_r;
always @ (posedge Clk_50m or negedge Rst_n)
if(!Rst_n)
SramLink_r <= 1'b0;
else case (CurrentState_r)
IDLE:
if(SramWrReq_w) SramLink_r <= 1'b1;
else if(SramRdReq_w) SramLink_r <= 1'b0;
else SramLink_r <= 1'b0;
WrData0: SramLink_r <= 1'b1;
default: SramLink_r <= 1'b0;
endcase
/* ************************************************************************* */
assign SramData = SramLink_r ? SramWrData_r : 16'bx;
assign SramWrEn_n = ~SramLink_r;
/* ************************************************************************* */
endmodule
这次代码的编写过程自己特别列了一个Verilog HDL的代码书写规范,无规矩不成方圆吗??说明,在复制过程中可能格式有变,在QUARTUS II 12.1中看起来真的很漂亮,再加上其软件的只能功能,编写起来舒服、漂亮,享受其中的快乐吧,O(∩_∩)O~,时间不早了,灯亮了,自己该睡了…
用户1852423 2016-6-13 09:44
用户1851850 2016-4-10 20:50
用户1758489 2014-11-7 12:01
liang890319_284707880 2013-9-9 17:10
用户403664 2013-9-9 14:59