eeprominterfaceVerilog实现的简单程序I2C总线接口.docx

上传人:b****4 文档编号:12095939 上传时间:2023-04-17 格式:DOCX 页数:13 大小:18.79KB
下载 相关 举报
eeprominterfaceVerilog实现的简单程序I2C总线接口.docx_第1页
第1页 / 共13页
eeprominterfaceVerilog实现的简单程序I2C总线接口.docx_第2页
第2页 / 共13页
eeprominterfaceVerilog实现的简单程序I2C总线接口.docx_第3页
第3页 / 共13页
eeprominterfaceVerilog实现的简单程序I2C总线接口.docx_第4页
第4页 / 共13页
eeprominterfaceVerilog实现的简单程序I2C总线接口.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

eeprominterfaceVerilog实现的简单程序I2C总线接口.docx

《eeprominterfaceVerilog实现的简单程序I2C总线接口.docx》由会员分享,可在线阅读,更多相关《eeprominterfaceVerilog实现的简单程序I2C总线接口.docx(13页珍藏版)》请在冰豆网上搜索。

eeprominterfaceVerilog实现的简单程序I2C总线接口.docx

eeprominterfaceVerilog实现的简单程序I2C总线接口

    

eeprom_interfaceVerilog实现的简单程序(I2C总线接口)

    

    

Actel公司时间:

2008年08月13日

    

字体:

大中小

    

    关键词:

<"cblue""target='_blank'>上电<"cblue""target='_blank'>串行闪存<"cblue""target='_blank'>第一个<"cblue""target='_blank'>加载<"cblue""target='_blank'>连续输出

    

    

    

//i2c.vhd

//

//这是是能从一个外部NUM(AT24C02A)读数据到一个256x8的外部SRAM块的I2C主接口程序,

//当用于写NUM的外部逻辑寄存器存取时,SRAM就从外部源读数据并且把数据写到特定的I2C地址。

//----------------------------------------------------------------------

//

//?

?

?

?

?

?

?

?

?

?

?

?

?

Copyright2004Actelcorporation

//

//----------------------------------------------------------------------

//

//Version1.2?

06/04/04J.Vorgert-workingfile

//

//----------------------------------------------------------------------

'timescale1ns/1ps

modulei2c(Reset_n,CLK,INIT,IENB,IADDR,IDATA,ICLK,UPDT,

?

?

?

?

?

?

?

?

?

?

?

UENB,UADDR,UDATA,SDI,SDO,SCK);

inputReset_n;?

/*activelowreset*/

inputCLK?

?

?

;?

/*processorclock?

*/

outputINIT?

?

;?

/*highduringinit*/

outputIENB?

?

;?

/*lowtoenablewrite*/

output[7:

0]IADDR?

;?

/*initaddress*/

output[7:

0]IDATA?

;?

/*initdata*/

outputICLK?

?

;?

/*initclock*/

inputUPDT?

?

;?

/*hightotriggermirrorimageupdate*/

outputUENB?

?

;?

/*lowtoenablefifo*/

input[7:

0]UADDR;/*writeaddress*/

input[7:

0]UDATA;?

/*writedata*/

inputSDI?

?

?

;?

/*serialinput*/

outputSDO?

?

?

;/*activelowopen-draindriveenable-data*/

outputSCK?

?

?

;/*activelowopen-draindriveenable-clock*/

regIENB;

regINIT;

regUENB;

regBTCK;

wireSTEN;?

?

?

?

reg?

[3:

0]CSTATE;?

?

reg?

[3:

0]BCNT?

;?

reg?

[7:

0]CCNT?

;?

regDLY?

?

?

?

;

regD2;

wireD2I;

wireNKI?

?

?

?

;

regNACK?

?

?

;

wireWRI?

?

?

?

;

wireRDI?

?

?

?

;

reg[8:

0]BYTE?

?

;

reg[8:

0]SDATA?

;

wireLD_BYTE?

;

regSTSP?

?

?

?

;

wireCTL_VAL?

;

always@(posedgeCLKornegedgeReset_n)

begin

?

if(Reset_n==1'b0)

?

?

?

?

BTCK<=1'b0;

?

else

?

?

?

?

BTCK<=#1!

BTCK;

end

//INITissetatpower-upandclearedwhenthestatemachine

//reachesstate0101.

always@(negedgeReset_norposedgeCLK)

begin

?

if(Reset_n==1'b0)

?

?

?

?

INIT<=1'b1;

?

elseif(CSTATE==4'b0101)

?

?

?

?

?

?

?

INIT<=#11'b0;

end

//Thisstatemachineisset-uptoread/writedatatoanAT24C02A

//serialFlashmemory

//这个状态机是建立AT24C02A<"cblue""title="串行闪存">串行闪存的数据读写

//Atpower-up,theINITbitisset,andthestatemachineexecutes

//a'sequencialread'operationstartingataddress0x000and

//proceddinguntilall256byteshavebeenreadandforwardedinto

//theinternalmemoryblock.Thestatemachinethensendsa

//stopbittotheFlashandclearstheINITcontrolbit.

//

//在<"cblue""title="上电">上电时,INIT被设置为高,状态机从地址0x000开始执行“连续读”操作,

//一直进行下去直到所有的256字节都被读,然后向前到内部存储区,

//状态机然后给FLASH发送一个停止位并且清除INIT控制位。

//Thestatemachinethenwaitsforupdttobeset.

//Whentheupdtbitisset,theinterfaceassertsu_enblowona

//falling-edgeofclkandaddr/dataislatched?

onthenextfallingedge

//(rd_clkshouldbeontherising-edge).?

Thestatemachinewrites

//datatotheexternalFLASHmemoryonebyteatatimewhenever

//updtisassertedhigh.?

IftheFIFOremains'notempty'thenthis

//blockwillpolltheNVMuntilitisready,andthenproceedwith

//awritecycleforthenextbyte.

//状态机一直等待UPDT被置为高。

当updt比特被置成高,当clk下降沿时,接口把u_enb设成低

//(rd_clk应该在上升沿)。

这个状态机每次updt为高时就写一个字节数据到外部闪存。

//如果FIFO保持“非空”,则这个块会一直等到它准备好,然后在接下来的比特进行一个写周期。

//StateMachine:

//

//0000-resetstate:

?

?

generateastartbitandload0xA0command

//0001-sendbyte:

?

?

?

?

thenload0x00address

//0010-sendbyte:

?

?

?

?

generateastartbitandload0xA1command

//0011-sendbyte:

?

?

?

?

clearbytecount

//0100-receivebyte:

?

ifcnt/=FF:

ack,cnt++,goto0004else:

nack

//0101-stop:

?

?

?

?

?

?

?

?

?

assertstopbitandloopuntilupdt=1-then

//?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

generateastartbitandloadA0

//0110-sendbyte:

?

?

?

?

sendbyte-ifnack-goto0101,elseloadAddress

//0111-sendbyte:

?

?

?

?

senddatabyte,loaddata

//1000-sendbyte:

?

?

?

?

goto0101

//

//Inpractice,thestatemachineisjustacounterthatstartsatzero

//andcountsup,thenjumpsbackto101andcountsupagain,

//returningtozeroonlywhenreset_nisassertedlow.

//在练习中,状态机只是一个从0开始计数的计数器,加起来,然后跳到101,再重新计数,

//只有到reset_n被置为低时才返回到0。

assignSTEN=(BCNT[3]==1'b1&&

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

(CSTATE[2]!

=1'b1||CSTATE[2:

1]==2'b11||

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

CSTATE[3]?

==1'b1||(CSTATE==4'b0100&&CCNT==8'b11111111)||

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

(CSTATE==4'b0101&&UPDT==1'b1)))?

1'b1:

1'b0;

always@(negedgeReset_nornegedgeCLK)

begin

?

if(Reset_n==1'b0)?

?

?

?

?

CSTATE<=4'b0000;

?

else

?

begin

?

if(STEN==1'b1&&BTCK==1'b0)

?

?

?

?

?

?

?

begin

?

?

?

?

?

?

?

?

if(CSTATE<4'b0101&&NACK==1'b1)

?

?

?

?

?

?

?

?

?

?

CSTATE<=#14'b0000;

?

?

?

?

?

?

?

end

?

?

else

?

?

?

?

?

?

?

begin

?

?

?

?

?

?

?

if(CSTATE[3]==1'b1||NACK==1'b1)

?

?

?

?

?

?

?

?

?

CSTATE<=#14'b0101;

?

?

?

?

?

?

?

else

?

?

?

?

?

?

?

?

?

CSTATE<=#1CSTATE+1'b1;

?

?

?

?

?

?

?

end

?

end

end

//Thebitcounter(BCNT)isclearedatthestatetransition

//andduringthefirstcycleofstate'0011'(forstartbit).

//incrementedonthefalling-edgeofclkwhenBTCKislow.

//比特计数器在过渡状态时和在状态“0011”(起始比特)<"cblue""title="第一个">第一个循环期间被清空。

//在clk下降沿并且BTCK为低电平时,比特计数器增加。

always@(negedgeReset_nornegedgeCLK)

begin

?

if(Reset_n==1'b0)

?

?

?

?

begin

?

?

?

?

BCNT<=4'b0000;

?

?

?

?

DLY?

<=1'b0;

?

?

?

?

end

?

else

?

?

?

begin

?

?

?

?

if(BTCK==1'b0)

?

?

?

?

?

?

begin

?

?

?

?

?

?

if(BCNT[3]==1'b1&&CSTATE==4'b0010)

?

?

?

?

?

?

?

?

?

DLY<=#11'b1;

?

?

?

?

?

?

else

?

?

?

?

?

?

?

?

?

DLY<=1'b0;

?

?

?

?

?

?

?

?

?

?

?

?

if(BCNT[3]==1'b1||(CSTATE==4'b0011&&DLY==1'b1))

?

?

?

?

?

?

?

?

?

BCNT<=#14'b0000;

?

?

?

?

?

?

else

?

?

?

?

?

?

?

?

?

BCNT<=#1BCNT+1'b1;

?

?

?

?

?

?

end

?

?

?

?

?

?

end

end

//Thebytecounter(CCNT)isclearedinstate0011.

//字节计数器在状态0011时被清零。

//ItisincrementedduringtheACKbitaftereach

//bytetransferinstate0100tocount0x00-0xFFbytes

//astheyarereadfromtheNVM.?

ccntisusedbothas

//acontrolsignalandastheiaddroutput.

assignD2I=(BTCK==1'b1&&BCNT[3]==1'b1&&CSTATE==4'b0100)?

1'b1:

1'b0;

?

?

?

?

?

?

?

?

?

?

always@(negedgeReset_nornegedgeCLK)

begin

?

if(Reset_n==1'b0)

?

?

begin

?

?

?

?

CCNT<=8'b0;

?

?

?

?

D2?

?

<=1'b0;

?

?

end

?

else

?

?

begin

?

?

?

?

D2<=#1D2I;

?

?

?

?

if(CSTATE==4'b0011)

?

?

?

?

?

?

?

CCNT<=#18'b0;

?

?

?

?

elseif(D2==1'b1)

?

?

?

?

?

?

?

CCNT<=#1CCNT+1'b1;

?

?

?

?

end

end

//thefollowinglogiccheckstheACKbitforallstatesexcept

//states'0100'and'0101'andassertsNACKifthedatapinis

//highduringthe9thbitofanytransfer.?

Thisisregistered

//sothatthevalueispresentduringstatechanges.

assignNKI=(BCNT[3]==1'b1&&CSTATE!

=4'b0100&&CSTATE!

=4'b0101&&SDI==1'b1)?

1'b1:

1'b0;

always@(negedgeReset_norposedgeCLK)

begin

?

if(Reset_n==1'b0)

?

?

?

?

NACK<=1'b0;

?

elseif(BTCK==1'b1)

?

?

?

?

NACK<=#1NKI;

end

//Writeenablesareclearedto1atpower-upandareassertedlowduring

//ACKinstate0100.

assignWRI=(CSTATE==4'b0100&&BCNT[3]==1'b1&&BTCK==1'b1)?

1'b0:

1'b1;

always@(negedgeReset_nornegedgeCLK)

begin

?

if(Reset_n==1'b0)

?

?

?

?

IENB<=1'b1;

?

else

?

?

?

?

IENB<=#1WRI;

end

assignIADDR=CCNT[7:

0];?

?

/*usebytecountasaddress*/

assignIDATA=SDATA[8:

1];?

/*accountforACKbit*/

assignICLK=!

BTCK;?

?

?

?

?

?

?

?

?

?

/*invertBTCKandusetherising-edgeofthissignalas*/

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

/*thewriteclockintointernalSRAM*/

//UENBisclearedto1atpower-upandisassertedlowinstate0111

//UEUB在上电时被清到1,在0111状态当BCNT=7和BTCK=1时被置为低.

//whileBCNT=7andBTCK=1.?

Itisclockedonthefalling-edge

//ofCLKsoRD_CLKshouldoccurontherising-edge.

assignRDI=(CSTATE==4'b0111&&BCNT==4'b0111?

&&BTCK==1'b1)?

0:

1;

always@(negedgeReset_nornegedgeCLK)

begin

?

if(Reset_n==1'b0)

?

?

?

?

UENB?

<=1'b1;

?

else

?

?

?

?

UENB<=#1RDI;

?

end

//Thevaluethatgetsloadedintosdataisdetermined

//bywhichstatewe'reexiting...

//这个装载到sdata里的值由从哪个状态退出来决定

always@(CSTATEorUDATAorUADDR)

begin

?

case(CSTATE)

?

?

?

4'b0000:

?

BYTE=9'b101000001;/*A0*/

?

?

?

4'b0010:

?

BYTE=9'b101000011;/*A1*/

?

?

?

4'b0101:

?

BYTE=9'b101000001;/*A0*/

?

?

?

4'b0110:

?

BYTE={UADDR,1'b1};

?

?

?

4'b0111:

?

BYTE={UDATA,1'b1};

?

?

?

default:

?

BYTE=9'b000000001;/*0001,0011*/

?

endcase

end

//Thedataregisteris9bitslong(BYTEandACKbit)

//ItisparallelloadedduringtheACKcycleinstates

//0000,0001,0010,0011,0101,0110,and0111;

//这个数据寄存器为9比特长(一个字节加一个ACK位)

//在状态0000,0001,0010,0101,0110和0111状态的ACK循环时,这些都是平行<"cblue""title="加载">加载的。

assignLD_BYTE=(BCNT[3]==1'b1&&BTCK==1'b0&&CSTATE!

=4'b0100&&CSTATE[3]==1'b0)?

1'b1:

1'b0;

always@(negedgeReset_nornegedgeCLK)

begin

?

if(Reset_n==1'b0)

?

?

?

?

SDATA<=9'b111111111;

?

else

?

?

?

?

begin

?

?

?

?

if(LD_BYTE==1'b1)

?

?

?

?

?

?

?

SDATA<=#1BYTE;

?

?

?

?

elseif((CSTATE!

=4'b0101&&CSTATE!

=4'b0100&&BTCK==1'b0&&DLY==1'b0)||

?

?

?

?

?

?

?

?

?

?

(CSTATE==4'b0100&&BTCK==1'b1))

?

?

?

?

?

?

?

?

?

?

?

SDATA<=#1{SDATA[7:

0],SDI};

?

?

?

?

end

end

//Startbits(datafallingwhileBTCKishigh)aregeneratedas

//weexitstates0000,0010,and0101;stopbits(datarising

//whileBTCKishigh)aregeneratedasweenterstate0101.

//ThisisdonewiththeSTSPsignal.

//起始位(数据下降当BTCK为高)产生于退出状态0000,0010和0101时;

//停止位(数据上升当BTCK为高)产生于进入状态0101时。

//这些由STSP信号完成

always@(negedgeReset_nornegedg

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 营销活动策划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1