2016-06-29 79 views
0

我與FT600 16位芯片的USB3.0通信接口。計算機將通過FT600與FPGA進行通信,反之亦然。我創建了一個FSM來聲明適當的信號並將數據寫入內存。FT600與FPGA連接

問題:我認爲問題出在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 
[email protected](*) 
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 
[email protected](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 
[email protected](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代碼作爲例子,我會很感激鏈接。

回答

0

下面是一個提示:用這個替換巨大的case語句。它不完全一樣的東西,但需要少得多的空間和更容易理解:

[email protected](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 

在塊頂部的四項作業被稱爲默認分配和往往是有用的,以使代碼更緊湊並且更容易理解。