上一篇说道了写时序,今天来讲讲读时序。
1.USB芯片读时序图
由此可以看出他用到的信号线是
ifclk,slrd,flag_empty, usb_fdata, sloe,slcs这几个引脚。
所以就要写程序去满足他的时序。
写程序前想的时序:
write时序中,使用的是FIFO的满标志,read时序中,使用的是FIFO的空标志。
2.代码:
// *********************************************************************************
// Project Name : OSXXXX
// Author : ZhangXiaoHong
// Email : 1208481840@qq.com
// Website : /
// Create Time : 2018/12/25 14:56:43
// File Name : .v
// Module Name :
// Called By :
// Abstract :
//
// CopyRight(c) 2018, ZhangXiaoHong Studio..
// All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change
// Description
// -----------------------------------------------------------------------
// 2018/12/25 XioaHong 1.0 Original
//
// *********************************************************************************
`timescale 1ns/1ns
module usb_top(
input ifclk ,
input s_rst_n ,
input usb_full , //满标志
input usb_empty , //空标志
output wire usb_slcs , //FIFO使能标志
output wire usb_slwr , //FIFO写触发标志信号
output wire usb_slrd , //FIFO的读触发标志,低电平有效
output wire usb_sloe , //FIFO的输出使能,低电平有效
output wire [1:0] usb_fifoadr , //FIFO片选信号
input [15:0] usb_fdata //FIFO的数据信号
);
//========================================================================\
// =========== Define Parameter and Internal signals ===========
//========================================================================/
reg usb_slrd_reg ;
//=============================================================================
//************** Main Code **************
//=============================================================================
always @(posedge ifclk or negedge s_rst_n) begin
if(s_rst_n == 1'b0)
usb_slrd_reg <= 1'b1;
else if(usb_empty == 1'b1)
usb_slrd_reg <= 1'b0;
else
usb_slrd_reg <= 1'b1;
end
assign usb_slrd = (usb_empty == 1'b1 && usb_slrd_reg == 1'b0)? 1'b0: 1'b1;
//assign usb_slrd = (usb_empty == 1'b1)? 1'b0: 1'b1;
assign usb_slcs = 1'b0;
assign usb_slwr = 1'b1;
assign usb_sloe = 1'b0;
assign usb_fifoadr = 2'b00;//2,4,,6,8
//--------------------------------------
wire [35:0] CONTROL0;
wire [19:0] ila_trig;
assign ila_trig[15:00] = usb_fdata;
assign ila_trig[16:16] = usb_slrd;
assign ila_trig[17:17] = usb_empty;
assign ila_trig[18:18] = usb_slrd_reg;
assign ila_trig[19:19] = usb_full;
chipscope_icon chipscope_icon_inst (
.CONTROL0(CONTROL0) // INOUT BUS [35:0]
);
chipscope_ila chipscope_ila_inst (
.CONTROL(CONTROL0), // INOUT BUS [35:0]
.CLK(ifclk), // IN
.TRIG0(ila_trig) // IN BUS [19:0]
);
endmodule
这里使用到了Xilinx FPGA的两个IP核,ICON核,ILA核用来调试。
xilinx FPGA调试IP核的作用可以参考
Xilinx FPGA ChipScope的ICON/ILA/VIO核使用
这篇博文。
简单来讲,ICON是必须的,这是PC和FPGA JTAG通信的IP核。
ILA相当于逻辑分析仪的功能。
VIO是用来模拟IO,比如可以用于UART模拟发送数据给他。
ICON核这里不用设置:
直接点击Generate生成即可。
ILA这里需要更改他的采样深度。也可以不改
第二页设置中,需要改变Port Width,Port Width需要根据你实际情况来决定。
然后点击Generate.
3.添加xilinx FPGA的调试IP核到工程
将程序下载到FPGA中,打开chipscope,双击trigger setup。然后将usb_slrd改成下降沿触发。
将waveform里面的信号改成你程序中对应的信号名称。
4.下载调试工程
Chipscope显示的波形
和发送的一致,所以代码正确。
(注意:这里的顺序是因为他是大端模式,所以显示的不是01 08,而是08 01)