简化串行EEPROM系统设计

本文介绍了一种基于Verilog的IIC接口EEPROM读写控制器的设计方法,包括信号源模块、EEPROM行为模型及EEPROM读写控制器模块的具体实现细节。详细解释了各个模块的功能、工作流程及仿真结果。

参考自夏宇闻老师《verilog系统设计原理》
EEPROM系统模型
系统设计基础原理:
IIC串行总线工作状态定义如下:
在这里插入图片描述
(1)总线非忙状态(A段):SDA和SCL均保持高电平;
(2)启动数据传输(B段):SCL为高电平,SDA的下降沿被认为是启动信号,只有出现启动信号之后,其他的命令才有效。
(3)停止数据传输(C段):SCL为高电平,SDA的上升沿被认为是停止信号。
(4)数据有效(D段):出现启动信号后,在SCL高电平时,数据线稳定,表示要传输的数据;SDA必须在SCL低电平时改变。每个数据占用一个时钟脉冲。

EEPROM写操作帧格式:
写操作过程即通过EEPROM读写控制器将一个字节数据发送到EEPROM中指定地址的存储单元。
过程如下:EEPROM读写控制器发送启动信号,紧跟着一个控制字节(包含特征编码1010+芯片地址/页地址XXX+写状态(0))至总线上;收到EEPROM产生的一个应答位后,紧跟着发送一字节地址和一字节数据,EEPROM分别产生一次应答位,最后读写控制器产生停止信号。
在这里插入图片描述
EEPROM读操作帧格式:
读操作即通过读写控制器读取EEPROM中指定地址的存储单元中的一个字节数据。
过程如下:EEPROM读写控制器发送启动信号和一个控制字节(此时控制状态为写)至总线上,通过写操作设置EEPROM存储单元地址,此期间EEPROM会产生必要的应答位;读写控制器紧跟着重新发送启动信号和一个控制字节(此时控制状态为读),EEPROM发出应答信号后,寻址存储单元的数据从SDA线上输出。EEPROM产生一次非应答(高电平),最后读写控制器产生停止信号。
在这里插入图片描述

Verilog程序由三个模块构成:
Signal:信号源模块,产生用于EEPROM读写器件的仿真测试信号,能产生相应的复位信号(RESET),时钟信号(CLK),读信号(WR),写信号(RD),并行地址信号(ADDR)和并行数据信号(DATA),并能接收串行EEPROM读写期间的应答信号(ACK)及,以此来调节发送或接收数据的速度。
其中ACK为输入信号,DATA为双向信号,可输出EEPROM写操作的数据,也可接收EEPROM读操作的数据。该模块为行为仿真,采用阻塞赋值,不可综合为门级网表。
代码如下所示:

module Signal(
input                       ACK          ,//应答信号,EEPROM读写器用于控制信号源读写速度
inout[7:0]                  DATA         ,//写操作数据
output reg                  RESET        ,//复位信号
output reg                  CLK          ,//时钟周期200ns
output reg                  RD           ,//读标志 持续一个时钟
output reg                  WR           ,//写标志 持续一个时钟
output reg[10:0]            ADDR          //读/写地址
);


reg                       W_R                   ; 
reg[7:0]                  data_to_eeprom        ;//DATA输出写EEPROM操作的数据
reg[10:0]                 addr_mem[0:255]       ;//地址存储器
reg[7:0]                  data_mem[0:255]       ;//数据(写)存储器
reg[7:0]                  ROM[0:2047]           ;//表示EEPROM存储器
integer                   i,j                   ;//循环参数
integer                   OUTFILE               ;//文件句柄,文件内容为写操作地址,数据




parameter test_number =50; //测试次数
assign    DATA =(W_R)? 8'bz:data_to_eeprom;//W_R=0,DATA输出写EEPROM操作的数据

//-----------------时钟输入-----------------
always #(`timeslice2/2) CLK = ~CLK ;

