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

📄 i2ctop.v

📁 华大机顶盒源码(包括所有源代码).rar
💻 V
📖 第 1 页 / 共 2 页
字号:
module i2ctop(ResetN, CLKM,
              I2C_D_IN, I2C_D_O, IDO_EN,
              I2C_C_IN, I2C_C_O, ICO_EN,
              //input
              I2cAddr, MEM_FAIL,PROG_END,
              //output
              K, Pause, PIDT_Addr, PIDT_WR, PIDT_DATA,  
              //debug
              cur_st,datai,datao,cnt1
              );
                 
input ResetN;
input CLKM;

input       I2C_D_IN;
input       I2C_C_IN;
output      I2C_D_O; 
output      IDO_EN;
output      I2C_C_O;
output      ICO_EN;

//input
input [2:0] I2cAddr;
input       MEM_FAIL;
input       PROG_END;

//output
output       K;
output       Pause;
output [5:0] PIDT_Addr;
output       PIDT_WR;
output [7:0] PIDT_DATA;

//debug
output [4:0] cur_st;
output [7:0] datai;
output [7:0] datao ;
output [3:0] cnt1;

wire in1;
wire out1 ;
wire i2cc_pe ;
wire i2cc_ne ;
wire ack_in ;
wire ack_out;
wire stop;
wire start;
wire [3:0] cnt2;
wire [3:0] cnt1;
wire [7:0] datai;
wire [7:0] datao ;
wire cnt_en;
wire i2cen_in;
wire i2cen_o ;
wire i2c_c_i;
wire cen;

wire [5:0] ADDR;
wire WR_REG;
wire [7:0] DO;

assign PIDT_DATA = DO;

assign ICO_EN=~i2cen_o;
assign I2C_C_O = 0;

movereg U1( .clk(CLKM), 
            .reset(ResetN) ,
            .in(in1), 
            .out(out1), 
            .cnt1(cnt1), 
            .i2c_clk(i2c_c_i),
            .i2c_clk_posedge(i2cc_pe), 
            .i2c_clk_negedge(i2cc_ne),
            .data_in(datao), 
            .data_out(datai), 
            .ack_in(ack_out), 
            .ack_out(ack_in), 
            .i2c_d_out_en(IDO_EN),
            .i2c_d_in(I2C_D_IN), 
            .i2c_d_out(I2C_D_O),
            .i2c_en_in(i2cen_in), 
            .i2c_en_out(i2cen_o)
            );

