2016-06-29 9 views
0

USB3.0 통신을 위해 FT600 16 비트 칩과 인터페이스하고 있습니다. 컴퓨터는 FT600을 통해 FPGA로 통신하고 그 반대의 경우도 마찬가지입니다. 적절한 신호를 표명하고 데이터를 메모리에 기록하기 위해 FSM을 만들었습니다.FPGA와의 인터페이스 FT600

문제점 : 문제는 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 

블록의 상단에있는 네 개의 과제

이 코드를보다 컴팩트하게 기본 할당라고 종종 유용있다 이해하기 쉽습니다.