课程设计论文线制 I2C CMOS串行EEPROM的FPGA设计

上传人:痛*** 文档编号:79139743 上传时间:2022-04-23 格式:DOC 页数:36 大小:751KB
收藏 版权申诉 举报 下载
课程设计论文线制 I2C CMOS串行EEPROM的FPGA设计_第1页
第1页 / 共36页
课程设计论文线制 I2C CMOS串行EEPROM的FPGA设计_第2页
第2页 / 共36页
课程设计论文线制 I2C CMOS串行EEPROM的FPGA设计_第3页
第3页 / 共36页
资源描述:

《课程设计论文线制 I2C CMOS串行EEPROM的FPGA设计》由会员分享,可在线阅读,更多相关《课程设计论文线制 I2C CMOS串行EEPROM的FPGA设计(36页珍藏版)》请在装配图网上搜索。

1、河南大学物理与电子学院 二线制 I2C CMOS 串行 EEPROM 的FPGA设计姓名:学号:080230114院系:物理院电子系2011年1月1日一、 课程设计摘要:(1)背景知识:A、基本介绍:二线制I2C CMOS 串行EEPROM AT24C02/4/8/16 是一种采用CMOS 工艺制成的串行可用电擦除可编程只读存储器。B、I2C (Inter Integrated Circuit)总线特征介绍 :I2C 双向二线制串行总线协议定义如下: 只有在总线处于“非忙”状态时,数据传输才能被初始化。在数据传输期间,只要时钟线为高电平,数据线都必须保持稳定,否则数据线上的任何变化都被当作“启

2、动”或“停止”信号。图 1 是被定义的总线状态。 总线非忙状态(A 段) 数据线SDA 和 时钟线 SCL 都保持高电平。 启动数据传输(B 段) 当时钟线(SCL)为高电平状态时,数据线(SDA)由高电平变为低电平的下降沿被认为是“启动”信号。只有出现“启动”信号后,其它的命令才有效。 停止数据传输(C 段) 当时钟线(SCL)为高电平状态时,数据线(SDA)由低电平变为高电平的上升沿被认为是“停止”信号。随着“停在”信号出现,所有的外部操作都结束。 数据有效(D 段) 在出现“启动”信号以后,在时钟线(SCL)为高电平状态时数据线是稳定的,这时数据线的状态就要传送的数据。数据线(SDA)上

3、的数据的改变必须在时钟线为低电平期间完成,每位数据占用一个时钟脉冲。每个数传输都是由“启动”信号开始,结束于“停止” 信号。 应答信号 每个正在接收数据的EEPROM 在接到一个字节的数据后,通常需要发出一个应答信号。而每个正在发送数据的EEPROM 在发出一个字节的数据后,通常需要接收一个应答信号。EEPROM 读写控制器必须产生一个与这个应答位相联系的额外的时钟脉冲。在EEPROM 的读操作中,EEPROM 读写控制器对EEPROM 完成的最后一个字节不产生应答位,但是应该给EEPROM 一个结束信号。 C、3. 二线制I2C CMOS 串行EEPROM读写操作 EEPROM 的写操作(字

4、节编程方式) 所谓EEPROM 的写操作(字节编程方式)就是通过读写控制器把一个字节数据发送到EEPROM 中指定地址的存储单元。其过程如下:EEPROM 读写控制器发出“启动”信号后,紧跟着送4 位I2C 总线器件特征编码1010 和3 位EEPROM 芯片地址/页地址XXX 以及写状态的R/W 位(=0),到总线上。这一字节表示在接收到被寻址的EEPROM 产生的一个应答位后,读写控制器将跟着发送1 个字节的EEPROM 存储单元地址和要写入的1 个字节数据。EEPROM 在接收到存储单元地址后又一次产生应答位以后,读写控制器才发送数据字节,并把数据写入被寻址的存储单元。EEPROM 再一

5、次发出应答信号,读写控制器收到此应答信号后,便产生“停止”信号。字节写入帧格式如图2 所示: 二线制I2C CMOS 串行EEPROM 的读操作 所谓EEPROM 的读操作即通过读写控制器读取 EEPROM 中指定地址的存储单元中的一个字节数据。串行EEPROM 的读操作分两步进行:读写器首先发送一个“启动”信号和控制字节(包括页面地址和写控制位)到EEPROM,再通过写操作设置EEPROM 存储单元地址(注意:虽然这是读操作,但需要先写入地址指针的值),在此期间EEPROM 会产生必要的应答位。接着读写器重新发送另一个“启动”信号和控制字节(包括页面地址和读控制位R/W = 1),EEPRO

