上一节实现了USB2.0 基于FPGA的同步写递增数据的操作,本节即实现简单的USB读取数据,所读取的数据使用黑金AX516开发板配套的EZ—USB。如果使用其他的上位机可能会导致电脑识别不了AX516的USB端口。首先明确一点我们在上一节所讲到的,我们的固件库烧进去的模式是工作在SLAVE FIFO的同步模式下,根据数据手册上面所提到的框图如下图所示:

根据上图可以看到我们设置为SLAVEFIFO模式后,所用到的端口以及端口的方向即如下图:

 

端口解释:

IFCLK:FX2输出的时钟,可作为通信的同步时钟。

FLAGA、FLAGB、FLAGC、FLAGD:FX2输出的FIFO状态信息,如满、空等。

SLCS:FIFO的片选信号,外部逻辑控制,当SLCS输出高时,不可进行数据传输。

SLOE:FIFO输出使能,外部逻辑控制,当SLOE无效时,数据线不输出有效数据。

SLRD:FIFO读信号,外部逻辑控制,同步读时,FIFO指针在SLRD有效时的每个IFCLK的上升沿递增,异步读时,FIFO读指针在SLRD的每个有效至无效的跳变沿时递增。

SLWR:FIFO写信号,外部逻辑控制,同步写时,在SLWR有效时的每个IFCLK的上升沿时数据被写入,FIFO指针递增,异步写时,在SLWR的每个有效至无效的跳变沿时数据被写入,FIFO写指针递增。

PKTEND:包结束信号,外部逻辑控制,在正常情况下,外部逻辑向FX2的FIFO中写数,当写入FIFO端点的字节数等于FX2固件设定的包大小时,数据将自动被打成一包进行传输,但有时外部逻辑可能需要传输一个字节数小于FX2固件设定的包大小的包,这时,它只需在写入一定数目的字节后,声明此信号,此时FX2硬件不管外部逻辑写入了多少字节,都自动将之打成一包进行传输。

FD[15:0]:数据线。

FIFOADR[1:0]:选择4个FIFO端点的地址线,外部逻辑控制。

 由此可以写出我们的端口信号:

 1 module   usb_read(                                   
 2                                                      
 3      input        wire               s_rst_n     ,   
 4      input        wire               usb_ifclk   ,   
 5      input        wire               usb_empty   ,   
 6      input        wire               usb_full    ,   
 7      output       wire               usb_slcs    ,   
 8      output       wire               usb_slwr    ,   
 9      output       wire               usb_slrd    ,   
10      output       wire               usb_sloe    ,   
11      output       wire      [1:0]    usb_fifoaddr,   
12      input        wire      [15:0]   usb_fifodata    
13                                                      
14                                                      
15                                                      
16 );                                                   

其中s_rst_n 是系统的复位信号。同步时钟使用USB芯片提供的的IFCLK-->usb_ifclk,在FLAG{2:0}中我们只使用了FLAGB读满标志和卸空标志,在同步度状态下使能相关端口,

1 assign                usb_slrd   =    (usb_empty ==1'b1&& usb_slrd_reg==1'b0)? 1'b0 : 1'b1;                              
2 assign                usb_slwr   =    1'b1 ;                                                                             
3 assign                usb_sloe   =    1'b0 ;                                                                             
4 assign                usb_slcs   =    1'b0 ;                                                                             
5 assign                usb_fifoaddr =  2'b00 ;                                                                            

SLOE是输出使能,拉低的时候有效。slcs片选信号低有效,FIFOADDR[1:0];4个FIFO配置与其中

00:代表2—out——FIFO端口,

01:代表4——out——FIFO端口,

10:代表6——in——FIFO端口 ,

11:  :代表8——in-----FIFO端口

88根据数据手册所给出的同步读的时序图:

 

通过时序图可以发现FLAGS标志位为高的时候数据可以读出来,可以推出读满的的标志位是在拉低的是后表示读空,由此为出发点画出同步读的时序图:

实现上图时序:

