📄 op_ctrl.v
字号:
/*********************************************************************
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 + -