【求教】eeprom行为模块的问题

2019-07-16 01:14发布

菜鸟一个,最近正在看夏宇闻的书,看到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
  //-------------------------------
二楼放图

QQ截图20131005190650.png
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
混血王子傻瓜
1楼-- · 2019-07-16 01:23
图有了,第一次启动的时候正常,结束前有一个高阻的毛刺,不明白是怎么回事,在第二次启动的时候,控制字节就出问题了,求教················
混血王子傻瓜
2楼-- · 2019-07-16 03:46
 精彩回答 2  元偷偷看……
混血王子傻瓜
3楼-- · 2019-07-16 05:53
兄弟们························,手贱把源程序作了下修改,就成这样了·····················

一周热门 更多>