FPGA Player

好记性不如烂笔头

导航

SRAM的控制程序

 

虽然SRAM的时序比起SDRAM要简单的多,但我是耗了好几天的时间,更让人纠结的是

我竟然会把管脚分配错误,耽误了两天。希望大家给看看,指点一二也好。

//DATA_EN会有一个周期的高电平,如果DATA_EN为高电平说明:
//如果在SRAM的写过程已经写完了一位,数据和地址可以再次产生
//如果在SRAM的读过程可以再产生下一个地址;
//如果在
module SRAM_Ctrl(
   SYS_CLK  ,
  SYS_RST_N ,
  SD_CE_N  ,
  SD_WE_N  ,
  SD_OE_N  ,
  SD_ADDR  ,//SRAM的地址
  SD_DATA  ,//SRAM的数据总线
  SD_BHE_N ,
  SD_BLE_N ,
  OUT_DATA ,//SRAM为输出时,读出数据的输出
  RD_REQ  ,//读写的请求信号
  WR_EN  ,//向FIFO的写数据请求信号
  DATA_EN  ,//写地址和数据的指示信号
  WR_DONE , //SRAM写满的标志信号
  IN_DATA  ,
  GEN_ADDR ,
  WR_REQ
 
  
 );

input    WR_REQ ;
input    RD_REQ ;
input    SYS_CLK ;
input    SYS_RST_N;
input [15 : 0] IN_DATA ;
input [17 : 0] GEN_ADDR;
output    DATA_EN ;
output    SD_CE_N ;
output    WR_EN ;
output    SD_WE_N;
output    SD_OE_N ;
output    SD_BHE_N;
output    SD_BLE_N;
input    WR_DONE;
output [15 : 0] OUT_DATA;
output [17 : 0] SD_ADDR;
inout [15 : 0] SD_DATA ;
reg        SD_WE_N;
reg  [  3 : 0] C_STATE ;
reg  [15 : 0] OUT_DATA;
reg      DATA_EN;
parameter IDLE  = 4'd0,
  WR_WAIT =  4'd1,
  WRITE  =  4'd2,
  READ  =  4'd3,
  RD_WAIT =  4'd4;
assign  SD_CE_N  = 1'b0;
assign  SD_OE_N  = 1'b0;
assign  SD_BHE_N = 1'b0;
assign  SD_BLE_N  = 1'b0;
always@( posedge SYS_CLK or negedge SYS_RST_N ) begin
 if( !SYS_RST_N ) begin
  C_STATE  <= IDLE;
  SD_WE_N <= 1'b1;
 end
 else
  case( C_STATE )
   IDLE : begin
     if( WR_REQ ) begin
       C_STATE <= WRITE;
       SD_WE_N <= 1'b0;     
     end
    else if( RD_REQ ) begin
       C_STATE <= READ;
       SD_WE_N <= 1'b1; 
    end
    else begin
     C_STATE  <= IDLE;
     SD_WE_N <= 1'b1;
        end
   end
  WRITE  : C_STATE <= WR_WAIT;
  WR_WAIT : C_STATE <= IDLE ;
  READ   : C_STATE <= RD_WAIT;
  RD_WAIT : C_STATE <= IDLE;
  default  : C_STATE <= IDLE;
  endcase
end
always@( posedge SYS_CLK or negedge SYS_RST_N ) begin
if( !SYS_RST_N )
   OUT_DATA <= 16'hzzzz;
else if( C_STATE == READ )
   OUT_DATA  <= SD_DATA ;
else   OUT_DATA  <= 16'hzzzz; 
end
always@( posedge SYS_CLK or negedge SYS_RST_N ) begin
if( !SYS_RST_N )
  DATA_EN <= 1'b0;
else if( (C_STATE == WR_WAIT) || ( C_STATE == RD_WAIT ))
  DATA_EN <= 1'b1;
else  DATA_EN <= 1'b0;
end
assign I_O_LINK  = ( (C_STATE == WRITE ) || (C_STATE ==  WR_WAIT)) ? 1'b1 : 1'b0;
assign SD_DATA =  I_O_LINK ? IN_DATA : 16'hzzzz;
assign WR_EN   = ( C_STATE == RD_WAIT ) ? 1'b1 : 1'b0;
assign  SD_ADDR = (C_STATE == WRITE || C_STATE == READ ||
   C_STATE == WR_WAIT || C_STATE == RD_WAIT ) ? GEN_ADDR  : 18'hz;
endmodule

 ///********************************修改后的SRAM控制程序***************************************

我是很想把SRAM的接口写好的,所以又做了一些改进,但是还是有不如意的地方,就在沿触发的设计上,现在还没有找到

更好的办法,只能先如此,说明一下各个输入输出的作用吧:

WR_REQ:写时钟,一个上升沿写进一位;

RD_REQ:读时钟,一个上升沿读走一位;

WR_EN:向FIFO的写有效信号,连接到FIFO写请求信号

module SRAM_Ctrl(
   SYS_CLK  ,
  SYS_RST_N ,
  SD_CE_N  ,
  SD_WE_N  ,
  SD_OE_N  ,
  SD_ADDR  ,//SRAM的地址
  SD_DATA  ,//SRAM的数据总线
  SD_BHE_N ,
  SD_BLE_N ,
  OUT_DATA ,//SRAM为输出时,读出数据的输出
  RD_REQ  ,

  WR_EN  ,//向FIFO的写数据请求信号
  DATA_EN  ,//写地址和数据的指示信号
  WR_DONE , //SRAM写满的标志信号
  IN_DATA  ,
  GEN_ADDR ,
  WR_REQ
 
  
 );

input    WR_REQ ;
input    RD_REQ ;
input    SYS_CLK ;
input    SYS_RST_N;
input [15 : 0] IN_DATA ;
input [17 : 0] GEN_ADDR;
output    DATA_EN ;
output    SD_CE_N ;
output    WR_EN ;
output    SD_WE_N;
output    SD_OE_N ;
output    SD_BHE_N;
output    SD_BLE_N;
input    WR_DONE;
output [15 : 0] OUT_DATA;
output [17 : 0] SD_ADDR;
inout [15 : 0] SD_DATA ;
reg  [  3 : 0] C_STATE ;
reg  [15 : 0] OUT_DATA;
reg      DATA_EN;
reg      WR_REQ1;
reg     RD_REQ1;
parameter IDLE  = 4'd0,
  WR_WAIT =  4'd1,
  WRITE  =  4'd2,
  READ  =  4'd3,
  RD_WAIT =  4'd4;
assign  SD_CE_N  = 1'b0;
assign  SD_OE_N  = 1'b0;
assign  SD_BHE_N = 1'b0;
assign  SD_BLE_N  = 1'b0;
always@( posedge SYS_CLK or negedge SYS_RST_N ) begin
if( !SYS_RST_N ) 
  WR_REQ1 <= 1'b0;
else  WR_REQ1 <= WR_REQ;
end
always@( posedge SYS_CLK or negedge SYS_RST_N ) begin
if( !SYS_RST_N ) 
  RD_REQ1 <= 1'b0;
else  RD_REQ1 <= RD_REQ;
end
wire Pos_WR_REQ = WR_REQ && (~WR_REQ1) ;
wire Pos_RD_REQ = RD_REQ && (~RD_REQ1);
always@( posedge SYS_CLK or negedge SYS_RST_N ) begin
 if( !SYS_RST_N ) begin
  C_STATE  <= IDLE;
 end
 else
  case( C_STATE )
   IDLE :
     if( Pos_WR_REQ && !WR_DONE)
        C_STATE <= WRITE;    
    else if( Pos_RD_REQ && WR_DONE)
        C_STATE <= READ;
    else    C_STATE  <= IDLE;
  WRITE  : C_STATE <= WR_WAIT;
  WR_WAIT : C_STATE <= IDLE ;
  READ   : C_STATE <= RD_WAIT;
  RD_WAIT : C_STATE <= IDLE;
  default  : C_STATE <= IDLE;
  endcase
end
always@( posedge SYS_CLK or negedge SYS_RST_N ) begin
if( !SYS_RST_N )
   OUT_DATA <= 16'hzzzz;
else if( C_STATE == READ )
   OUT_DATA  <= SD_DATA ;
else   OUT_DATA  <= 16'hzzzz; 
end
always@( posedge SYS_CLK or negedge SYS_RST_N ) begin
if( !SYS_RST_N )
  DATA_EN <= 1'b0;
else if( (C_STATE == WR_WAIT) || ( C_STATE == RD_WAIT ))
  DATA_EN <= 1'b1;
else  DATA_EN <= 1'b0;
end
wire I_O_LINK  = ( (C_STATE == WRITE ) || (C_STATE ==  WR_WAIT)) ? 1'b1 : 1'b0;
assign SD_DATA =  I_O_LINK ? IN_DATA : 16'hzzzz;
assign WR_EN   = ( C_STATE == RD_WAIT  ) ? 1'b1 : 1'b0;
assign  SD_ADDR = (C_STATE == WRITE || C_STATE == READ ||
   C_STATE == WR_WAIT || C_STATE == RD_WAIT ) ? GEN_ADDR  : 18'hz;
assign SD_WE_N = ( C_STATE == WRITE || C_STATE == WR_WAIT) ? 1'b0 : 1'b1;
endmodule

 

posted on 2012-10-16 22:12  中国的孩子  阅读(1378)  评论(2编辑  收藏  举报