FX2LP与FPGA的简单批量回环

我需求将FPGA处理的视频数据通过USB发送给电脑,先实现一个小目标,做一个简单的数据回环。

利用赛普拉斯EZ-USB FX2LP系列USB2.0的接口控制器,固件配置好为异步批量模式,并通过官方提供的Control Center进行测试。

上图是FX2LP连接至FPGA时所需的硬件连接

它们之间的接口信号说明如下

  • FLAGA    OUT FIFO空标志位,高电平表示非空
  • FLAGC    IN FIFO满标志位,高电平表示不满
  • SLCS      片选信号,低电平有效
  • SLOE           输出使能,低电平有效
  • SLRD                读控制,低电平有效
  • SLWR               写控制,低电平有效
  • FIFOADR[1:0]  FIFO地址选择,2'b00为OUT FIFO地址,2'b10为IN FIFO地址
  • FD[15:0]           双向数据信号

设计时参看规格书给出的时序图

从时序图中,大致可以看出在异步模式下,数据是在SLWR和SLRD的上升沿读入读出,

 

设计时序如上图,时钟选取为10MHz

下面附上具体代码

module usb_loop(
    input    sys_clk_p    ,
    input    sys_clk_n    ,
    input    reset_n        ,
    
    input    usb_flaga    ,
    input    usb_flagc    ,
    
    output    reg    [1:0]    usb_fifoaddr    ,
    output    reg            usb_slcs        ,
    output    reg            usb_sloe        ,
    output    reg            usb_slrd        ,
    output    reg            usb_slwr        ,
    
    inout        [15:0]    usb_fd
    );

    reg    usb_fd_en;
    reg    [15:0]    usb_data;
    
    //    Clock
    //    differential clock -> single clock -> 10MHz clock
    wire    sys_clk        ;
    IBUFGDS    buf_clk    (
    .I    (sys_clk_p    ),
    .IB    (sys_clk_n    ),
    .O    (sys_clk    )
    );
    
    pll_10    u_pll_10    (
    .clk_in1   (sys_clk    ),    // 200Mhz
    .clk_out1  (clk_10    )    // 10Mhz
    );
    
    
    
    // count
    reg    flag_cnt;
    reg [2:0]    cnt;
    wire add_cnt;
    wire end_cnt;
    always @(posedge clk_10 or negedge reset_n) begin
        if(reset_n == 0)
            cnt <= 0;
        else if(add_cnt) begin
            if(end_cnt)
                cnt <= 0;
            else
                cnt <= cnt + 1;
        end
    end
    assign add_cnt = flag_cnt;
    assign end_cnt = add_cnt && cnt == 6 - 1;
    
    always @(posedge clk_10 or negedge reset_n) begin
        if(reset_n == 0)
            flag_cnt <= 0;
        else if(flag_cnt == 0 && usb_flaga == 1 && usb_flagc == 1)
            flag_cnt <= 1;
        else if(end_cnt)
            flag_cnt <= 0;
    end
    
    
    
    always @(posedge clk_10 or negedge reset_n) begin
        if(reset_n == 0)
            usb_slcs <= 1;
        else
            usb_slcs <= 0;
    end
    
    /*
    cnt        0    1    2    3    4    5
    addr    0    0    0    2    2    2
    slrd    1    0    1    1    1    1
    sloe    1    0    1    1    1    1
    slwr    1    1    1    1    0    1
    */
    always @(posedge clk_10 or negedge reset_n) begin
        if(reset_n == 0)
            usb_fifoaddr <= 0;
        else if(add_cnt && cnt == 3 - 1)
            usb_fifoaddr <= 2'b10;
        else if(end_cnt)
            usb_fifoaddr <= 0;
    end
    
    always @(posedge clk_10 or negedge reset_n) begin
        if(reset_n == 0)
            usb_slrd <= 1;
        else if(add_cnt && cnt == 1 - 1)
            usb_slrd <= 0;
        else if(add_cnt && cnt == 2 - 1)
            usb_slrd <= 1;
    end
    
    always @(posedge clk_10 or negedge reset_n) begin
        if(reset_n == 0)
            usb_sloe <= 1;
        else if(add_cnt && cnt == 1 - 1)
            usb_sloe <= 0;
        else if(add_cnt && cnt == 2 - 1)
            usb_sloe <= 1;
    end
    
    always @(posedge clk_10 or negedge reset_n) begin
        if(reset_n == 0)
            usb_slwr <= 1;
        else if(add_cnt && cnt == 4 - 1)
            usb_slwr <= 0;
        else if(add_cnt && cnt == 5 - 1)
            usb_slwr <= 1;
    end
    
    assign usb_fd = (usb_fd_en) ? usb_data : 16'hz;
    
    always @(posedge clk_10 or negedge reset_n) begin
        if(reset_n == 0)
            usb_data <= 0;
        else if(add_cnt && cnt == 2 - 1)
            usb_data <= usb_fd; 
    end
    
    always @(posedge clk_10 or negedge reset_n) begin
        if(reset_n == 0)
            usb_fd_en <= 0;
        else if(add_cnt && cnt == 3 - 1)
            usb_fd_en <= 1;
        else if(end_cnt)
            usb_fd_en <= 0;
    end
    
endmodule
View Code
原文地址:https://www.cnblogs.com/qingkai/p/8665723.html