6、M 收到后发出应答信号,然后,要寻址存储单元的数据就从SDA 线上输出。读操作有三种: 读当前地址存储单元的数据、读指定地址存储单元的数据、读连续存储单元的数据。在这里只介绍读指定地址存储单元数据的操作。读指定地址存储单元数据的帧格式如图3:(2)实现功能及设计思路: EEPROM是要实现接收来自信号源模型产生的读信号、写信号、并行地址信号、并行数据信号,并把它们转换为相应的串行信号发送到串行EEPROM(AT24C02/4/8/16) 的行为模型中去的功能,同时它还发送应答信号 (ACK)到信号源模型,以便让信号源来调节发送或接收数据的速度以配合EEPROM模型的接收(写)和发送(读)数据。

7、其基本设计思路是利用同步有限状态机的设计方法实现,根据串行EEPROM的读写特性,用五个状态时钟完成写操作,用七个状态时钟完成读操作,通过编写EEPROM读写器的模块以及随机读写数据模块,再加上信号产生模块,最终封装在一块完成初步的设计。二、系统设计部分 (1)整体设计的组织结构(2)子单元设计结构: EEPROM 的行为模型 为了设计这样一个电路我们首先要设计一个EEPROM 的Verilog HDL 模型,而设计这样一个模型我们需要仔细地阅读和分析EEPROM 器件的说明书,因为EEPROM 不是我们要设计的对象,而是我们验证设计对象所需要的器件,所以只需设计一个EEPROM 的行为模型,

8、而不需要可综合风格的模型,这就大大简化了设计过程。下面的Verilog HDL 程序就是这个EEPROM(AT24C02/4/8/16) 能完成一个字节数据读写的部分行为模型。这里只对在操作中用到的信号线进行模拟,对于没有用到的信号线就略去了。对EEPROM用于基本总线操作的引脚SCL和SDA说明如下:SCL,串行时钟端,这个信号用于对输入和输出数据的同步,写入串行EEPROM的数据用其上升沿同步,输出数据用其下降沿同步;SDA,串行数据(/地址)输入/输出端。EEPROM的行为模型如下:/-eeprom.v文件开始-define timeslice 100module EEPROM(scl,

9、sda); input scl; inout sda; reg out_flag; reg7:0 memory2047:0; reg10:0 address; reg7:0 memory_buf; reg7:0 sda_buf; reg7:0 shift; reg7:0 addr_byte; reg7:0 ctrl_byte; reg7:0 State; integer i; /- parameter r7= 8b10101110, w7= 8b10101110, /main7 r6= 8b10101101, w6= 8b10101100, /main6 r5= 8b10101011, w5=

10、 8b10101010, /main5 r4= 8b10101001, w4= 8b10101000, /main4 r3= 8b10100111, w3= 8b10100110, /main3 r2= 8b10100101, w2= 8b10100100, /main2 r1= 8b10100011, w1= 8b10100010, /main1 r0= 8b10100001, w0= 8b10100000; /main0 /- assign sda =(out_flag = 1) ? sda_buf7 : 1bz; /-寄存器和存储器初始化- initial begin addr_byte

11、 = 0; ctrl_byte = 0; out_flag = 0; sda_buf = 0; State = 2b00; memory_buf = 0; address = 0; shift = 0; for(i=0;i=0;i=i-1) begin (negedge scl); #timeslice; sda_buf = sda_buf1; end (negedge scl) #timeslice sda_buf7 = 1; (negedge scl) #timeslice out_flag = 0; end endtask endmodule /-eeprom.v文件结束-EEPROM读

12、写器的可综合的Verilog HDL模型 下面的程序是一个串行EEPROM读写器的可综合的Verilog HDL模型,它接收来自信号源模型产生的读信号、写信号、并行地址信号、并行数据信号,并把它们转换为相应的串行信号发送到串行EEPROM(AT24C02/4/8/16) 的行为模型中去;它还发送应答信号 (ACK)到信号源模型,以便让信号源来调节发送或接收数据的速度以配合EEPROM模型的接收(写)和发送(读)数据。因为它是我们的设计对象,所以它不但要仿真正确无误,还需要可综合。 这个程序基本上由两部分组成:开关组合电路和控制时序电路,见图5。开关电路在控制时序电路的控制下按照设计的要求有节奏

