新闻  |   论坛  |   博客  |   在线研讨会
EEPROM的Verilog HDL程序
chen3bing | 2024-06-20 19:09:25    阅读:29   发布文章

代码:

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	    
  endmodule

EEPROM_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
endmodule

Signal.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

endmodule

Top.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));  
 
endmodule

addr.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.jpg

2.jpg

地址1,数据1

3.jpg

写信号拉高

4.jpg

地址10,数据10


5.jpg

写信号拉高

6.jpg地址16,数据16,写信号拉高

7.jpg读信号拉高

8.jpg

读出数据1

9.jpg第16个数据

10.jpg读出第16个数据


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

参与讨论
登录后参与讨论
1
最近文章
方波振荡电路
2024-09-14 14:59:39
6V3A电路
2024-09-14 14:18:10
推荐文章
最近访客