//-----------------读写信号输入--------------
initial begin
   RESET=1  ;
   i=0      ;
   j=0      ;
   W_R=0    ;
   CLK=0    ;
   RD=0     ;
   WR=0     ;
   #1000    ;
   RESET=0  ;
   
   //WR拉高一个时钟,收到ACK后再次循环,循环次数test_number
   repeat(test_number)begin
      #(5*`timeslice2);
      WR=1;
      #(`timeslice2)
      WR=0;
      @(posedge ACK);
   end   

   //写操作完成后,W_R拉高,进入读操作 
   #(10*`timeslice2);
   W_R=1;
   
   //RD拉高一个时钟,收到ACK后再次循环,循环次数test_number
   repeat(test_number)begin
      #(5*`timeslice2)
      RD=1;
      #(`timeslice2)
      RD=0;
      @(posedge ACK);
   end 
end 

//读地址存储器,数据存储器,test_number个时钟;并将地址与对应数据写入eeprom.dat文件
initial begin
   $display("writing----writing----writing----writing");
   #(2*`timeslice2);
   
   for(i=0;i<test_number;i=i+1)begin
      ADDR=addr_mem[i];
      data_to_eeprom=data_mem[i];
      // $fdisplay(OUTFILE,"@%0h   %0h",ADDR,data_to_eeprom);
	  $fdisplay(OUTFILE,"%0h",data_to_eeprom);
      @(posedge ACK);
   end 
end 

//将eeprom.dat文件数据存于ROM;比较读eeprom.dat文件数据与写入数据是否一致
initial@(posedge W_R)begin
  ADDR=addr_mem[0];
  $fclose(OUTFILE);
  $readmemh("C:/users/lenovo/Desktop/example/eeprom.dat",ROM);
  $display("Begin READING----READING----READING----READING");
  for(j=0;j<=test_number;j=j+1)begin
    ADDR=addr_mem[j];
    @(posedge ACK);
    if(data_mem[ADDR]==ROM[ADDR])
       $display("data_mem%0h==ROM_[%0h]%0h---READ RIGHT",data_mem[ADDR],ADDR,ROM[ADDR]);
    else 
       $display("data_mem%0h!==ROM[%0h]%0h---READ WRONG",data_mem[ADDR],ADDR,ROM[ADDR]);
  end 
end 

//将dat文件中地址,数据分别储存在addr_mem,data_mem存储器;打开eeprom.dat文件
initial begin
   OUTFILE=$fopen("C:/users/lenovo/Desktop/example/eeprom.dat");
   $readmemh("C:/users/lenovo/Desktop/example/addr.dat",addr_mem);
   $readmemh("C:/users/lenovo/Desktop/example/data.dat",data_mem);
end 


endmodule

其中,addr.dat,data.dat分别为存放EEPROM读/写操作地址,写操作数据的文件;eeprom.dat用于输出EEPROM读操作的数据,与写入数据对比是否一致(文件中数据为十六进制表示)。

00
01
02
03
04
05
06
07
08
09
0a
0b
0c
0d
0e
0f
10
11
12
13
14
15
16
17
18
19
1a
1b
1c
1d
1e
1f
20
21
22
23
24
25
26
27
28
29
2a
2b
2c
2d
2e
2f
30
31
32
33
34
35
36
37
38
39
3a
3b
3b
3a
39
38
37
36
35
34
33
32
31
30
2f
2e
2d
2c
2b
2a
29
28
27
26
25
24
23
22
21
20
1f
1e
1d
1c
1b
1a
19
18
17
16
15
14
13
12
11
10
0f
0e
0d
0c
0b
0a
09
08
07
06
05
04
03
02
01
00

仿真结果如下图所示:
写操作:
在这里插入图片描述
可观察到DATA此时从Signal模块输出至EEPROM读写器,该数据为EEPROM写操作的数据;WR为写信号,EEPROM读写器检测到该信号后,从SDA数据线给EEPROM器件发出写入帧信号;ADDR为写入地址。
读操作:
在这里插入图片描述
可观察到Signal发出读信号RD一段时间后,EEPROM读写器会发出应答信号ACK,同时返回读EEPROM数据DATA;将读数据与写入数据进行对比,可验证程序正确性:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值