在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 4454|回复: 6

[求助] 同步SRAM读写

[复制链接]
发表于 2020-5-11 11:37:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 leo_zhao 于 2020-5-11 12:57 编辑

本人在用FPGA驱动is61lps409618B同步SRAM芯片时遇到读写的问题:
       每次都只能读出最后一次待存进SRAM的值,先开始我以为是地址信号没给上,每次都在同一个地址读写,后来我发现我好像只是把inout数据端口的数读出来了而已,因为我即使不给SRAM时钟信号,它也是这样。我的感觉是读写信号没有给到芯片端口,或者芯片没有工作,读写的时序我是按照手册写的,写的比较简单(用计数器进行状态控制,进行循环读写),希望有经验的大神给点指导意见啊,下面是我的代码,:



  `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: zx
//
// Create Date:    16:05:13 04/27/2020
// Design Name:
// Module Name:    SRAM_4096_18B
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module SRAM_4096_18B(
    input clk,
input rst,
input data_en, //输入标志信号
input [15:0]data_i,//输入数据
output reg out_dv, //输出标志信号
//对接SRAM芯片//
    output reg BWE_N,
    output CE2_N,
    output CE_N,
    output CE2,
    output ZZ,
    output BWA_N,
    output MODE,
    output reg ADSP_N,
    output BWB_N,
    output ADV_N,
    output reg ADSC_N,
    output GW_N,
    output OE_N,
    (*KEEP="TRUE"*)output  [21:0] Addr/* synthesis syn_keep = 1*/,
inout  [8:0]DQa,
inout  [8:0]DQb
    );


assign ZZ=1'b0;   //睡眠模式,高电平有效//
assign MODE=1'b0;
assign ADV_N=1'b1;//序列传输,低有效//
assign BWA_N=1'b0;
assign BWB_N=1'b0;
assign GW_N=1'b1;
assign CE2_N=1'b0;
assign CE2=1'b1;
assign CE_N=1'b0;
assign OE_N=1'b0;
//assign GW_N=1'b1;

wire DQPb_in,DQPa_in; //两路奇偶校验位//
assign DQPa_in=1'b0;  //奇偶校验位赋值//
assign DQPb_in=1'b0;
reg [17:0] sram_output;
assign DQb[8:0]=(BWE_N)?9'bz:sram_output[17:9];
assign DQa[8:0]=(BWE_N)?9'bz:sram_output[8:0];
reg sram_input_en;
wire [17:0]data_read/* synthesis syn_keep = 1*/;
assign data_read[17:9]=(!BWE_N)?9'bzQb[8:0];
assign data_read[8:0]=(!BWE_N)?9'bzQa[8:0];

(*KEEP="TRUE"*)reg [15:0]data_read_d1/* synthesis syn_preserve=TRUE */;          //for test//
always@(posedge clk)
begin
data_read_d1<={data_read[16:9],data_read[7:0]};
end

(*KEEP="TRUE"*)reg [21:0]Addrbuf/* synthesis syn_preserve=TRUE */;
assign Addr=(ADSP_N)?22'bz:Addrbuf/* synthesis syn_preserve=TRUE */;
reg [4:0] state_cnt/* synthesis syn_preserve=TRUE */; //32计数器//

always@(posedge clk)
begin
if(rst)
  state_cnt<=0;
else
  if(state_cnt<20)
   state_cnt<=state_cnt+1;
  else
   state_cnt<=0;
end
reg [17:0] data_w;
always@(posedge clk)
begin
if(rst)
  begin
   data_w<=18'd0;
  end
else
  begin
   data_w<={1'b0,data_i[15:8],1'b0,data_i[7:0]};
  end
end
always@(posedge clk)
begin
if(rst)  //复位//
  begin
   ADSP_N<=1'b1;
   ADSC_N<=1'b1;
   BWE_N<=1'b1;
   //OE_N<=1'b1;
   Addrbuf<=22'd0;
   sram_output<=18'd0;
  end
else
  begin
   if(state_cnt==5'd0)   //开始写//
    begin
     //地址//
     ADSP_N<=1'b1;
     ADSC_N<=1'b1;//第一拍先不写入地址,因为地址进入存储器只需要一个延时,而数据需要两个//
     Addrbuf<=22'd0;
     //写使能//         //使能 但不给数据//
     BWE_N<=1'b1;  
     sram_output<=18'd0;
     sram_output_en<=1'b1;
     //读使能//     //不使能//
     //OE_N<=1'b1;
    end
   else if(state_cnt==5'd1)   
    begin
     //地址//
     ADSP_N<=1'b0;
     ADSC_N<=1'b1;//写入地址0//
     Addrbuf<=22'd0;
     //写使能//      //不使能 //
     BWE_N<=1'b1;  
     sram_output<=18'd0;
     sram_output_en<=1'b1;
     //读使能//     //不使能//
     //OE_N<=1'b1;
    end
   else if(state_cnt==5'd2)   
    begin
     //地址//
     ADSP_N<=1'b1;
     ADSC_N<=1'b1;//第一拍先不写入地址,因为地址进入存储器只需要一个延时,而数据需要两个//
     Addrbuf<=22'd0;
     //写使能//         //使能 但不给数据//
     BWE_N<=1'b0;  
     sram_output<=data_w;
     sram_output_en<=1'b0;
     //读使能//     //不使能//
     //OE_N<=1'b1;
    end
   else if(state_cnt==5'd3)   
    begin
     //地址//
     ADSP_N<=1'b0;
     ADSC_N<=1'b1;//写入地址10//
     Addrbuf<=22'd10;
     //写使能//      //不使能 //
     BWE_N<=1'b1;  
     sram_output<=18'd0;
     //读使能//     //不使能//
     //OE_N<=1'b1;
    end
   else if(state_cnt==5'd4)   
    begin
     //地址//
     ADSP_N<=1'b1;
     ADSC_N<=1'b1;//第一拍先不写入地址,因为地址进入存储器只需要一个延时,而数据需要两个//
     Addrbuf<=22'd0;
     //写使能//         //使能 但不给数据//
     BWE_N<=1'b0;  
     sram_output<=data_w;
     //读使能//     //不使能//
     //OE_N<=1'b1;
    end
   else if(state_cnt==5'd11)   //读地址//
    begin
     //地址//
     ADSP_N<=1'b0;
     ADSC_N<=1'b1;
     Addrbuf<=22'd0;//读地址0//
     //写使能//      //使能 并给数据//
     BWE_N<=1'b1;
     sram_output<=18'd0;
     //读使能//     //不使能//
     //OE_N<=1'b1;
    end
   else if(state_cnt==5'd12)   //开始读//
    begin
     //地址//
     ADSP_N<=1'b1;
     ADSC_N<=1'b1;
     Addrbuf<=22'd0;
     //写使能//         //不使能//
     BWE_N<=1'b1;  
     sram_output<=18'd0;
     //读使能//     //使能//
     //OE_N<=1'b1;
    end
   else if(state_cnt==5'd13)   
    begin
     //地址//
     ADSP_N<=1'b0;
     ADSC_N<=1'b1;
     Addrbuf<=22'd10;//读地址10//
     //写使能//         //不使能//
     BWE_N<=1'b1;
     sram_output<=18'd0;
     //读使能//     //使能//
     //OE_N<=1'b0;
    end
   else if(state_cnt==5'd14)   //开始读//
    begin
     //地址//
     ADSP_N<=1'b1;
     ADSC_N<=1'b1;
     Addrbuf<=22'd0;
     //写使能//         //不使能//
     BWE_N<=1'b1;  
     sram_output<=18'd0;
     //读使能//     //使能//
     //OE_N<=1'b1;
    end
   else if(state_cnt==5'd15)
    begin
     //地址//
     ADSP_N<=1'b1;
     ADSC_N<=1'b1;
     Addrbuf<=22'd0;//读地址10//
     //写使能//         //不使能//
     BWE_N<=1'b1;
     sram_output<=18'd0;
     //读使能//     //使能//
     //OE_N<=1'b0;
    end
   else
    begin
     //地址//
     ADSP_N<=1'b1;
     ADSC_N<=1'b1;
     Addrbuf<=22'd0;//读地址10//
     //写使能//         //不使能//
     BWE_N<=1'b1;
     sram_output<=18'd0;
     //读使能//     //使能//
     //OE_N<=1'b0;   
    end
  end
end
endmodule


发表于 2020-5-12 19:24:09 | 显示全部楼层
能不能用内部逻辑分析仪抓波形看看?而且你的RST接到什么地方的?没法先做功能仿真吗?
 楼主| 发表于 2020-5-13 11:20:58 | 显示全部楼层


gaurson 发表于 2020-5-12 19:24
能不能用内部逻辑分析仪抓波形看看?而且你的RST接到什么地方的?没法先做功能仿真吗? ...


捕获.PNG
这是用chipscope抓的波形,rst是我自己在fpga里面用定时器写的。。

 楼主| 发表于 2020-5-13 11:30:17 | 显示全部楼层


leo_zhao 发表于 2020-5-13 11:20
这是用chipscope抓的波形,rst是我自己在fpga里面用定时器写的。。


clk.jpg
我输出的clk电平标准是LVCOMOS33,但是用示波器观测到fpga输出的时钟上限只有2.8v左右,应该是3.3v才对啊

发表于 2021-8-29 17:42:46 | 显示全部楼层
laokouqian
发表于 2021-9-1 09:26:29 | 显示全部楼层
great
发表于 2021-9-2 16:06:51 | 显示全部楼层
本帖最后由 innovation 于 2021-9-2 16:10 编辑


leo_zhao 发表于 2020-5-13 11:30
我输出的clk电平标准是LVCOMOS33,但是用示波器观测到fpga输出的时钟上限只有2.8v左右,应该是3.3v才对 ...


虽然你没有给出问题的最终解决方案,但相信问题不在你这个示波器的测试结果上。FPGA逻辑工程师还是需要相当的电路知识的:
1. 从你的照片模模糊糊的判断你的示波器水平轴设置的是20ns/div,时钟频率大概20MHz,测试波形的上升时间大概20ns
2. 你提到FPGA对时钟输出的电平规范设置为LVCMOS33,但没提驱动强度和斜率(速率)的设置
3. MSO4054这个示波器的采样率是2.5GHz,模拟带宽500MHz,但这些参数是可调的,带宽有20M和250M的选项
4. 综合考虑,你最大的可能是没注意到示波器的带宽设置,结合数据和测试波形来看,有很大可能设置的是20M的带宽
5. 3.3V变为2.8V,同时信号上升/下降时间很长,有很大可能是因为带宽不够
6. 3.3V变为2.8V,对数字电路来说,不是工作与否的问题,是噪声容限变差的问题
7. 很大可能你的测试方法不客观,你看到的波形和SRAM芯片本身感受的输入信号并不一致,你咋个分析和判断呢?
8. 如果单以示波器显示的波形来看,2.8V的幅值不会是问题,更大的问题应该考虑如此缓慢的上升/下降时间,时钟抖动会超出你的预算,导致一些你没考虑到的时序问题
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-23 22:55 , Processed in 0.022705 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表