I2Csm U2( .clk(CLKM) , 
          .reset(ResetN) , 
          .cnt1(cnt1),
          .cnt_en(cnt_en),
          .reg_in(in1),
          .reg_out(out1),
          .i2c_data_in(datai),
          .i2c_data_out(datao), 
          .start(start),
          .stop(stop),
          .ack_in(ack_in),
          .ack_out(ack_out),
          .i2c_en(i2cen_in),
          .data_out(DO),
          .data_in(8'h00),
          .addr(ADDR),
          .wr_reg(WR_REG),
          .I2cAddr(I2cAddr),
          .cur_state(cur_st));

EdgeDetect U3( .clk(CLKM), 
               .i2c_clk(i2c_c_i), 
               .i2c_data(I2C_D_IN),
               .i2c_clk_posedge(i2cc_pe),
               .i2c_clk_negedge(i2cc_ne), 
               .start(start),
               .stop(stop));

                 
counter  U4( .clk(CLKM) , 
             .en(cnt_en) , 
             .i2c_clk_posedge(i2cc_pe) , 
             .cnt1(cnt1) ,
             .cnt2(cnt2));    

m1       U5( .in(I2C_C_IN),
             .out(i2c_c_i),
             .ctl(~i2cen_o));

CtrlReg  U6( .ResetN(ResetN), 
             .CLKM(CLKM), 
             .I2CDB(DO), 
             .CEN(cen), 
             .WR(WR_REG), 
             .MEM_FAIL(MEM_FAIL), 
             .PROG_END(PROG_END),
             .K(K),
             .Pause(Pause)
           );

RegAddr U7( .ResetN(ResetN), 
            .CLKM(CLKM), 
            .abus(ADDR), 
            .CEN(cen),
            .PIDT_Addr(PIDT_Addr),
            .WR(WR_REG),
            .PIDT_WR(PIDT_WR)
          );

endmodule


/*******************************************************************/
module CtrlReg(ResetN, CLKM, 
               //input 
               I2CDB, CEN, WR, MEM_FAIL, PROG_END,
               //output 
               K, Pause);
               
input       ResetN;
input       CLKM;
input       CEN;
input       WR;
input       MEM_FAIL;
input       PROG_END;
input [7:0] I2CDB;

output       K;
output       Pause;

reg [7:0] CtrReg;

assign K = CtrReg[3];
assign Pause = CtrReg[4];

always @(posedge CLKM or negedge ResetN)
if(!ResetN)
   CtrReg <= 8'h08;
else if(MEM_FAIL || PROG_END)
   CtrReg <= 8'h08;
else if(CEN & WR)
   CtrReg <= I2CDB;
else
   CtrReg <= CtrReg;

endmodule

/*******************************************************************/
module RegAddr(ResetN, CLKM, abus, CEN, PIDT_Addr, WR, PIDT_WR);

input        ResetN;
input        CLKM;
input  [5:0] abus;
input        WR;

output       CEN;
output [5:0] PIDT_Addr;
output       PIDT_WR;

reg       CEN;
reg [5:0] PIDT_Addr;
reg       PIDT_WR;

always @(posedge CLKM or negedge ResetN)
if(!ResetN) begin
   CEN <= 0;
   PIDT_Addr <= 0;
   PIDT_WR <= 0;
end else if(abus == 6'h00) begin
   CEN <= 1;
   PIDT_Addr <= 0;
   PIDT_WR <= 0;
end else if(abus > 6'h01 && abus<6'h32) begin
   CEN <= 0;
   PIDT_Addr <= abus - 6'h02;
   PIDT_WR <= WR;
end else begin
   CEN <= 0;
   PIDT_Addr <= 0;
   PIDT_WR <= 0;
end
   
endmodule
     

/*******************************************************************/

module counter ( clk , 
                 en , 
                 i2c_clk_posedge , 
                 cnt1 , cnt2 );

input clk ;
input en  ;
input i2c_clk_posedge ;
output [3:0] cnt1 ;
output [3:0] cnt2 ;

reg [3:0] cnt1;
reg [3:0] cnt2;

always @(posedge clk or negedge en)
if(~en) begin
  cnt1 <= 0 ;
  cnt2 <= 0 ;
end
else begin
  if(i2c_clk_posedge) begin
    if(cnt1==8) begin
       cnt1 <= 0 ;
       if (cnt2==15)
           cnt2 <= cnt2 ;
       else 
           cnt2 <= cnt2 + 1 ;
    end
    else begin
       cnt1 <= cnt1 + 1 ;
       cnt2 <= cnt2 ;
    end
  end
end

endmodule

/**************************************************************/

module EdgeDetect ( clk , i2c_clk , i2c_data ,
                    i2c_clk_posedge,i2c_clk_negedge,start,stop);

input  clk;
input  i2c_clk ;
input  i2c_data ;
output i2c_clk_posedge;
output i2c_clk_negedge;
output start;
output stop;

reg start ;
reg stop ;
reg i2c_clk_buf1;
reg i2c_data_buf1;
reg i2c_clk_buf2;
reg i2c_data_buf2;
wire i2c_data_posedge;
wire i2c_data_negedge;

assign i2c_clk_posedge = i2c_clk_buf1 & (~i2c_clk_buf2) ;
assign i2c_clk_negedge = (~i2c_clk_buf1) & i2c_clk_buf2 ;
assign i2c_data_posedge = i2c_data_buf1 & (~i2c_data_buf2) ;
assign i2c_data_negedge = (~i2c_data_buf1) & i2c_data_buf2 ; 

always @(posedge clk)
begin
  i2c_clk_buf1 <= i2c_clk ;
  i2c_clk_buf2 <= i2c_clk_buf1 ;
  i2c_data_buf1 <= i2c_data ;
  i2c_data_buf2 <= i2c_data_buf1 ;
  if(i2c_clk) begin
     if (i2c_data_negedge) begin 
         start <= 1;
         stop  <= 0;
     end
     else if (i2c_data_posedge) begin
         start <= 0 ;
         stop  <= 1 ;
     end
     else begin
         start <= 0 ;
         stop  <= 0 ;
     end
  end
  else begin
     start <= 0 ;
     stop  <= 0 ;
  end
end

endmodule 

/******************************************************************/

module I2Csm(clk , reset , cnt1,cnt_en,reg_in,reg_out, 
             i2c_data_in ,i2c_data_out , start,stop,
             ack_in,ack_out,i2c_en,
             data_out,data_in,
             addr,wr_reg, I2cAddr,
             cur_state);

input clk ;
input reset ;
input [3:0] cnt1; 
input [7:0] i2c_data_in ;
input start,stop;
input ack_in;
input [7:0] data_in;
input [2:0] I2cAddr;

output cnt_en; 
output reg_in,reg_out;
output ack_out;
output [7:0] i2c_data_out;
output [7:0] data_out;
output [5:0] addr ;
output wr_reg;
output i2c_en;
output [4:0] cur_state ;

reg cnt_en; 
reg reg_in,reg_out;
reg ack_out;
reg [7:0] i2c_data_out;
reg [7:0] data_out;
reg [5:0] addr ;
reg wr_reg;
reg i2c_en;

reg [4:0] cur_state ;
reg [4:0] next_state ;

//wire Device_addr_wr = {4'b1011 , I2cAddr, 1'b0};
//wire Device_addr_rd = {4'b1011 , I2cAddr, 1'b1};

parameter IDLE = 5'd0, START = 5'd1,
          COMP_ADDR_WR=5'd2 , ADDRESS=5'd3 , COMP_INS=5'd4 , 
          WRITE_REG1=5'd5 , WRITE_REG2=5'd6 , WRITE_REG3=5'd7 , WRITE_REG4=5'd8 ,
          WRITE_REG5=5'd9 , SEND_ACK=5'd10 , SEND_NAK=5'd11 ,
          WAIT_RESTART2=5'd12, RESTART=5'd13 , COMP_ADDR_RD=5'd14 , START_READ=5'd15 , 
          READ_REG1=5'd16 , READ_REG2=5'd17 , READ_REG3=5'd18 , READ_REG4=5'd19 ,
          READ_REG5=5'd20 , WAIT_STOP1=5'd21 , WAIT_STOP2=5'd22 ,WAIT_RESTART1=5'd23
          ;


always @(posedge clk or negedge reset)
if(!reset)
   cur_state <= IDLE ;
else
   cur_state <= next_state ;


always @(cur_state or ack_in or cnt1 or start or stop or i2c_data_in or I2cAddr or data_out)
begin
 case (cur_state)
   IDLE : begin
          if(start) 
             next_state <= START ;
          else 
             next_state <= IDLE ;
          end

   START : begin//has received START signal , read 1st Byte
          if(cnt1==8)
            next_state <= COMP_ADDR_WR ;
          else 
            next_state <= START ;
          end

   COMP_ADDR_WR : begin  //compare addr,send ack/nak 
          if(data_out=={4'b1011 , I2cAddr, 1'b0})  
            if(cnt1==0)
              next_state <= ADDRESS ;
            else
              next_state <= COMP_ADDR_WR ;
          else
               next_state <= IDLE ;
          end

  ADDRESS : begin//read 2nd Byte
          if(cnt1==8)
             next_state <= COMP_INS ;
          else
             next_state <= ADDRESS ;
          end
 
  COMP_INS : begin
            if(data_out[5:0]<6'h32)
               next_state <= SEND_ACK ;
            else 
               next_state <= SEND_NAK;
          end

//-----------------------------------------------------------------------------
//stop
/*    WAIT_STOP1 : begin
          if(cnt1==1)
             next_state <= WAIT_STOP2 ;
          else 
             next_state <= WAIT_STOP1 ;
          end

   WAIT_STOP2 : begin
//          if(stop)
             next_state <= IDLE ;
//          else 
//             next_state <= WAIT_STOP2 ;
          end
*/ 
//-----------------------------------------------------------------------------
//return ACK 
   SEND_ACK : begin
          if(cnt1==0) begin
//             if(data_out[7]==1)
//               next_state <= WAIT_RESTART1 ;//read operation
//             else
               next_state <= WRITE_REG1 ; //write addr
          end
          else 
             next_state <= SEND_ACK ;
          end

//-----------------------------------------------------------------------------
//return NAK
   SEND_NAK : begin
          if(cnt1==0)
             next_state <= WAIT_STOP1 ;
          else  
             next_state <= SEND_NAK ;
          end

//--------------------------------------------------------------------------
//write reg
   WRITE_REG1 : begin
          if(stop)
             next_state <= IDLE ;
          else if(cnt1==8)
             next_state <= WRITE_REG2 ;
          else 
             next_state <= WRITE_REG1 ;
          end

    WRITE_REG2 : begin
          next_state <= WRITE_REG3 ;
          end 
    WRITE_REG3 : begin
          next_state <= WRITE_REG4 ;
          end 
    WRITE_REG4 : begin
          next_state <= WRITE_REG5 ;
          end           
    WRITE_REG5 : begin//reset mcu_wr_reg , and return ack
          if(cnt1==0) 
               next_state <= WRITE_REG1 ;
          else
            next_state <= WRITE_REG5 ;
          end

//-------------------------------------------------------------------------------
//read device , wait re_start
/*   WAIT_RESTART1 : begin
          if(cnt1==1)
              next_state <= WAIT_RESTART2;
          else
              next_state <= WAIT_RESTART1;
          end

   WAIT_RESTART2 : begin
          if(start)
             next_state <= RESTART ;
          else
             next_state <= WAIT_RESTART2 ;
          end

  RESTART : begin
          if(cnt1==8)
            next_state <= COMP_ADDR_RD ;
          else
            next_state <= RESTART ;
          end

  COMP_ADDR_RD : begin//compare addr ( read device ), and return ack or nak
          if(data_out=={4'b1011 , I2cAddr, 1'b1})
             if(cnt1 == 0 )
                next_state <= START_READ ;
             else
                next_state <= COMP_ADDR_RD ;
          else
             next_state <= IDLE ;
          end

  START_READ : begin
               next_state <= READ_REG1 ;
               end
*/
//------------------------------------------------------------------------
//read status
/*    READ_REG1 : begin//wait a clock cycle

⌨️ 快捷键说明

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