"); //-->
代码:
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个数据
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
电路引脚及主要特性PS2402 带复位电路的EEPROM
EEPROM三重测试
新系列串口EEPROM内置唯一ID码,适合设备识别、溯源和可持续性应用
复旦微电推出NAND Flash及EEPROM存储器新品
富士通电子将自9月推出业内最高密度8Mbit ReRAM产品
电路引脚及主要特性DS1867 带EEPROM的双数字电位器
AT93C46or56or55串行EEPROM及单片机程序
第25讲 FLASH模拟EEPROM实验
请教个 串行 eeprom
EEPROM和PCI9052的连接电路图
全面理解非易失存储器(Flash,EPROM,EEPROM)
谁在at91rm9200上用过eeprom?
MSPM0在指定Flash地址开辟模拟EEPROM
语音合成芯片VP-1000和EEPROM相连只作放音的电路图
[推荐]51 flash文件系统DIY___I2C EEPROM的读写(2)
富士通电子推出能在苛刻环境正常工作的SPI 2Mbit FRAM
求助i2c,eeprom工作原理,小弟要用软件模拟一个i2c控制器?
数据保存期限100年,安森美新款EEPROM是如何做到的?
复旦微电子推出低功耗超宽电压I2C串行EEPROM
EEPROM 和 flash 这样讲,早就懂了!
avr eeprom保护方法.
意法半导体推出Page EEPROM二合一存储器提升智能边缘设备的性能和能效
并口读写EEPROM
器件资料\\at24c01a
“andery88”的基于IICA0的EEPROM读写视频
AT93C46 56 55串行EEPROM及单片机程序
电路引脚及主要特性PS9346 带复位电路的EEPROM
PIC12C67X