13、的打开或闭合,这样SDA可以按I2C 数据总线的格式输出或输入,SDA和SCL一起完成EEPROM的读写操作。 电路最终用同步有限状态机(FSM)的设计方法实现。程序实则上是一个嵌套的状态机,由主状态机和从状态机通过由控制线启动的总线在不同的输入信号的情况下构成不同功能的较复杂的有限状态机,这个有限状态机只有唯一的驱动时钟CLK。根据串行EEPROM的读写操作时序可知,用5个状态时钟可以完成写操作,用7个状态时钟可以完成读操作,由于读写操作的状态中有几个状态是一致的,用一个嵌套的状态机即可。状态转移如图6,程序由一个读写大任务和若干个较小的任务所组成,其状态机采用独热编码,若需改变状态编码,只

14、需改变程序中的parameter定义即可。读者可以通过模仿这一程序来编写较复杂的可综合Verilog HDL模块程序。这个设计已通过后仿真,并可在FPGA上实现布局布线。完成串行EEPROM读写器件的设计后,我们还需要做的重要一步是EEPROM读写器件的仿真。仿真可以分为前仿真和后仿真,前仿真是Verilog HDL的功能仿真,后仿真是Verilog HDL 代码经过综合、布局布线后的时序仿真。为此,我们还要编写了用于EEPROM读写器件的仿真测试的信号源程序。这个信号源能产生相应的读信号、写信号、并行地址信号、并行数据信号,并能接收串行EEPROM读写器件的应答信号 (ACK),来调节发送或

15、接收数据的速度。在这个程序中,我们为了保证串行EEPROM读写器件的正确性,可以进行完整的测试,写操作时输入的地址信号和数据信号的数据通过系统命令$readmemh 从addr.dat 和 data.dat 文件中取得,而在addr.dat 和data.dat文件中可以存放任意数据。读操作时从EEPROM 读出的数据存入文件eeprom.dat ,对比三个文件的数据就可以验证程序的正确性。$readmemh和$fopen等系统命令读者可以参考Verilog HDL的语法部分。最后我们把信号源、EEPROM和EEPROM读写器用顶层模块连接在一起。在下面的程序就是这个信号源的Verilog HD

16、L模型和顶层模块。EEPROM读写器模型如下:/-eeprom_wr.v文件开始-Module EEPROM_WR(sda,scl,ack,reset,clk,wr,rd,addr,data,main_state, sh8out_buf, head_state,sh8in_state);output scl,ack;input reset,clk,wr,rd;input10:0addr;inout sda;inout7:0data;output10:0main_state;output7:0sh8out_buf;output2:0head_state;output9:0 sh8in_state

17、;reg ack,scl,wf,rf,ff;reg1:0 head_buf,stop_buf;reg7:0 sh8out_buf;reg8:0 sh8out_state;reg9:0 sh8in_state;reg2:0 head_state,stop_state;reg10:0 main_state;reg7:0 data_from_rm;reg link_sda,link_read,link_head,link_write,link_stop;wire sda1,sda2,sda3,sda4;assign sda1=(link_head)?head_buf1:1b0;assign sda2

18、=(link_write)?sh8out_buf7:1b0;assign sda3=(link_stop)?stop_buf1:1b0;assign sda4=(sda1 | sda2 | sda3);assign sda=(link_sda)?sda4:1bz;assign data=(link_read)?data_from_rm:8hzz;parameter idle=11b00000000001,ready=11b00000000010,write_start=11b00000000100,ctrl_write= 11b00000001000,addr_write = 11b00000

19、010000,data_write = 11b00000100000,read_start = 11b00001000000,ctrl_read = 11b00010000000,data_read = 11b00100000000,stop= 11b01000000000,ackn= 11b10000000000,sh8out_bit7=9b000000001,sh8out_bit6=9b000000010,sh8out_bit5=9b000000100,sh8out_bit4=9b000001000,sh8out_bit3=9b000010000,sh8out_bit2=9b0001000

20、00,sh8out_bit1=9b001000000,sh8out_bit0=9b010000000,sh8out_end= 9b100000000;parameter sh8in_begin=10b0000000001,sh8in_bit7 =10b0000000010,sh8in_bit6 =10b0000000100,sh8in_bit5 =10b0000001000,sh8in_bit4 =10b0000010000,sh8in_bit3 =10b0000100000,sh8in_bit2 =10b0001000000,sh8in_bit1 =10b0010000000,sh8in_b

