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

📄 i2c_control_blk_ver.v

📁 Xilinx的I2C总线控制器
💻 V
📖 第 1 页 / 共 3 页
字号:
            visual_0_arb_lost <= 1'b1;            visual_0_msta_rst <= 1'b1;          end         else        begin          visual_0_arb_lost <= arb_lost;          visual_0_msta_rst <= 1'b0;        end      end   end    //   ************************  SCL_Generator Process ************************  //   This process generates SCL and SDA when in Master mode. It generates the START  //   and STOP conditions. If arbitration is lost, SCL will be generated until the  //   end of the byte transfer.  always @(scl_state or arb_lost or sm_stop or gen_stop or rep_start or bus_busy or    gen_start or master_slave or stop_scl_reg or clk_cnt or bit_cnt or scl_in or    state or sda_out or sda_out_reg or stop_scl_reg or master_sda)  begin    //   state machine defaults    visual_0_scl_out <= 1'b1;    visual_0_sda_out <= sda_out_reg;    visual_0_stop_scl <= stop_scl_reg;    visual_0_clk_cnt_en <= 1'b0;    visual_0_clk_cnt_rst <= 1'b1;    visual_0_next_scl_state <= scl_state;    case (scl_state)      `scl_state_type_SCL_IDLE :      begin        visual_0_sda_out <= 1'b1;        visual_0_stop_scl <= 1'b0;        //   leave IDLE state when master, bus is idle, and gen_start        if (master_slave && !bus_busy && gen_start)          visual_0_next_scl_state <= `scl_state_type_START;       end      `scl_state_type_START :      begin        //   generate start condition        visual_0_clk_cnt_en <= 1'b1;        visual_0_clk_cnt_rst <= 1'b0;        visual_0_sda_out <= 1'b0;        visual_0_stop_scl <= 1'b0;        if (clk_cnt == `START_HOLD)          visual_0_next_scl_state <= `scl_state_type_SCL_LOW_EDGE;        else          visual_0_next_scl_state <= `scl_state_type_START;       end      `scl_state_type_SCL_LOW_EDGE :      begin        visual_0_clk_cnt_rst <= 1'b1;        visual_0_scl_out <= 1'b0;        visual_0_next_scl_state <= `scl_state_type_SCL_LOW;        visual_0_stop_scl <= 1'b0;      end      `scl_state_type_SCL_LOW :      begin        visual_0_clk_cnt_en <= 1'b1;        visual_0_clk_cnt_rst <= 1'b0;        visual_0_scl_out <= 1'b0;        //   set SDA_OUT based on control signals        if (arb_lost)          visual_0_stop_scl <= 1'b0;        else if (((sm_stop || gen_stop) && (state != `state_type_ACK_DATA &&                 state != `state_type_ACK_HEADER && state !=                 `state_type_WAIT_ACK)))        begin          visual_0_sda_out <= 1'b0;          visual_0_stop_scl <= 1'b1;        end        else if (rep_start)        begin          visual_0_sda_out <= 1'b1;          visual_0_stop_scl <= 1'b0;        end        else if (clk_cnt == `DATA_HOLD)        begin          visual_0_sda_out <= master_sda;          visual_0_stop_scl <= 1'b0;        end        else          visual_0_stop_scl <= 1'b0;         //   determine next state        if (clk_cnt == `LOW_CNT)          if (bit_cnt == `CNT_DONE && arb_lost)            visual_0_next_scl_state <= `scl_state_type_SCL_IDLE;          else            visual_0_next_scl_state <= `scl_state_type_SCL_HIGH_EDGE;         else          visual_0_next_scl_state <= `scl_state_type_SCL_LOW;       end      `scl_state_type_SCL_HIGH_EDGE :      begin        visual_0_clk_cnt_rst <= 1'b1;        visual_0_scl_out <= 1'b1;        if (((sm_stop || gen_stop) && (state != `state_type_ACK_DATA && state !=            `state_type_ACK_HEADER && state != `state_type_WAIT_ACK)))          visual_0_stop_scl <= 1'b1;        else          visual_0_stop_scl <= 1'b0;         //   this state sets SCL high        //   stay in this state until SCL_IN = 1        //   this will hold the counter in reset until all SCL drivers        //   have released SCL to 1        if (!scl_in)          visual_0_next_scl_state <= `scl_state_type_SCL_HIGH_EDGE;        else          visual_0_next_scl_state <= `scl_state_type_SCL_HIGH;       end      `scl_state_type_SCL_HIGH :      begin        //   now all SCL drivers have set SCL to '1'        //   begin count for high time        visual_0_clk_cnt_en <= 1'b1;        visual_0_clk_cnt_rst <= 1'b0;        visual_0_scl_out <= 1'b1;        //   check to see if a repeated start or a stop needs to be        //   generated. If so, only hold SCL high for half of the high time        if (clk_cnt == `HIGH_CNT_2)        begin        begin          if (rep_start)            visual_0_next_scl_state <= `scl_state_type_START;          else if (stop_scl_reg)            visual_0_next_scl_state <= `scl_state_type_SCL_IDLE;         end        end        else if (clk_cnt == `HIGH_CNT)          visual_0_next_scl_state <= `scl_state_type_SCL_LOW_EDGE;        else          visual_0_next_scl_state <= `scl_state_type_SCL_HIGH;       end    endcase   end    always @( posedge (sys_clk) or negedge (reset) )  begin    if (!reset)    begin      visual_0_scl_state <= `scl_state_type_SCL_IDLE;      visual_0_sda_out_reg <= 1'b1;      visual_0_scl_out_reg <= 1'b1;      visual_0_stop_scl_reg <= 1'b0;    end    else    begin      visual_0_scl_state <= next_scl_state;      visual_0_sda_out_reg <= sda_out;      visual_0_scl_out_reg <= scl_out;      visual_0_stop_scl_reg <= stop_scl;    end   end    //   ************************  Input Registers Process ************************  //   This process samples the incoming SDA and SCL with the system clock  always @( posedge (sys_clk) or negedge (reset) )  begin    if (!reset)    begin      visual_0_sda_in <= 1'b1;      visual_0_scl_in <= 1'b1;      visual_0_msta_d1 <= 1'b0;      visual_0_sda_out_reg_d1 <= 1'b1;    end    else    begin      //   the following if, then, else clauses are used      //   because scl may equal 'H' or '1'      if (!scl)        visual_0_scl_in <= 1'b0;      else        visual_0_scl_in <= 1'b1;       if (!sda)        visual_0_sda_in <= 1'b0;      else        visual_0_sda_in <= 1'b1;       visual_0_sda_out_reg_d1 <= sda_out_reg;      visual_0_msta_d1 <= msta;    end   end    //   ************************   uP Control Bits Process ************************  //   This process detects the rising and falling edges of MSTA and sets signals to  //   control generation of start and stop conditions  //   This process also sets the master slave bit based on MSTA if and only if it is not  //   in the middle of a cycle, i.e. bus_busy = '0'  always @( posedge (sys_clk) or negedge (reset) )  begin    if (!reset)    begin      visual_0_gen_start <= 1'b0;      visual_0_gen_stop <= 1'b0;      visual_0_master_slave <= 1'b0;    end    else    begin      if (!msta_d1 && msta)        //   rising edge of MSTA - generate start condition        visual_0_gen_start <= 1'b1;      else if (detect_start)        visual_0_gen_start <= 1'b0;       if (!arb_lost && msta_d1 && !msta)        //   falling edge of MSTA - generate stop condition only        //   if arbitration has not been lost        visual_0_gen_stop <= 1'b1;      else if (detect_stop)        visual_0_gen_stop <= 1'b0;       if (!bus_busy)        visual_0_master_slave <= msta;      else        visual_0_master_slave <= master_slave;     end   end    //   ************************  Main State Machine Process ************************  //   The following process contains the main I2C state machine for both master and slave  //   modes. This state machine is clocked on the falling edge of SCL. DETECT_STOP must stay as  //   an asynchronous reset because once STOP has been generated, SCL clock stops.  always @( negedge (scl) or negedge (reset))  begin    if (!reset)    begin      visual_0_state <= `state_type_IDLE;      visual_0_sm_stop <= 1'b0;    end    else      case (state)        `state_type_IDLE :          //  ----------- IDLE STATE -------------          if (detect_start)            visual_0_state <= `state_type_HEADER;          else if (detect_stop)          begin            visual_0_state <= `state_type_IDLE;            visual_0_sm_stop <= 1'b0;          end         `state_type_HEADER :          //  ----------- HEADER STATE -------------          if (bit_cnt == `CNT_DONE)            visual_0_state <= `state_type_ACK_HEADER;          else if (detect_stop)          begin            visual_0_state <= `state_type_IDLE;            visual_0_sm_stop <= 1'b0;          end         `state_type_ACK_HEADER :          //  ----------- ACK_HEADER 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_in)            //   ack has been received, check for master/slave            if (master_slave)              //   master, so check mtx bit for direction              if (!mtx)                //   receive mode                visual_0_state <= `state_type_RCV_DATA;              else                //  transmit mode                visual_0_state <= `state_type_XMIT_DATA;             else              if (addr_match)                //  if maas = '1' then                //   addressed slave, so check I2C_HEADER(0) for direction                if (!i2c_header[0])                  //   receive mode                  visual_0_state <= `state_type_RCV_DATA;                else                  //   transmit mode                  visual_0_state <= `state_type_XMIT_DATA;               else                //   not addressed, go back to IDLE                visual_0_state <= `state_type_IDLE;            else          begin            //   no ack received, stop            visual_0_state <= `state_type_IDLE;            if (master_slave)              visual_0_sm_stop <= 1'b1;           end         `state_type_RCV_DATA :          //  ----------- RCV_DATA State --------------          //   If stop signal detected          //  if (detect_stop = '1') then          //  state <= IDLE;          //   Continue transmitting          if (bit_cnt == `CNT_DONE)            //   Send an acknowledge            visual_0_state <= `state_type_ACK_DATA;          else if (detect_stop)          begin            visual_0_state <= `state_type_IDLE;            visual_0_sm_stop <= 1'b0;          end         `state_type_XMIT_DATA :          //  ---------- XMIT_DATA State --------------          //   If stop signal detected          //  if (detect_stop = '1') then          //     state <= IDLE;          if (bit_cnt == `CNT_DONE)            //   Wait for acknowledge            visual_0_state <= `state_type_WAIT_ACK;          else if (detect_stop)          begin            visual_0_state <= `state_type_IDLE;            visual_0_sm_stop <= 1'b0;          end         `state_type_ACK_DATA :        begin          //  ----------- ACK_DATA State --------------          visual_0_state <= `state_type_RCV_DATA;          if (detect_stop)          begin            visual_0_state <= `state_type_IDLE;            visual_0_sm_stop <= 1'b0;          end         end

⌨️ 快捷键说明

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