0

我正在与用于 USB3.0 通信的 FT600 16 位芯片连接。计算机将通过 FT600 与 FPGA 进行通信,反之亦然。我创建了一个 FSM 来断言适当的信号并将数据写入内存。

问题:我认为问题出在 FPGA 代码而不是硬件上,但看起来只有每隔一个字节正确记录到内存中。

我指的时序图在第 16 页:http: //www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT600Q-FT601Q%20IC%20Datasheet.pdf

这是我的 FSM 代码:

parameter [4:0] S1 =    5'd0, //Neutral state
                        S2 =    5'd1, //Data transfer from FPGA to Computer
                        SA_1 = 5'd8,
                        SA_2 = 5'd9,
                        S3 =    5'd2, //Data transfer from Computer to FPGA
                        S4 =    5'd3,
                        S5 =    5'd4,
                        S6 =    5'd5,
                        S7 =    5'd6,
                        S8 =    5'd7;
reg [4:0] state=0;
reg [4:0] nstate=0;

//wire [15:0] wdata;
wire [15:0] rdata;
//Counter c1 (wdata, Cclock);

assign rdata = (state == S5) ? DATA_I :  rdata; //Holds the recieved data on DATA
assign DATA_O = (state == S7) ? rdata :  16'bz; //rdata : 16'bz;    //{8'h41,8'h41} :  16'bz; //Sends the transmitted data on DATA
reg OE_N_reg = 1;//Confirmation signal when Computer writes data to FPGA
reg RD_N_reg = 1;//Confirmation signal when Computer writes data to FPGA
reg WR_N_reg = 1;//Confirmation signal when FPGA writes data to Computer

assign OE_N = OE_N_reg;
assign RD_N = RD_N_reg;
assign WR_N = WR_N_reg;

//ByteEnable configuration based on state
assign BE[0] = (state == S3) ? 1'bz :  1; 
assign BE[1] = (state == S3) ? 1'bz :  1;

//Debugging outputs
//assign GPIO_O[7:3] = 0;
//assign GPIO_O[2] = OE_N;
//assign GPIO_O[3] = RD_N;
//assign GPIO_O[4] = WR_N;
//assign GPIO_O[7:5] = DATA[2:0];

//State Logic
always@(*) 
begin
    case(state)
        S1:if(TXE_N == 0)
            begin
                    nstate <= S2;
            end

            else
            begin
                if(RXF_N == 0)
                begin
                    nstate <= SA_1;
                end

                else
                begin
                    nstate <= S1;
                end
            end

        S2:if(TXE_N == 0)
            begin
                nstate <= SA_2;
            end

            else
            begin
                nstate <= S1;       
            end
        SA_1: if(RXF_N == 0)
            begin
                nstate <= S3;
            end

            else
            begin
                nstate <= S1;   
            end 
        S3:if(RXF_N == 0)
            begin
                nstate <= S4;
            end

            else
            begin
                nstate <= S1;   
            end
        S4:if(RXF_N == 0)
            begin
                nstate <= S5;
            end

            else
            begin
                nstate <= S1;   
            end
        S5:if(RXF_N == 0)
            begin
                nstate <= S5;
            end

            else
            begin
                nstate <= S6;   
            end
        S6: nstate <= S1;
        SA_2: if(TXE_N == 0)
            begin
                nstate <= S7;
            end

            else
            begin
                nstate <= S1;
            end
        S7: if(TXE_N == 0)
            begin
                nstate <= S7;
            end

            else
            begin
                nstate <= S8;       
            end
        S8: nstate <= S1;


        default:    nstate <= S1;

    endcase
end

//Output Assignment
always@(negedge S_AXI_ACLK) 
begin
    case(state)
        S1: begin

            RD_N_reg <= 1;
            WR_N_reg <= 1;
            OE_N_reg <= 1;
            DATA_T   <= 1;
            end

        S2: begin

            RD_N_reg <= 1;
            WR_N_reg <= 1;
            OE_N_reg <= 1;
            DATA_T   <= 1;
            end
        SA_1: begin

            RD_N_reg <= 1;
            WR_N_reg <= 1;
            OE_N_reg <= 1;
            DATA_T   <= 1;
            end

        S3: begin

            RD_N_reg <= 1;
            WR_N_reg <= 1;
            OE_N_reg <= 1;
            DATA_T   <= 1;
            end
        S4: begin

            RD_N_reg <= 1;
            WR_N_reg <= 1;
            OE_N_reg <= 0;
            DATA_T   <= 1;
            end
        S5: begin

            RD_N_reg <= 0;
            WR_N_reg <= 1;
            OE_N_reg <= 0;
            DATA_T   <= 1;
            end
        S6: begin

            RD_N_reg <= 1;
            WR_N_reg <= 1;
            OE_N_reg <= 1;
            DATA_T   <= 1;
            end
        SA_2: begin

            RD_N_reg <= 1;
            WR_N_reg <= 1;
            OE_N_reg <= 1;
            DATA_T   <= 1;
            end
        S7: begin

            RD_N_reg <= 1;
            WR_N_reg <= 0;
            OE_N_reg <= 1;
            DATA_T   <= 0;
            end
        S8: begin

            RD_N_reg <= 1;
            WR_N_reg <= 1;
            OE_N_reg <= 1;
            DATA_T   <= 1;
            end


        default:    begin

            RD_N_reg <= 1;
            WR_N_reg <= 1;
            OE_N_reg <= 1;
            DATA_T   <= 1;
                    end
    endcase
end


//Update states
always@(negedge S_AXI_ACLK) 
begin
    state <= nstate;
end

//RECORD rdata INTO MEM:
always @(negedge Bus2IP_Clk) 
begin
    if((RD_N == 0)) begin
        s <= s+(11'd15);
        ram[0][0][s] <= rdata[15:0];
    end
    read_address <= mem_address; //AXI4 stuff
end

有什么想法/建议吗?如果已经存在 FT600 的简单代码作为示例,我将不胜感激链接。

4

1 回答 1

0

这里有一个提示:用这个替换巨大的 case 语句。它做的事情完全相同,但占用的空间要少得多,而且更容易理解:

always@(negedge S_AXI_ACLK) 
begin
    RD_N_reg <= 1;
    WR_N_reg <= 1;
    OE_N_reg <= 1;
    DATA_T   <= 1;
    case(state)
        S4: OE_N_reg <= 0;
        S5: begin
            RD_N_reg <= 0;
            OE_N_reg <= 0;
            end
        S7: begin
            WR_N_reg <= 0;
            DATA_T   <= 0;
            end
    endcase
end

块顶部的四个赋值称为默认赋值,通常有助于使代码更紧凑、更易于理解。

于 2016-06-30T15:08:34.833 回答