菜鸟一个,最近正在看夏宇闻的书,看到I2C总线那里,在编写eeprom的行为模块这出问题了,求大家解答,下面是我的源程序
`
timescale 1ns/1ns
`define timeslice 100
module EEPROM(scl,sda); //eeprom行为模型
input scl;
inout sda;
reg out_flag; //sda数据输出的控制信号
reg [7:0] address; //地址寄存器
reg [7:0] ctrlbyte; //控制字寄存器
reg [7:0] datain; //输入数据字节寄存器
reg [7:0] dataout; //输出数据字节寄存器
reg [7:0] memory[2047:0]; //模拟eeprom存储器
reg [1:0]state; //状态寄存器
reg [7:0] shift; //任务数据寄存器
reg [10:0] mem_ads; //存储器总地址
integer i;
//----------端口赋值-----------
assign sda=(out_flag==1)?dataout[7]:1'bz; //这里把高阻改成1,仍然可以分析
//--------初始化------------
initial
begin
address=0;ctrlbyte=0;
datain=0;state=2'b00;
shift=0;dataout=0;
out_flag=0;mem_ads=0;
for(i=0;i<2048;i=i+1)
memory[i]=0;
end
//-----------------------
//-------启动信号------------
always@(negedge sda)
if(scl==1)
begin
shift_in(ctrlbyte); //做接口验证时只用这一个器件模型,故不对ctrlbyte的其他字节进行验证
if(ctrlbyte[0]==0)
begin
shift_in(address);
state=2'b01; //写入数据
end
else
begin
state=2'b10; //读出数据
disable write;
end
end
//--------------------------
//------读写过程------------
always @(posedge sda)
if(scl==1)
stop;
else
begin
casex(state)
2'b01:begin
write;
mem_ads=mem_ads+1;
if (mem_ads>2047) mem_ads=0; //地址超过2k,自动回到前边覆盖
end
2'b10:begin
read;
mem_ads=mem_ads+1;
if (mem_ads>2047) mem_ads=0;
end
default:state=2'b00;
endcase
end //主状态机结束
//---------------------------
//------停止信号-------------
task stop;
begin
state=2'b00;
address=0;
ctrlbyte=0;
datain=0;
dataout=0;
out_flag=0;
mem_ads=0;
end
endtask
//--------------------------
//-------写入数据操作-----------------
task write;
begin
shift_in(datain);
mem_ads={ctrlbyte[3:1],address};
memory[mem_ads]=datain;
//address=address+1;
//if (address>2047) address=0; //地址超过2k,自动回到前边覆盖
end
endtask
//------------------------------
//--------读出数据操作-----------------
task read;
begin
mem_ads={ctrlbyte[3:1],address};
dataout=memory[mem_ads];
shift_out;
//address=address+1;
//if (address>2047) address=0;
end
endtask
//------------------------------
//------读进数据线上的一个字节并应答----------
task shift_in;
output [7:0] shift;
begin
@ (posedge scl) shift[7]=sda;
@ (posedge scl) shift[6]=sda;
@ (posedge scl) shift[5]=sda;
@ (posedge scl) shift[4]=sda;
@ (posedge scl) shift[3]=sda;
@ (posedge scl) shift[2]=sda;
@ (posedge scl) shift[1]=sda;
@ (posedge scl) shift[0]=sda;
@ (negedge scl)
begin
#`timeslice;
dataout=0;
out_flag=1;
end
@ (negedge scl)
#`timeslice out_flag=0;
end
endtask
//-------------------------------
//------内容输出到数据线上----------
task shift_out;
begin
out_flag=1;
for(i=6;i>=0;i=i-1)
@ (negedge scl) #`timeslice dataout=dataout<<1;
@ (negedge scl) #`timeslice dataout[7]=1; //非应答,换成高阻也可以分析
@ (negedge scl) #`timeslice out_flag=0;
end
endtask
endmodule
//-------------------------------
二楼放图
-
一周热门 更多>