21、it0 =10b0100000000,sh8in_end =10b1000000000;parameter head_begin=3b001,head_bit =3b010,head_end =3b100,stop_begin=3b001,stop_bit =3b010,stop_end =3b100,yes=1b1,no=1b0;always (negedge clk)if(reset) scl=1b0;else scl=scl;always (posedge clk)if(reset) begin link_read=no;link_write=no; link_head=no;link_

22、stop=no; link_sda=no;ack=1b0;rf=1b0;wf=1b0;ff=1b0; main_state=idle; endelse begin casex(main_state)idle:begin link_read=no;link_write=no; link_head=no;link_stop=no; link_sda=no; if(wr) begin wf=1b1; main_state=ready; end else if(rd) begin rf=1b1; main_state=ready; end else begin wf=1b0;rf=1b0; main_

23、state=idle; end end ready:begin link_read=no;link_write=no; link_head=no;link_stop=yes; link_sda=yes; head_buf=2b10;stop_buf=1b01; head_state=head_begin; ff=1b0;ack=1b0;main_state=write_start; endwrite_start: if(ff=1b0) shift_head; else begin sh8out_buf7:0=4b1010,addr10:8,1b0; link_head=no;link_writ

24、e=yes; ff=1b0;sh8out_state=sh8out_bit6; main_state=ctrl_write; end ctrl_write: if(ff=1b0) shift8_out;/task else begin sh8out_state=sh8out_bit7; sh8out_buf7:0=addr7:0; ff=1b0;main_state=addr_write; endaddr_write: if(ff=1b0) shift8_out;/task else begin ff=1b0; if(wf) begin sh8out_state=sh8out_bit7; sh

25、8out_buf7:0=data; main_state=data_write; end if(rf) begin head_buf=2b10;head_state=head_begin; main_state=read_start; end end data_write: if(ff=1b0) shift8_out;/task else begin stop_state=stop_begin; main_state=stop; link_write=no;ff=1b0; endread_start: if(ff=1b0) shift_head;/task else begin sh8out_

26、buf=4b1010,addr10:8,1b1; link_head=no;link_sda=yes; link_write=yes;ff=1b0;sh8out_state=sh8out_bit6; main_state=ctrl_read; end ctrl_read: if(ff=1b0) shift8_out;/task else begin link_sda=no;link_write=no;ff=1b0; sh8in_state=sh8in_begin; main_state=data_read; enddata_read: if(ff=1b0) shift8in;/task els

27、e begin link_stop=yes;link_sda=yes;stop_state=stop_bit; ff=1b0;main_state=stop; end stop: if(ff=1b0) shift_stop;/task else begin ack=1b1;ff=1b0;main_state=ackn; end ackn: begin ack=1b0;wf=1b0;rf=1b0;main_state=idle; end default :main_state=idle; endcaseendtask shift8in;/ begin case(sh8in_state) sh8i

28、n_begin:sh8in_state=sh8in_bit7; sh8in_bit7: if(scl) begin data_from_rm7=sda;sh8in_state=sh8in_bit6;end else sh8in_state=sh8in_bit7; sh8in_bit6: if(scl) begin data_from_rm6=sda;sh8in_state=sh8in_bit5;end else sh8in_state=sh8in_bit6; sh8in_bit5: if(scl) begin data_from_rm5=sda;sh8in_state=sh8in_bit4;e

29、nd else sh8in_state=sh8in_bit5; sh8in_bit4: if(scl) begin data_from_rm4=sda;sh8in_state=sh8in_bit3;end else sh8in_state=sh8in_bit4;sh8in_bit3: if(scl) begin data_from_rm3=sda;sh8in_state=sh8in_bit2;end else sh8in_state=sh8in_bit3; sh8in_bit2: if(scl) begin data_from_rm2=sda;sh8in_state=sh8in_bit1;en

30、d else sh8in_state=sh8in_bit2; sh8in_bit1: if(scl) begin data_from_rm1=sda;sh8in_state=sh8in_bit0;end else sh8in_state=sh8in_bit1; sh8in_bit0: if(scl) begin data_from_rm0=sda;sh8in_state=sh8in_end;end else sh8in_state=sh8in_bit0;sh8in_end: if(scl) begin link_read=yes;ff=1b1;sh8in_state=sh8in_bit7;en

