0

I am interfacing with a FT600 16-bit chip for USB3.0 communication. The computer will communicate through the FT600 to the FPGA and vice versa. I have created an FSM to assert appropriate signals and write Data to memory.

Problem: I assume the problem is with the FPGA code and not the hardware but it looks like only every other byte is correctly recorded into memory.

The timing diagram I am referring to is on page 16: http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT600Q-FT601Q%20IC%20Datasheet.pdf

This is my FSM code:

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

Any ideas/suggestions? If there already exists simple code for the FT600 as an example I would appreciate a link.

1 Answers1

0

Here's a tip: replace the huge case statement with this. It does exactly the same thing, but takes up far less space and is easier to understand:

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

The four assignments at the top of the block are called default assignments and are often useful to make code more compact and easier to understand.

Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44