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

📄 i2c_control_blk_ver.v

📁 Xilinx的I2C总线控制器
💻 V
📖 第 1 页 / 共 3 页
字号:
        `state_type_WAIT_ACK :          //  ----------- WAIT_ACK State --------------          if (arb_lost)            visual_0_state <= `state_type_IDLE;          else if (detect_stop)          begin            visual_0_state <= `state_type_IDLE;            visual_0_sm_stop <= 1'b0;          end          else if ((!sda))            visual_0_state <= `state_type_XMIT_DATA;          else          begin            //   no ack received, generate a stop and return            //   to IDLE state            if (master_slave)              visual_0_sm_stop <= 1'b1;             visual_0_state <= `state_type_IDLE;          end       endcase    end    //   ************************  START/STOP Detect Process ************************  //   This process detects the start and stop conditions.  //   by using SDA as a clock.  always @( negedge (sda) or negedge (reset))  begin    if (!reset)      visual_0_detect_start <= 1'b0;    else      if (scl)        visual_0_detect_start <= 1'b1;      else if (state == `state_type_HEADER)        visual_0_detect_start <= 1'b0;      else        visual_0_detect_start <= 1'b0;    end    //   RXAK - Received Acknowledge  //   RXAK contains the value of SDA during the acknowledge bit of a bus cycle. If =0, then  //   an acknowledge signal has been received, if 1, then no acknowledge has been received.  //   This bit is not cleared at reset. The CPLD will reset this bit upon power-up  always @( negedge (scl) )  begin     begin    begin      if (state == `state_type_ACK_HEADER || state == `state_type_ACK_DATA ||          state == `state_type_WAIT_ACK)        visual_0_rxak <= sda_in;     end    end   end    always @( posedge (sda) or negedge (reset))  begin    if (!reset)      visual_0_detect_stop <= 1'b0;    else      if (scl)        visual_0_detect_stop <= 1'b1;      else if (detect_start)        visual_0_detect_stop <= 1'b0;      else        visual_0_detect_stop <= 1'b0;    end    always @( posedge (sys_clk) or negedge (reset) )  begin    if (!reset)      visual_0_i2c_header_en <= 1'b0;    else      if ((detect_start) || (state == `state_type_HEADER))        visual_0_i2c_header_en <= 1'b1;      else        visual_0_i2c_header_en <= 1'b0;    end    //   ************************  Bus Busy Process ************************  //   This process detects the start and stop conditions and sets the bus busy bit  //   It also describes a delayed version of the bus busy bit which is used to determine  //   MAL. MAL should be set if a start is detected while the bus is busy, however, the code below  //   sets bus_busy as soon as START is detected which would always set MAL. Therefore, a delayed  //   version of bus_busy is generated and used to determine MAL.  always @( posedge (sys_clk) or negedge (reset) )  begin    if (!reset)    begin      visual_0_bus_busy <= 1'b0;      visual_0_bus_busy_d1 <= 1'b0;    end    else    begin      visual_0_bus_busy_d1 <= bus_busy;      if (detect_start)        visual_0_bus_busy <= 1'b1;       if (detect_stop)        visual_0_bus_busy <= 1'b0;     end   end    //   set SDA and SCL  assign sda = (sda_oe == 1'b1 ? 1'b0 : 1'bz);  assign scl = (scl_out_reg == 1'b0 ? 1'b0 : 1'bz);  assign scl_not =  (~ (scl)) ;  //   sda_oe is set when master and arbitration is not lost and data to be output = 0 or  //   when slave and data to be output is 0  assign sda_oe = (((master_slave == 1'b1 && arb_lost == 1'b0 && sda_out_reg ==                  1'b0) || (master_slave == 1'b0 && slave_sda == 1'b0) ||                  stop_scl_reg == 1'b1) ? 1'b1 : 1'b0);  //   the following signals are only here because Viewlogic's VHDL compiler won't allow a constant  //   to be used in a component instantiation  assign reg_clr = `CLR_REG;  assign zero_sig = ZERO;  assign cnt_zero = `ZERO_CNT;  assign cnt_start = `START_CNT;  assign rep_start = rsta; //   repeat start signal is RSTA control bit  //   MBB - Bus Busy Bit  //   This bit indicates the status of the bus. This bit is set when a START signal is detected and  //   cleared when a stop signal is detected. It is also cleared on reset. This bit is identical to  //   the signal bus_busy set in the process set_bus_busy.  assign mbb = bus_busy;  //   ************************  uP Address Register ************************  assign addr_match = (i2c_header[7:1] == madr[7:1] ? 1'b1 : 1'b0);  assign i2c_header_ld = 1'b0;  //   Counter control lines  assign bit_cnt_en = ((state == `state_type_HEADER) || (state ==                      `state_type_RCV_DATA) || (state == `state_type_XMIT_DATA)                       ? 1'b1 : 1'b0);  assign bit_cnt_ld = ((state == `state_type_IDLE) || (state ==                      `state_type_ACK_HEADER) || (state == `state_type_ACK_DATA)                      || (state == `state_type_WAIT_ACK) ? 1'b1 : 1'b0);   //   MAL - Arbitration Lost Bit  //   This bit is set when the arbitration procedure is lost. Arbitration is lost when:  //  	1. SDA is sampled low when the master drives high during addr or data transmit cycle  //  	2. SDA is sampled low when the master drives high during the acknowledge bit of a  //  		data receive cycle  //  	3. A start cycle is attempted when the bus is busy  //  	4. A repeated start is requested in slave mode  //  	5. A stop condition is detected that the master did not request it.  //   This bit is cleared upon reset and when the software writes a '0' to it  //   Conditions 1 & 2 above simply result in SDA_IN not matching SDA_OUT while SCL is high. This  //   design will not generate a START condition while the bus is busy. When a START is detected, this hardware  //   will set the bus busy bit and gen_start stays set until detect_start asserts, therefore will have  //   to compare with a delayed version of bus_busy. Condition 3 is really just  //   a check on the uP software control registers as is condition 4. Condition 5 is also taken care  //   of by the fact that SDA_IN does not equal SDA_OUT, however, this process also tests for if a stop  //   condition has been detected when this master did not generate it  always @( posedge (sys_clk) or negedge (reset) )  begin    if (!reset)      visual_0_mal <= 1'b0;    else    begin      if (mal_bit_reset)        visual_0_mal <= 1'b0;      else if (master_slave)      begin        if ((arb_lost) || (bus_busy_d1 && gen_start) || (detect_stop && !            gen_stop && !sm_stop))          visual_0_mal <= 1'b1;       end      else if (rsta)        //   repeated start requested while slave        visual_0_mal <= 1'b1;     end   end    //   MAAS - Addressed As Slave Bit  //   When its own specific address (MADR) matches the I2C Address, this bit is set. The CPU is  //   interrupted provided the MIEN is set. Then the CPU needs to check the SRW bit and set its  //   TX-RX mode accordingly. Writing to the MBCR clears this bit  always @( posedge (sys_clk) or negedge (reset) )  begin    if (!reset)      visual_0_maas <= 1'b0;    else      if (mbcr_wr)        visual_0_maas <= 1'b0;      else if (state == `state_type_ACK_HEADER)        visual_0_maas <= addr_match;  //   the signal address match compares MADR with I2_ADDR      else        visual_0_maas <= maas;    end    //   ************************  uP Status Register Bits Processes ************************  //   The following processes and assignments set the bits of the MBUS status register MBSR  //  //   MCF - Data transferring bit  //   While one byte of data is being transferred, this bit is cleared. It is set by the falling edge  //   of the 9th clock of a byte transfer and is not cleared at reset  always @( negedge (scl) or negedge (reset) )  begin    if (!reset)      visual_0_mcf <= 1'b0;    else      if (bit_cnt == `CNT_DONE)        visual_0_mcf <= 1'b1;      else        visual_0_mcf <= 1'b0;    end    //   SRW - Slave Read/Write Bit  //   When MAAS is set, SRW indicates the value of the R/W command bit of the calling address sent  //   from the master. This bit is only valid when a complete transfer has occurred and no other  //   transfers have been initiated. The CPU uses this bit to set the slave transmit/receive mode.  //   This bit is reset by reset  always @( posedge (sys_clk) or negedge (reset) )  begin    if (!reset)      visual_0_srw <= 1'b0;    else      if (state == `state_type_ACK_HEADER)        visual_0_srw <= i2c_header[0];      else        visual_0_srw <= srw;    end    always @( posedge (sys_clk) or negedge (reset) )  begin    if (!reset)    begin      visual_0_shift_reg_en <= 1'b0;      visual_0_shift_reg_ld <= 1'b0;    end    else    begin      if (((master_slave && state == `state_type_HEADER) || (state ==          `state_type_RCV_DATA) || (state == `state_type_XMIT_DATA)))        visual_0_shift_reg_en <= 1'b1;      else        visual_0_shift_reg_en <= 1'b0;       if (((master_slave && state == `state_type_IDLE) || (state ==          `state_type_WAIT_ACK) || (state == `state_type_ACK_HEADER &&          i2c_header[0] && !master_slave) || (state == `state_type_ACK_HEADER &&          mtx && master_slave)))        visual_0_shift_reg_ld <= 1'b1;      else        visual_0_shift_reg_ld <= 1'b0;     end   end    //   MIF - M-bus Interrupt  //   The MIF bit is set when an interrupt is pending, which causes a processor interrupt  //   request provided MIEN is set. MIF is set when:  //  	1. Byte transfer is complete (set at the falling edge of the 9th clock  //  	2. MAAS is set when in slave receive mode  //  	3. Arbitration is lost  //   This bit is cleared by reset and software writting a '0'to it  always @( posedge (sys_clk) or negedge (reset) )  begin    if (!reset)      visual_0_mif <= 1'b0;    else    begin      if (mif_bit_reset)        visual_0_mif <= 1'b0;      else if (mal || mcf || (maas && !i2c_header[0] && !master_slave))        visual_0_mif <= 1'b1;     end   end    //   ************************  Slave and Master SDA ************************  always @( negedge (reset) or posedge (sys_clk) )  begin    if (!reset)    begin      visual_0_master_sda <= 1'b1;      visual_0_slave_sda <= 1'b1;    end    else    begin      if (state == `state_type_HEADER || state == `state_type_XMIT_DATA)        visual_0_master_sda <= shift_out;      else if (state == `state_type_ACK_DATA)        visual_0_master_sda <= txak;      else        visual_0_master_sda <= 1'b1;       //   For the slave SDA, address match (MAAS) only has to be checked when      //   state is ACK_HEADER because state      //   machine will never get to state XMIT_DATA or ACK_DATA      //   unless address match is a one.      if ((maas && state == `state_type_ACK_HEADER) || (state ==          `state_type_ACK_DATA))        visual_0_slave_sda <= txak;      else if ((state == `state_type_XMIT_DATA))        visual_0_slave_sda <= shift_out;      else        visual_0_slave_sda <= 1'b1;     end   end    //   ************************  uP Data Register ************************  //   Register for uP interface MBDR_I2C  always @( posedge (sys_clk) or negedge (reset) )  begin    if (!reset)      visual_0_mbdr_i2c <= {{8{ 1'b0 }}};    else      if ((state == `state_type_ACK_DATA) || (state == `state_type_WAIT_ACK))        visual_0_mbdr_i2c <= shift_reg;      else        visual_0_mbdr_i2c <= mbdr_i2c;    end  endmodule

⌨️ 快捷键说明

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