⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2cslave.v

📁 Verilog HDL实现的I2C Slave模拟
💻 V
字号:
各位朋友,以下是我的一个模拟I2C从设备的 verilog代码,但是在maxplux下老是编译不通过,有兴趣的朋友,能否一起探讨一下。联系方式:pjultra@163.com
`timescale 1ns/1ns
`define timeslice 100
module i2c_slave(main_rst_,scl,sda,s_rst,fan_ctrl,fan_alter);
input [2:0] fan_ctrl,fan_alter;
output [7:0] s_rst;
input scl,main_rst_;
inout sda;
reg [7:0] s_rst;
reg out_flag;         //SDA数据输出的控制信号
reg [7:0] memory_buf;
reg [7:0] ctrl_byte;
reg [7:0] addr_byte;
reg [7:0] sda_buf;
reg [7:0] shift;
reg [1:0] state;

parameter  cpld_addr_r=8'b10011001,
           cpld_addr_w=8'b10011000;
parameter  reg1=8'b00000000,reg2=8'b11111111;

//-----------输出SDA-------
assign sda=(out_flag==1)?sda_buf[7]:1'bz;
//----------启动信号-----------
always@(negedge sda or negedge main_rst_) begin
   if(!main_rst_) begin   //--------------寄存器和存储器初始化--------------------
       addr_byte<=0; ctrl_byte<=0; out_flag<=0;
       sda_buf<=0;     memory_buf<=0;
       shift<=0;  s_rst<=1; state<=2'b00;
   end
   else if(scl==1) begin
       state=state&&2'b01;
       if (state==2'b11)
        disable write_to_cpld;
   end
end
//------主机状态------------------
always@(posedge sda or negedge main_rst_)
begin
   if(!main_rst_)begin    //--------------寄存器和存储器初始化--------------------
       addr_byte<=0; ctrl_byte<=0; out_flag<=0;
       sda_buf<=0;     memory_buf<=0;
       shift<=0;  s_rst<=1; state<=2'b00;
   end
   else if(scl==1) begin
      state<=2'b00;
      addr_byte<=0;  
      ctrl_byte<=0;
      out_flag=0;  
      sda_buf=0;
   end
   else begin
       casex(state)
         2'b01:begin
             read_in;
             if(ctrl_byte==cpld_addr_w) begin
                  state=2'b10;
                  write_to_cpld;   //写操作
              end
              else state=2'b00;
         end
         2'b11: read_from_cpld;     //--读操作
         default: state=2'b00;
       endcase
   end  //主状机结束
end
//-------操作停止------------
//----读进控制字和存储器单元地址---------
task read_in;
   begin
     shift_in(ctrl_byte);
     shift_in(addr_byte);
   end
endtask
//------CPLD的写操作-------------------
task write_to_cpld;
    begin
      shift_in(memory_buf);
      if(addr_byte==reg1)
       s_rst=memory_buf;
      else s_rst=8'b11111111;
      state=2'b00; //回到0状态
    end
endtask
//-------CPLD的读操作-----------
task read_from_cpld;
   begin
     shift_in(ctrl_byte);
     if(ctrl_byte==cpld_addr_r)
       begin
          if(addr_byte==reg2);
          sda_buf={fan_ctrl,fan_alter,2'b00};
          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
//------CPLD存储器中的数据通过SDA数据线输出,数据在SCL低电平时变化
task shift_out;
   begin 
      out_flag=1;
      @(negedge scl) #`timeslice sda_buf=sda_buf<<1;
      @(negedge scl) #`timeslice sda_buf=sda_buf<<1;
      @(negedge scl) #`timeslice sda_buf=sda_buf<<1;
      @(negedge scl) #`timeslice sda_buf=sda_buf<<1;
      @(negedge scl) #`timeslice sda_buf=sda_buf<<1;
      @(negedge scl) #`timeslice sda_buf=sda_buf<<1;
      @(negedge scl) #`timeslice sda_buf=sda_buf<<1;
      @(negedge scl) #`timeslice sda_buf[7]=1;
      @(negedge scl) #`timeslice out_flag=0;
   end
endtask
endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -