"); //-->
代码:
EEPROM.V
`timescale 1ns/1ns
`define timeslice 100
module EEPROM(scl, sda);
input scl; //串行时钟线
inout sda; //串行数据线
reg out_flag; //SDA数据输出的控制信号
reg[7:0] memory[2047:0];
reg[10:0] address;
reg[7:0] memory_buf;
reg[7:0] sda_buf; //SDA 数据输出寄存器
reg[7:0] shift; //SDA 数据输入寄存器
reg[7:0] addr_byte; //EEPROM 存储单元地址寄存器
reg[7:0] ctrl_byte; //控制字寄存器
reg[1:0] State; //状态寄存器
integer i;
//--------------------------------------------------------------
parameter r7= 8'b10101111,w7= 8'b10101110, //main7
r6= 8'b10101101,w6= 8'b10101100, //main6
r5= 8'b10101011,w5= 8'b10101010, //main5
r4= 8'b10101001,w4= 8'b10101000, //main4
r3= 8'b10100111,w3= 8'b10100110, //main3
r2= 8'b10100101,w2= 8'b10100100, //main2
r1= 8'b10100011,w1= 8'b10100010, //main1
r0= 8'b10100001,w0= 8'b10100000; //main0
//--------------------------------------------------------------
assign sda = (out_flag == 1) ? sda_buf[7] : 1'bz;
//----------寄存器和存储器初始化---------
initial
begin
addr_byte = 0;
ctrl_byte = 0;
out_flag = 0;
sda_buf = 0;
State = 2'b00;
memory_buf = 0;
address = 0;
shift = 0;
for(i=0;i<=2047;i=i+1)
memory[i]=0;
end
//------------ 启动信号 -----------------------------
always @ (negedge sda)
if(scl == 1 )
begin
State = State + 1;
if(State == 2'b11)
disable write_to_eeprm;
end
//------------ 主状态机 --------------------------
always @(posedge sda)
if (scl == 1 ) //停止操作
stop_W_R;
else
begin
casex(State)
2'b01:
begin
read_in;
if(ctrl_byte==w7||ctrl_byte==w6||ctrl_byte==w5
||ctrl_byte==w4||ctrl_byte==w3||ctrl_byte==w2
||ctrl_byte==w1||ctrl_byte==w0)
begin
State = 2'b10;
write_to_eeprm; //写操作
end
else
State = 2'b00;
end
2'b11:
read_from_eeprm; //读操作
default:
State=2'b00;
endcase
end //主状态机结束
//------------- 操作停止------------------------------
task stop_W_R;
begin
State =2'b00; //状态返回为初始状态
addr_byte = 0;
ctrl_byte = 0;
out_flag = 0;
sda_buf = 0;
end
endtask
//------------- 读进控制字和存储单元地址 ------------------------
task read_in;
begin
shift_in(ctrl_byte);
shift_in(addr_byte);
end
endtask
//------------EEPROM 的写操作---------------------------------------
task write_to_eeprm;
begin
shift_in(memory_buf);
address = {ctrl_byte[3:1],addr_byte};
memory[address] = memory_buf;
$display("eeprm----memory[%0h]=%0h",address,memory[address]);
State =2'b00; //回到0状态
end
endtask
//-----------EEPROM 的读操作----------------------------------------
task read_from_eeprm;
begin
shift_in(ctrl_byte);
if(ctrl_byte==r7||ctrl_byte==r6||ctrl_byte==r5||ctrl_byte==r4
||ctrl_byte==r3||ctrl_byte==r2||ctrl_byte==r1||ctrl_byte==r0)
begin
address = {ctrl_byte[3:1],addr_byte};
sda_buf = memory[address];
shift_out;
State= 2'b00;
end
end
endtask
//-----SDA 数据线上的数据存入寄存器,数据在SCL的高电平有效-------------
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 ;
out_flag = 1; //应答信号输出
sda_buf = 0;
end
@(negedge scl)
#`timeslice out_flag = 0;
end
endtask
//----EEPROM 存储器中的数据通过SDA 数据线输出,数据在SCL 低电平时变化
task shift_out;
begin
out_flag = 1;
for(i=6;i>=0;i=i-1)
begin
@ (negedge scl);
#`timeslice;
sda_buf = sda_buf<<1;
end
@(negedge scl) #`timeslice sda_buf[7] = 1; //非应答信号输出
@(negedge scl) #`timeslice out_flag = 0;
end
endtask
endmoduleEEPROM_WR.v
`timescale 1ns/1ns
module EEPROM_WR(SDA,SCL,ACK,RESET,CLK,WR,RD,ADDR,DATA);
output SCL; //涓茶鏃堕挓绾output ACK; //璇诲啓涓€涓懆鏈熺殑搴旂瓟淇″彿
input RESET; //澶嶄綅淇″彿
input CLK; //鏃堕挓淇″彿杈撳叆
input WR,RD; //璇诲啓淇″彿
input[10:0] ADDR; //鍦板潃绾inout SDA; //涓茶鏁版嵁绾inout[7:0] DATA; //骞惰鏁版嵁绾reg ACK;
reg SCL;
reg WF,RF; //璇诲啓鎿嶄綔鏍囧織
reg FF; //鏍囧織瀵勫瓨鍣reg [1:0] head_buf; //鍚姩淇″彿瀵勫瓨鍣reg[1:0] stop_buf; //鍋滄淇″彿瀵勫瓨鍣
reg [7:0] sh8out_buf; //EEPROM鍐欏瘎瀛樺櫒
reg [8:0] sh8out_state; //EEPROM 鍐欑姸鎬佸瘎瀛樺櫒
reg [9:0] sh8in_state; //EEPROM 璇荤姸鎬佸瘎瀛樺櫒
reg [2:0] head_state; //鍚姩鐘舵€佸瘎瀛樺櫒
reg [2:0] stop_state; //鍋滄鐘舵€佸瘎瀛樺櫒
reg [10:0] main_state; //涓荤姸鎬佸瘎瀛樺櫒
reg [7:0] data_from_rm; //EEPROM璇诲瘎瀛樺櫒
reg link_sda; //SDA 鏁版嵁杈撳叆EEPROM寮€鍏
reg link_read; //EEPROM璇绘搷浣滃紑鍏
reg link_head; //鍚姩淇″彿寮€鍏reg link_write; //EEPROM鍐欐搷浣滃紑鍏reg link_stop; //鍋滄淇″彿寮€鍏
wire sda1,sda2,sda3,sda4;
//--------------涓茶鏁版嵁鍦ㄥ紑鍏崇殑鎺у埗涓嬫湁娆″簭鐨勮緭鍑烘垨杈撳叆-------------------
assign sda1 = (link_head) ? head_buf[1] : 1'b0;
assign sda2 = (link_write) ? sh8out_buf[7] : 1'b0;
assign sda3 = (link_stop) ? stop_buf[1] : 1'b0;
assign sda4 = (sda1 | sda2 | sda3);
assign SDA = (link_sda) ? sda4 : 1'bz;
assign DATA = (link_read) ? data_from_rm : 8'hzz;
//--------------------------------涓荤姸鎬佹満鐘舵€佸畾涔-----------------------------------------
parameter
Idle = 11'b00000000001,
Ready = 11'b00000000010,
Write_start = 11'b00000000100,
Ctrl_write = 11'b00000001000,
Addr_write = 11'b00000010000,
Data_write = 11'b00000100000,
Read_start = 11'b00001000000,
Ctrl_read = 11'b00010000000,
Data_read = 11'b00100000000,
Stop = 11'b01000000000,
Ackn = 11'b10000000000,
//-------------------------骞惰鏁版嵁涓茶杈撳嚭鐘舵€----------------------------
sh8out_bit7 = 9'b000000001,
sh8out_bit6 = 9'b000000010,
sh8out_bit5 = 9'b000000100,
sh8out_bit4 = 9'b000001000,
sh8out_bit3 = 9'b000010000,
sh8out_bit2 = 9'b000100000,
sh8out_bit1 = 9'b001000000,
sh8out_bit0 = 9'b010000000,
sh8out_end = 9'b100000000;
//--------------------------涓茶鏁版嵁骞惰杈撳嚭鐘舵€---------------------------
parameter sh8in_begin = 10'b0000000001,
sh8in_bit7 = 10'b0000000010,
sh8in_bit6 = 10'b0000000100,
sh8in_bit5 = 10'b0000001000,
sh8in_bit4 = 10'b0000010000,
sh8in_bit3 = 10'b0000100000,
sh8in_bit2 = 10'b0001000000,
sh8in_bit1 = 10'b0010000000,
sh8in_bit0 = 10'b0100000000,
sh8in_end = 10'b1000000000,
//---------------------------------鍚姩鐘舵€---------------------------------
head_begin = 3'b001,
head_bit = 3'b010,
head_end = 3'b100,
//---------------------------------鍋滄鐘舵€---------------------------------
stop_begin = 3'b001,
stop_bit = 3'b010,
stop_end = 3'b100;
parameter YES = 1,
NO = 0;
//-------------浜х敓涓茶鏃堕挓scl锛屼负杈撳叆鏃堕挓鐨勪簩鍒嗛-------------------
always @(negedge CLK)
if(RESET)
SCL <= 0;
else
SCL <= ~SCL;
//-----------------------------涓荤姸鎬佹満绋嬪簭----------------------------------
always @ (posedge CLK)
if(RESET)
begin
link_read <= NO;
link_write <= NO;
link_head <= NO;
link_stop <= NO;
link_sda <= NO;
ACK <= 0;
RF <= 0;
WF <= 0;
FF <= 0;
main_state <= Idle;
end
else
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 <= 1;
main_state <= Ready ;
end
else if(RD)
begin
RF <= 1;
main_state <= Ready ;
end
else
begin
WF <= 0;
RF <= 0;
main_state <= Idle;
end
end
Ready:
begin
link_read <= NO;
link_write <= NO;
link_stop <= NO;
link_head <= YES;
link_sda <= YES;
head_buf[1:0] <= 2'b10;
stop_buf[1:0] <= 2'b01;
head_state <= head_begin;
FF <= 0;
ACK <= 0;
main_state <= Write_start;
end
Write_start:
if(FF == 0)
shift_head;
else
begin
sh8out_buf[7:0] <= {1'b1,1'b0,1'b1,1'b0,ADDR[10:8],1'b0};
link_head <= NO;
link_write <= YES;
FF <= 0;
sh8out_state <= sh8out_bit6;
main_state <= Ctrl_write;
end
Ctrl_write:
if(FF ==0)
shift8_out;
else
begin
sh8out_state <= sh8out_bit7;
sh8out_buf[7:0] <= ADDR[7:0];
FF <= 0;
main_state <= Addr_write;
end
Addr_write:
if(FF == 0)
shift8_out;
else
begin
FF <= 0;
if(WF)
begin
sh8out_state <= sh8out_bit7;
sh8out_buf[7:0] <= DATA;
main_state <= Data_write;
end
if(RF)
begin
head_buf <= 2'b10;
head_state <= head_begin;
main_state <= Read_start;
end
end
Data_write:
if(FF == 0)
shift8_out;
else
begin
stop_state <= stop_begin;
main_state <= Stop;
link_write <= NO;
FF <= 0;
end
Read_start:
if(FF == 0)
shift_head;
else
begin
sh8out_buf <= {1'b1,1'b0,1'b1,1'b0,ADDR[10:8],1'b1};
link_head <= NO;
link_sda <= YES;
link_write <= YES;
FF <= 0;
sh8out_state <= sh8out_bit6;
main_state <= Ctrl_read;
end
Ctrl_read:
if(FF == 0)
shift8_out;
else
begin
link_sda <= NO;
link_write <= NO;
FF <= 0;
sh8in_state <= sh8in_begin;
main_state <= Data_read;
end
Data_read:
if(FF == 0)
shift8in;
else
begin
link_stop <= YES;
link_sda <= YES;
stop_state <= stop_bit;
FF <= 0;
main_state <= Stop;
end
Stop:
if(FF == 0)
shift_stop;
else
begin
ACK <= 1;
FF <= 0;
main_state <= Ackn;
end
Ackn:
begin
ACK <= 0;
WF <= 0;
RF <= 0;
main_state <= Idle;
end
default: main_state <= Idle;
endcase
end
//------------------------涓茶鏁版嵁杞崲涓哄苟琛屾暟鎹换鍔---------------------------------
task shift8in;
begin
casex(sh8in_state)
sh8in_begin:
sh8in_state <= sh8in_bit7;
sh8in_bit7: if(SCL)
begin
data_from_rm[7] <= SDA;
sh8in_state <= sh8in_bit6;
end
else
sh8in_state <= sh8in_bit7;
sh8in_bit6: if(SCL)
begin
data_from_rm[6] <= SDA;
sh8in_state <= sh8in_bit5;
end
else
sh8in_state <= sh8in_bit6;
sh8in_bit5: if(SCL)
begin
data_from_rm[5] <= SDA;
sh8in_state <= sh8in_bit4;
end
else
sh8in_state <= sh8in_bit5;
sh8in_bit4: if(SCL)
begin
data_from_rm[4] <= SDA;
sh8in_state <= sh8in_bit3;
end
else
sh8in_state <= sh8in_bit4;
sh8in_bit3: if(SCL)
begin
data_from_rm[3] <= SDA;
sh8in_state <= sh8in_bit2;
end
else
sh8in_state <= sh8in_bit3;
sh8in_bit2: if(SCL)
begin
data_from_rm[2] <= SDA;
sh8in_state <= sh8in_bit1;
end
else
sh8in_state <= sh8in_bit2;
sh8in_bit1: if(SCL)
begin
data_from_rm[1] <= SDA;
sh8in_state <= sh8in_bit0;
end
else
sh8in_state <= sh8in_bit1;
sh8in_bit0: if(SCL)
begin
data_from_rm[0] <= SDA;
sh8in_state <= sh8in_end;
end
else
sh8in_state <= sh8in_bit0;
sh8in_end: if(SCL)
begin
link_read <= YES;
FF <= 1;
sh8in_state <= sh8in_bit7;
end
else
sh8in_state <= sh8in_end;
default: begin
link_read <= NO;
sh8in_state <= sh8in_bit7;
end
endcase
end
endtask
//------------------------------ 骞惰鏁版嵁杞崲涓轰覆琛屾暟鎹换鍔---------------------------
task shift8_out;
begin
casex(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;
link_write <= YES;
sh8out_state <= sh8out_bit5;
sh8out_buf <= sh8out_buf<<1;
end
else
sh8out_state <= sh8out_bit6;
sh8out_bit5:
if(!SCL)
begin
sh8out_state <= sh8out_bit4;
sh8out_buf <= sh8out_buf<<1;
end
else
sh8out_state <= sh8out_bit5;
sh8out_bit4:
if(!SCL)
begin
sh8out_state <= sh8out_bit3;
sh8out_buf <= sh8out_buf<<1;
end
else
sh8out_state <= sh8out_bit4;
sh8out_bit3:
if(!SCL)
begin
sh8out_state <= sh8out_bit2;
sh8out_buf <= sh8out_buf<<1;
end
else
sh8out_state <= sh8out_bit3;
sh8out_bit2:
if(!SCL)
begin
sh8out_state <= sh8out_bit1;
sh8out_buf <= sh8out_buf<<1;
end
else
sh8out_state <= sh8out_bit2;
sh8out_bit1:
if(!SCL)
begin
sh8out_state <= sh8out_bit0;
sh8out_buf <= sh8out_buf<<1;
end
else
sh8out_state <= sh8out_bit1;
sh8out_bit0:
if(!SCL)
begin
sh8out_state <= sh8out_end;
sh8out_buf <= sh8out_buf<<1;
end
else
sh8out_state <= sh8out_bit0;
sh8out_end:
if(!SCL)
begin
link_sda <= NO;
link_write <= NO;
FF <= 1;
end
else
sh8out_state <= sh8out_end;
endcase
end
endtask
//--------------------------- 杈撳嚭鍚姩淇″彿浠诲姟 ---------------------------------
task shift_head;
begin
casex(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 <= 1;
head_buf <= head_buf<<1;
head_state <= head_end;
end
else
head_state <= head_bit;
head_end:
if(!SCL)
begin
link_head <= NO;
link_write <= YES;
end
else
head_state <= head_end;
endcase
end
endtask
//--------------------------- 杈撳嚭鍋滄淇″彿浠诲姟 --------------------------------------
task shift_stop;
begin
casex(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_buf<<1;
stop_state <= stop_end;
end
else
stop_state<= stop_bit;
stop_end: if(!SCL)
begin
link_head <= NO;
link_stop <= NO;
link_sda <= NO;
FF <= 1;
end
else
stop_state <= stop_end;
endcase
end
endtask
endmoduleSignal.v
`timescale 1ns/1ns
`define timeslice 200
module Signal(RESET,CLK,RD,WR,ADDR,ACK,DATA);
output RESET; //复位信号
output CLK; //时钟信号
output RD,WR; //读写信号
output[10:0] ADDR; //11位地址信号
input ACK; //读写周期的应答信号
inout[7:0] DATA; //数据线
reg RESET;
reg CLK;
reg RD,WR;
reg W_R; //低位:写操作;高位:读操作
reg[10:0] ADDR;
reg[7:0] data_to_eeprom;
reg[10:0] addr_mem[0:255];
reg[7:0] data_mem[0:255];
reg[7:0] ROM[0:2047];
integer i,j;
integer OUTFILE;
assign DATA = (W_R) ? 8'bz : 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(15) //连续写15次数据,调试成功后可以增加到全部地址覆盖测试
begin
# (5 * `timeslice);
WR = 1;
# (`timeslice);
WR = 0;
@ (posedge ACK); //EEPROM_WR转换模块请求写数据
end
#(10 * `timeslice);
W_R = 1; //开始读操作
repeat(15) //连续读15次数据
begin
# (5 * `timeslice);
RD = 1;
# ( `timeslice );
RD = 0;
@ (posedge ACK); //EEPROM_WR转换模块请求读数据
end
end
//-----------------------------------------写操作-----------------------------
initial
begin
$display("writing-----writing-----writing-----writing");
# (2*`timeslice);
for(i=0;i<=15;i=i+1)
begin
ADDR = addr_mem[i]; //输出写操作的地址
data_to_eeprom = data_mem[i]; //输出需要转换的平行数据
$fdisplay(OUTFILE,"@%0h %0h",ADDR, data_to_eeprom);
//把输出的地址和数据记录在已经打开的eeprom.dat文件中
@(posedge ACK) ; //EEPROM_WR转换模块请求写数据
end
end
//----------------------------------------读操作----------------------------
initial
@(posedge W_R)
begin
ADDR = addr_mem[0];
$fclose (OUTFILE); //关闭已经打开的eeprom.dat文件
$readmemh("./eeprom.dat",ROM); //把数据文件的数据读到ROM中
$display("Begin READING-----READING-----READING-----READING");
for(j = 0; j <= 15; j = j+1)
begin
ADDR = addr_mem[j];
@(posedge ACK);
if(DATA == ROM[ADDR]) //比较并显示发送的数据和接收到的数据是否一致
$display("DATA %0h == ROM[%0h]---READ RIGHT",DATA,ADDR);
else
$display("DATA %0h != ROM[%0h]---READ WRONG",DATA,ADDR);
end
end
initial
begin
OUTFILE = $fopen("./eeprom.dat"); // 打开一个名为eeprom.dat的文件备用
$readmemh("./addr.dat",addr_mem); // 把地址数据存入地址存储器
$readmemh("./data.dat",data_mem); // 把准备写入EEPROM的数据存入数据存储器
end
endmoduleTop.v
`timescale 1ns/1ns
`define timeslice 200
module Signal(RESET,CLK,RD,WR,ADDR,ACK,DATA);
output RESET; //澶嶄綅淇″彿
output CLK; //鏃堕挓淇″彿
output RD,WR; //璇诲啓淇″彿
output[10:0] ADDR; //11浣嶅湴鍧€淇″彿
input ACK; //璇诲啓鍛ㄦ湡鐨勫簲绛斾俊鍙inout[7:0] DATA; //鏁版嵁绾reg RESET;
reg CLK;
reg RD,WR;
reg W_R; //浣庝綅锛氬啓鎿嶄綔锛涢珮浣嶏細璇绘搷浣
reg[10:0] ADDR;
reg[7:0] data_to_eeprom;
reg[10:0] addr_mem[0:255];
reg[7:0] data_mem[0:255];
reg[7:0] ROM[0:2047];
integer i,j;
integer OUTFILE;
assign DATA = (W_R) ? 8'bz : 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(15) //杩炵画鍐5娆℃暟鎹紝璋冭瘯鎴愬姛鍚庡彲浠ュ鍔犲埌鍏ㄩ儴鍦板潃瑕嗙洊娴嬭瘯
begin
# (5 * `timeslice);
WR = 1;
# (`timeslice);
WR = 0;
@ (posedge ACK); //EEPROM_WR杞崲妯″潡璇锋眰鍐欐暟鎹 end
#(10 * `timeslice);
W_R = 1; //寮€濮嬭鎿嶄綔
repeat(15) //杩炵画璇5娆℃暟鎹
begin
# (5 * `timeslice);
RD = 1;
# ( `timeslice );
RD = 0;
@ (posedge ACK); //EEPROM_WR杞崲妯″潡璇锋眰璇绘暟鎹 end
end
//-----------------------------------------鍐欐搷浣----------------------------
initial
begin
$display("writing-----writing-----writing-----writing");
# (2*`timeslice);
for(i=0;i<=15;i=i+1)
begin
ADDR = addr_mem[i]; //杈撳嚭鍐欐搷浣滅殑鍦板潃
data_to_eeprom = data_mem[i]; //杈撳嚭闇€瑕佽浆鎹㈢殑骞宠鏁版嵁
$fdisplay(OUTFILE,"@%0h %0h",ADDR, data_to_eeprom);
//鎶婅緭鍑虹殑鍦板潃鍜屾暟鎹褰曞湪宸茬粡鎵撳紑鐨別eprom.dat鏂囦欢涓 @(posedge ACK) ; //EEPROM_WR杞崲妯″潡璇锋眰鍐欐暟鎹
end
end
//----------------------------------------璇绘搷浣---------------------------
initial
@(posedge W_R)
begin
ADDR = addr_mem[0];
$fclose (OUTFILE); //鍏抽棴宸茬粡鎵撳紑鐨別eprom.dat鏂囦欢
$readmemh("./eeprom.dat",ROM); //鎶婃暟鎹枃浠剁殑鏁版嵁璇诲埌ROM涓
$display("Begin READING-----READING-----READING-----READING");
for(j = 0; j <= 15; j = j+1)
begin
ADDR = addr_mem[j];
@(posedge ACK);
if(DATA == ROM[ADDR]) //姣旇緝骞舵樉绀哄彂閫佺殑鏁版嵁鍜屾帴鏀跺埌鐨勬暟鎹槸鍚︿竴鑷 $display("DATA %0h == ROM[%0h]---READ RIGHT",DATA,ADDR);
else
$display("DATA %0h != ROM[%0h]---READ WRONG",DATA,ADDR);
end
end
initial
begin
OUTFILE = $fopen("./eeprom.dat"); // 鎵撳紑涓€涓悕涓篹eprom.dat鐨勬枃浠跺鐢 $readmemh("./addr.dat",addr_mem); // 鎶婂湴鍧€鏁版嵁瀛樺叆鍦板潃瀛樺偍鍣 $readmemh("./data.dat",data_mem); // 鎶婂噯澶囧啓鍏EPROM鐨勬暟鎹瓨鍏ユ暟鎹瓨鍌ㄥ櫒
end
endmodule
//椤跺眰妯″潡锛/****************************************************************************
妯″潡鍚嶇О锛歍op 鏂囦欢鍚嶏細top.v
妯″潡鍔熻兘锛氱敤浜庢妸浜х敓娴嬭瘯淇″彿鐨勬ā鍧楋紙Signal锛変笌璁捐鐨勫叿浣撴ā鍧楋紙EEPROM_WR锛 浠ュ強EEPROM铏氭嫙妯″潡杩炴帴璧锋潵鐨勬ā鍧楋紝鐢ㄤ簬鍏ㄩ潰娴嬭瘯銆妯″潡璇存槑锛氭湰妯″潡涓鸿涓烘ā鍧楋紝涓嶅彲缁煎悎涓洪棬绾х綉琛ㄣ€備絾鍏朵腑EEPROM_WR鍙互缁煎悎
涓洪棬绾х綉琛紝鎵€浠ュ彲浠ュ鎵€璁捐鐨凟EPROM璇诲啓鍣ㄨ繘琛岄棬绾у悗浠跨湡銆****************************************************************************/
`include "./Signal.v"
`include "./EEPROM.v"
`include "./EEPROM_WR.v" //鍙互鐢‥EPROM_WR妯″潡鐩稿簲鐨刅erilog闂ㄧ骇缃戣〃鏉ユ浛鎹 `timescale 1ns/1ns
module Top;
wire RESET;
wire CLK;
wire RD,WR;
wire ACK;
wire[10:0] ADDR;
wire[7:0] DATA;
wire SCL;
wire SDA;
Signal signal(.RESET(RESET),.CLK(CLK),.RD(RD),
.WR(WR),.ADDR(ADDR),.ACK(ACK),.DATA(DATA));
EEPROM_WR eeprom_wr(.RESET(RESET),.SDA(SDA),.SCL(SCL),.ACK(ACK),
.CLK(CLK),.WR(WR),.RD(RD),.ADDR(ADDR),.DATA(DATA));
EEPROM eeprom(.sda(SDA),.scl(SCL));
endmoduleaddr.dat
@0 1 2 3 4 5 6 7 8 9 0a 0b 0c 0d 0e 0f 10
data.dat
@0 1 2 3 4 5 6 7 8 9 0a 0b 0c 0d 0e 0f 10
仿真波形图


地址1,数据1

写信号拉高

地址10,数据10

写信号拉高
地址16,数据16,写信号拉高
读信号拉高

读出数据1
第16个数据
读出第16个数据
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。