31、d else sh8in_state=sh8in_end; default:begin link_read=no;sh8in_state=sh8in_bit7; end endcaseendendtasktask shift8_out;begincasex(sh8out_state)sh8out_bit7: if(!scl)begin link_sda=yes;link_write=yes; sh8out_state=sh8out_bit6; end else sh8out_state=sh8out_bit7;sh8out_bit6: if(!scl) begin link_sda=yes;l

32、ink_write=yes; sh8out_state=sh8out_bit5;sh8out_buf=sh8out_buf1; end else sh8out_state=sh8out_bit6;sh8out_bit5: if(!scl) begin sh8out_state=sh8out_bit4;sh8out_buf=sh8out_buf1; end else sh8out_state=sh8out_bit5;sh8out_bit4: if(!scl) begin sh8out_state=sh8out_bit3;sh8out_buf=sh8out_buf1; end else sh8ou

33、t_state=sh8out_bit4;sh8out_bit3: if(!scl) begin sh8out_state=sh8out_bit2;sh8out_buf=sh8out_buf1; end else sh8out_state=sh8out_bit3;sh8out_bit2: if(!scl) begin sh8out_state=sh8out_bit1;sh8out_buf=sh8out_buf1; end else sh8out_state=sh8out_bit2;sh8out_bit1: if(!scl) begin sh8out_state=sh8out_bit0;sh8ou

34、t_buf=sh8out_buf1; end else sh8out_state=sh8out_bit1;sh8out_bit0: if(!scl) begin sh8out_state=sh8out_end;sh8out_buf=sh8out_buf1; end else sh8out_state=sh8out_bit0;sh8out_end: if(!scl) begin link_sda=no;link_write=no;ff=1b1; end else sh8out_state=sh8out_end;endcaseendendtasktask shift_head;begincasex

35、(head_state)head_begin: if(!scl) begin link_write=no;link_sda=yes; link_head=yes;head_state=head_bit; end else head_state=head_begin;head_bit: if(scl) begin ff=1b1;head_buf=head_buf1b1; head_state=head_end; end else head_state=head_bit;head_end: if(!scl) begin link_head=no;link_write=yes; end else h

36、ead_state=head_end;endcaseendendtasktask shift_stop;begincasex(stop_state)stop_begin: if(!scl) begin link_sda=yes;link_write=no;link_stop=yes;stop_state=stop_bit; end else stop_state=stop_begin;stop_bit: if(scl) begin stop_buf=stop_buf1; stop_state=stop_end; end else stop_state=stop_bit;stop_end: if

37、(!scl) begin link_head=no;link_stop=no;link_sda=no;ff=1b1; end else stop_state=stop_end;endcaseendendtaskendmodule/-eeprom_wr.v文件结束- 信号产生模块: 用于产生测试信号,对所设计的EEPROM_WR模块进行测试。Signal模块能对被测模块产生的ack信号产生影响,发出模仿MCU的数据、地址信号和读/写信号;被测信号的模块在接收到信号后会发出写/读EEPROM虚拟模块的信号。信号产生模型如下:/-signal.v文件开始-timescale 1ns/1nsdefin

38、e timeslice 100module Signal(reset,clk,rd,wr,addr,ack,data); output reset; output clk; output wr,rd; output 10:0 addr; input ack; inout 7:0data; reg reset; reg clk; reg rd,wr; reg W_R; reg10:0 addr; reg7:0 data_to_eeprom; reg10:0 addr_mem0:255; reg7:0 data_mem0:255; reg7:0 ROM1:2047; integer i,j; in

39、teger OUTFILE; parameter test_number = 50; assign data = (W_R) ? 8bz : data_to_eeprom; always # (timeslice/2) clk = clk; initial begin reset = 1; i = 0; j = 0; W_R = 0; clk = 0; rd = 0; wr = 0; #1000; reset = 0; repeat(test_number) begin #(5*timeslice); wr = 1; #(timeslice); wr = 0; (posedge ack); e

40、nd #(10* timeslice); W_R = 1; repeat(test_number) begin #(5*timeslice); rd = 1; #(timeslice); rd = 0; (posedge ack); end end initial begin $display(writing-writing-writing-writing); #(2*timeslice); for(i=0;i15;i=i+1) begin addr = addr_memi; data_to_eeprom = data_memi; $fdisplay(OUTFILE,%0h %0h,addr,data_to_eeprom); (posedge ack); end end initial (posedge W_R) begin addr=addr_mem0; $fclose(OUTFILE); $readmemh(D:/DC FPGA/dacheng/eeprom/eeprom.dat,ROM); $display(Begin READING-

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!