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

📄 op_ctrl.v

📁 Verilog for I2C core source code
💻 V
📖 第 1 页 / 共 3 页
字号:
/*********************************************************************
File name: 		  op_ctrl.v
Module name:	          op_ctrl	
Author:		         atuhappy( 陈亮)
Email:                  atuhappy@163.com    
Version:			1.0
Date:				2004.7.26


Function Description:
控制一次完整传输
						
*********************************************************************/

`include "../src/params.v"
module   op_ctrl(CLK,
                 RST_N,
                 OP_REQ,     //启动一次数据传输
                 OP_RES,     //对OP_REQ的响应
                 OP_NUM,    //发送或接收的字节数(OP_NUM+1)
                 DIR,       //1 wr 0 rd
                 DEVICE,    //访问器件地址
                 TARGET,    //访问器件的内部地址,如ram地址
                 BUSY_N,    //正在进行数据读写
                 ASK_IN,      //外设返回的ask
                 DATA_IN,    //发送缓冲区
                 DATA_OUT,   //接收缓冲区
                 FULL,      //产生一个高脉冲,表示接收缓冲区(DATA_OUT)已满
                 EMPTY,     //产生一个高脉冲,表示发送缓冲区(DATA_IN)已空
                 CMD,
                 COMM_RES,
                 TXD,
                 RXD);

input CLK, RST_N;
input  OP_REQ;
output  OP_RES;
input [7 :0] OP_NUM;
input DIR;
input [6 : 0] DEVICE;
input [7 : 0] TARGET;
output BUSY_N;
output ASK_IN;
input [7 : 0] DATA_IN;
output [7 : 0] DATA_OUT;    
output [`I2C_CMD_WIDTH - 1 : 0] CMD;
output FULL, EMPTY;
input COMM_RES;
output TXD;
input RXD;   

reg [7 : 0] DATA_OUT; 
reg FULL, EMPTY;
reg ASK_IN;
reg OP_RES;
reg BUSY_N;
reg [`I2C_CMD_WIDTH - 1 : 0] CMD;

reg [`OP_WIDTH - 1 : 0] curr_state, next_state;
reg [`I2C_CMD_WIDTH - 1 : 0] curr_comm, next_comm;
reg op_res;


reg [7 : 0] data;
reg [7 : 0] dataout_shift;
reg ld;

reg cnt_ld;
reg [8 : 0] cnt_shift;        
wire cnt_done;

reg trans_done;  //为高时,传输结束
reg [7 : 0] cnt;

reg shift;
reg [7 : 0] datain_shift;
reg sa;
reg comm_res;               //COMM_RES延时一个周期

reg full, empty;

reg busy_n;

reg chk_ask, chk_ask1;         //检测返回的ask信号
reg out_ask,out_ask1;         //读时,控制TXD返回ask信号 



always @(curr_state or curr_comm or RST_N or OP_REQ or COMM_RES or DIR or DEVICE or TARGET or DATA_IN or cnt_done or trans_done)
begin
  if(RST_N)
    begin
      case(curr_state)
        `OP_IDLE   : begin
                       data <= 0;
                       ld <= 0;
                       chk_ask <= 0;
                       shift <= 0;
                       cnt_ld <= 0;
                       sa <= 0;
                       busy_n <= 0;
                       full <= 0;
                       empty <= 0;
                       out_ask <= 0;
                       next_comm <= `I2C_CMD_NOP;
                       if (OP_REQ)
                         begin
                           next_state <= `OP_DADDR;
                           op_res <= 1;
                         end  
                       else 
                         begin
                           next_state <= `OP_IDLE;
                           op_res <= 0;
                         end 
                     end
        `OP_DADDR   : begin                                         //器件地址
                       op_res <= 0;
                       shift <= 0;
                       sa <= 0;
                       busy_n <= 1;
                       full <= 0;
                       empty <= 0;   
                       out_ask <= 0;                    
                       case(curr_comm)
                         `I2C_CMD_NOP   : begin
                                            next_state <= `OP_DADDR;
                                            next_comm <= `I2C_CMD_START;
                                            data <= 0;
                                            ld <= 0;
                                            cnt_ld <= 0;
                                            chk_ask <= 0;
                                          end
                         `I2C_CMD_START : begin
                                            next_state <= `OP_DADDR;
                                            chk_ask <= 0;
                                            if(COMM_RES)
                                              begin 
                                                next_comm <= `I2C_CMD_WRITE;
                                                data <= {DEVICE, 1'b0};
                                                ld <= 1;
                                                cnt_ld <= 1;
                                              end
                                            else
                                              begin
                                                next_comm <= `I2C_CMD_START;
                                                data <= 0;
                                                ld <= 0;  
                                                cnt_ld <= 0;                                              
                                              end     
                                          end 
                         `I2C_CMD_WRITE : begin                       //write 8bit
                                            chk_ask <= 0;
                                            next_state <= `OP_DADDR; 
                                            data <= 0;
                                            ld <= 0;  
                                            cnt_ld <= 0;                                          
                                            if(cnt_done) 
                                              begin
                                                next_comm <= `I2C_CMD_READ;
                                              end  
                                            else
                                              begin
                                                next_comm <= `I2C_CMD_WRITE; 
                                              end  
                                          end
                         `I2C_CMD_READ  : begin                                          //ack
                                            data <= 0;
                                            ld <= 0;      
                                            cnt_ld <= 0;
                                            chk_ask <= 1;                    
                                            if(COMM_RES)
                                              begin
                                                next_state <= `OP_TADDR; 
                                                next_comm <= `I2C_CMD_NOP;
                                              end
                                            else
                                              begin
                                                next_state <= `OP_DADDR; 
                                                next_comm <= `I2C_CMD_READ;
                                              end   
                                          end                
                         default        : begin
                                            data <= 0;
                                            ld <= 0;    
                                            cnt_ld <= 0;
                                            chk_ask <= 0;                      
                                            next_state <= `OP_IDLE;
                                            next_comm <= `I2C_CMD_NOP;
                                          end
                        endcase                                                                        
                     end 
        `OP_TADDR  : begin                                                        //目标地址
                       op_res <= 0;
                       shift <= 0;
                       sa <= 0;
                       busy_n <= 1;
                       full <= 0;
                       empty <= 0;  
                       out_ask <= 0;                     
                       case(curr_comm)
                         `I2C_CMD_NOP   : begin
                                            next_state <= `OP_TADDR;
                                            next_comm <= `I2C_CMD_WRITE; 
                                            data <= TARGET;
                                            ld <= 1;    
                                            cnt_ld <= 1; 
                                            chk_ask <= 0;                                        
                                          end 
                         `I2C_CMD_WRITE : begin                                      //write 8bit
                                            next_state <= `OP_TADDR;                         
                                            data <= 0;
                                            ld <= 0;     
                                            cnt_ld <= 0;
                                            chk_ask <= 0;
                                            if(cnt_done) 
                                              begin
                                                next_comm <= `I2C_CMD_READ;                                                
                                              end  
                                            else
                                              begin                                                
                                                next_comm <= `I2C_CMD_WRITE; 
                                              end                                                                                      
                                          end
                         `I2C_CMD_READ  : begin                                          //ack
                                            data <= 0;
                                            ld <= 0;   
                                            cnt_ld <= 0;  
                                            chk_ask <= 1;                     
                                            if(COMM_RES)
                                              begin

⌨️ 快捷键说明

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