reg                       usb_slrd_reg                 ;
assign                usb_slrd   =    (usb_empty ==1'b1&& usb_slrd_reg==1'b0)? 1'b0 : 1'b1;  
//usb_slrd_reg                                            
always    @(posedge usb_ifclk or negedge s_rst_n)begin    
                     if(!s_rst_n)                                   
                usb_slrd_reg   <=      1'b1 ;             
           else if(usb_empty == 1'b1)                     
                usb_slrd_reg   <=      1'b0 ;             
           else                                           
                usb_slrd_reg   <=      1'b1 ;                  
end                                                       
 

 

除此意外我们希望加一个计数器计算接收到的数据是不是和我们发送的数据个数一致:
reg              [15:0]   usb_rd_cnt                   ;
//usb_rd_cnt                                            
always     @(posedge usb_ifclk or negedge s_rst_n)begin 
            if(!s_rst_n)                                
                usb_rd_cnt     <=      'd0 ;            
            else if(usb_slrd == 1'b0 )                  
                usb_rd_cnt   <=    usb_rd_cnt +  1'b1 ; 
end                                                     

接下就是如何使用CHIOPSCOP来抓取接收到的数据波形:加入ILA——IP核和icon IP核,并例化到我们的模块中:

/********************chiop   scop ***************************/    
                                                                  
wire    [35:0]                  CONTROL              ;            
wire    [35:0]                 ila_trig             ;             
                                                                  
assign       ila_trig[15:00] =  usb_fifodata          ;           
assign       ila_trig[16:16]=  usb_full              ;            
assign       ila_trig[17:17]=  usb_slrd_reg             ;         
assign       ila_trig[18:18]=  usb_slrd              ;            
assign       ila_trig[19:19]=  usb_empty             ;            
assign       ila_trig[35:20]=  usb_rd_cnt            ;            
                                                                  
//例化ILA_IP                                                      
                                                                  
chipscope_ila chipscope_ila_inst(                                 
    .CONTROL                (CONTROL ), // INOUT BUS [35:0]       
    .CLK                    (usb_ifclk), // IN                    
    .TRIG0                  (ila_trig ) // IN BUS [18:0]          
);                                                                
//lihua                                                           
chipscope_icon  chipscope_icon_inst(                              
    .CONTROL0               (CONTROL ) // INOUT BUS [35:0]        
);                                                                
                                                                  

这样就实现了,对USB对的数据进行抓取从而验证驱动是否正确。当然需要用到上位机Cypress。总体代码如下,验证就不贴图片了,大家可自行验证,总体代码如下:

 1 module   usb_read(                                                                                                               
 2                                                                                                                                  
 3      input        wire               s_rst_n     ,                                                                               
 4      input        wire               usb_ifclk   ,                                                                               
 5      input        wire               usb_empty   ,                                                                               
 6      input        wire               usb_full    ,                                                                               
 7      output       wire               usb_slcs    ,                                                                               
 8      output       wire               usb_slwr    ,                                                                               
 9      output       wire               usb_slrd    ,                                                                               
10      output       wire               usb_sloe    ,                                                                               
11      output       wire      [1:0]    usb_fifoaddr,                                                                               
12      input        wire      [15:0]   usb_fifodata                                                                                
13                                                                                                                                  
14                                                                                                                                  
15                                                                                                                                  
16 );                                                                                                                               
17                                                                                                                                  
18 /**********************************************************************                                                          
19 ****************define  parameter and signals**************************                                                          
20 ***********************************************************************/                                                         
21 reg                       usb_slrd_reg                 ;                                                                         
22 reg              [15:0]   usb_rd_cnt                   ;                                                                         
23 /**********************************************************************                                                          
24 *******************main  code *****************************************                                                          
25 ***********************************************************************/                                                         
26                                                                                                                                  
27                                                                                                                                  
28 assign                usb_slrd   =    (usb_empty ==1'b1&& usb_slrd_reg==1'b0)? 1'b0 : 1'b1;                                      
29 assign                usb_slwr   =    1'b1 ;                                                                                     
30 assign                usb_sloe   =    1'b0 ;                                                                                     
31 assign                usb_slcs   =    1'b0 ;                                                                                     
32 assign                usb_fifoaddr =  2'b00 ;                                                                                    
33 //usb_slrd_reg                                                                                                                   
34 always    @(posedge usb_ifclk or negedge s_rst_n)begin                                                                           
35                      if(!s_rst_n)                                                                                                          
36                 usb_slrd_reg   <=      1'b1 ;                                                                                    
37            else if(usb_empty == 1'b1)                                                                                            
38                 usb_slrd_reg   <=      1'b0 ;                                                                                    
39            else                                                                                                                  
40                 usb_slrd_reg   <=      1'b1 ;                                                                                                 
41 end                                                                                                                              
42 //usb_rd_cnt                                                                                                                     
43 always     @(posedge usb_ifclk or negedge s_rst_n)begin                                                                          
44             if(!s_rst_n)                                                                                                         
45                 usb_rd_cnt     <=      'd0 ;                                                                                     
46             else if(usb_slrd == 1'b0 )                                                                                           
47                 usb_rd_cnt   <=    usb_rd_cnt +  1'b1 ;                                                                            
48 end                                                                                                                              
49                                                                                                                                  
50 /********************chiop   scop ***************************/                                                                   
51                                                                                                                                  
52 wire    [35:0]                  CONTROL              ;                                                                           
53 wire    [35:0]                 ila_trig             ;                                                                            
54                                                                                                                                  
55 assign       ila_trig[15:00] =  usb_fifodata          ;                                                                          
56 assign       ila_trig[16:16]=  usb_full              ;                                                                           
57 assign       ila_trig[17:17]=  usb_slrd_reg             ;                                                                        
58 assign       ila_trig[18:18]=  usb_slrd              ;                                                                           
59 assign       ila_trig[19:19]=  usb_empty             ;                                                                           
60 assign       ila_trig[35:20]=  usb_rd_cnt            ;                                                                           
61                                                                                                                                  
62 //例化ILA_IP                                                                                                                     
63                                                                                                                                  
64 chipscope_ila chipscope_ila_inst(                                                                                                
65     .CONTROL                (CONTROL ), // INOUT BUS [35:0]                                                                      
66     .CLK                    (usb_ifclk), // IN                                                                                   
67     .TRIG0                  (ila_trig ) // IN BUS [18:0]                                                                         
68 );                                                                                                                               
69 //lihua                                                                                                                          
70 chipscope_icon  chipscope_icon_inst(                                                                                             
71     .CONTROL0               (CONTROL ) // INOUT BUS [35:0]                                                                       
72 );                                                                                                                               
73                                                                                                                                  
74                                                                                                                                  
75 endmodule