📄 ft245_r_w.v
字号:
//*****************************************************
//模块名称: FT245_R_W
//模块功能: FT245BM 读写模块
//版本记录:
//V 1.0 2008-02-18 谢朝壮
//*****************************************************
//模块接口
//*****************************************************
module FT245_R_W(
//系统信号
input wire sclk, //sclk为FPGA工作时钟,默认100MHz.
input wire rst_n, //异步复位信号,低有效.
//FPGA和FT245MB间的USB接口
input wire USB_RXF,
input wire USB_TXE,
output reg USB_RD,
output reg USB_WR,
inout tri [7:0] USB_DATA, //USB和FPGA间的双向数据库总线
//模块内部和其他模块或器件间的接口
output reg [7:0] RX_data_fm_usb, //其他模块或器件从本模块读取来自USB接口的数据
input wire [7:0] TX_data_to_usb, //其他模块或器件向本模块写入发到USB接口的数据
input wire RD_Enable, //其他模块或器件从本模块读取来自USB接口数据的读使能,高有效
input wire WR_Enable, //其他模块或器件向本模块写入发到USB接口数据的写使能,高有效
output reg USB_busy //USB接口忙/空闲状态信号,高为忙碌,低为空闲
); //处于读状态时,由忙碌状态变为空闲状表示上一个数据开始有效
//******************************************************
//内部寄存器定义
reg [7:0] data_fm_usb; //从USB接收数据
reg [7:0] data_to_usb; //发送数据到USB
reg [7:0] data_to_usb_buffer; //发送缓冲寄存器
reg [4:0] RD_time_cont; //读等待时间计数器
reg [4:0] WR_time_cont; //写等待时间计数器
parameter RX_state0 = 2'b01; //读状态0
parameter RX_state1 = 2'b10; //读状态1
parameter TX_state0 = 2'b01; //写状态0
parameter TX_state1 = 2'b10; //写状态1
reg [1:0] RX_state; //读状态
reg [1:0] TX_state; //写状态
//******************************************************
//本模块与FT245B间的数据总线
//******************************************************
assign USB_DATA=(USB_WR==1'b1)?data_to_usb:8'bzz;
//******************************************************
//其他模块与本模块之间的数据交换
//******************************************************
always@(posedge sclk or negedge rst_n)//接收数据
if(!rst_n)
RX_data_fm_usb <= 8'b00;
else if(RD_Enable == 1'b1)
RX_data_fm_usb <= data_fm_usb;
//////////////////////////////////
always@(posedge sclk or negedge rst_n)//发送数据
if(!rst_n)
data_to_usb_buffer <= 8'b00;
else if(WR_Enable == 1'b1)
data_to_usb_buffer <= TX_data_to_usb;
//******************************************************
//USB接口忙/空闲状态信号USB_busy处理
//******************************************************
always@(posedge sclk or negedge rst_n)
if(!rst_n)
USB_busy<=1'b0; //状态机复位到空闲
else if((USB_RXF==1'b0 && RD_Enable == 1'b1)||(USB_TXE==1'b0 && WR_Enable==1'b1))
USB_busy<=1'b1; //状态机忙碌
else
USB_busy<=1'b0; //状态机空闲
//******************************************************
//读/写FT254BM相关等待时间计数
//******************************************************
always@(posedge sclk or negedge rst_n)
if(!rst_n)
RD_time_cont<=5'b0;
else if(USB_RD==1'b0) //读使能到来开始计数.
RD_time_cont<=RD_time_cont + 1'b1;
else if(USB_RXF == 1'b1) //USB_RXF没拉高之前不允许有其他跨读(写)操作
RD_time_cont<=5'b0;
//******************************************************
always@(posedge sclk or negedge rst_n)
if(!rst_n)
WR_time_cont<=5'b0;
else if(USB_WR==1'b1) //写使能到来开始计数.
WR_time_cont<=WR_time_cont + 1'b1;
else if(USB_TXE == 1'b1) //USB_TXE没拉高之前不允许有其他跨读(写)操作
WR_time_cont<=5'b0;
//******************************************************
//本模块读FT254BM状态机
//******************************************************
always@(posedge sclk or negedge rst_n) //sclk为FPGA工作时钟,默认100MHz.
if(!rst_n)
begin
RX_state<=RX_state0;
USB_RD <=1'b1;
end
else if(USB_RXF==1'b0 && RD_Enable == 1'b1) //RD_Enable 高有效
begin
case(RX_state)
RX_state0:
begin
if(RD_time_cont==5'b0)
USB_RD<=1'b0; //产生读信号的下降沿
else if(RD_time_cont==5'd5) //产生读信号的下降沿50ns后转到读状态1
RX_state<=RX_state1;
end
RX_state1:
begin
if(RD_time_cont==5'd6) //产生读信号的下降沿60ns后读数据
data_fm_usb<=USB_DATA; //读FT245BM芯片FIFO的当前字节
else if(RD_time_cont==5'd7) //USB_RD有效脉冲宽度最小为50ns,这里用70ns.
USB_RD<=1'b1;
end
endcase
end
else
begin
RX_state<=RX_state0;
USB_RD<=1'b1;
end
//******************************************************
//本模块写FT254BM状态机
//******************************************************
always@(posedge sclk or negedge rst_n) //sclk为FPGA工作时钟,默认100MHz.
if(!rst_n)
begin
TX_state<=TX_state0;
USB_WR <=1'b0;
end
else if(USB_TXE==1'b0 && WR_Enable==1'b1) //WR_Enable 高有效
begin
case(TX_state)
TX_state0:
begin
if(WR_time_cont==5'b0)
USB_WR<=1'b1; //产生写信号的上升沿
else if(WR_time_cont==5'd5) //产生写信号的上升沿50ns后转到写状态1
TX_state<=TX_state1;
end
TX_state1:
begin
if(WR_time_cont==5'd6) //产生写信号的上升沿60ns发送数据
data_to_usb <=data_to_usb_buffer; //写一个字节到FIFO,data_to_usb_buffer为发送缓冲寄存器
else if(WR_time_cont==5'd7) //USB_WR有效脉冲宽度最小为50ns,这里用70ns.
USB_WR <=1'b0;
end
endcase
end
else
begin
TX_state<=TX_state0;
USB_WR <=1'b0;
end
endmodule
//////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -