2016-12-10 7 views
0

FPGA를 사용하여 4 개의 모터를 제어하려고합니다. (의 Verilog HDL) 제가 차단 커스텀 모듈 항상 이용하는 코드를 만들었다 (하나 개의 서보 모터를 제어하는, 그리고 값-L_CTRL 및 R_CTRL 서보 모터가 왼쪽으로 한 단계를 회전 또는 우측의 여부를 판정 입력이다) 여기서 FPGA를 사용하여 4 개의 모터 제어

맞춤 모듈 번호 :

module Servo(CLK, RESETN, L_CTRL, R_CTRL, SERVO); 

input CLK; 
input RESETN, L_CTRL, R_CTRL; 
output SERVO; 
integer REG, CNT; 
reg L, R; 
reg SERVO; 

always @(posedge RESETN or posedge CLK) 
begin 
    if (RESETN) CNT = 0; 
    else 
    if (CNT >= 199) CNT = 0; 
    else CNT = CNT + 1; 
end 

always @(posedge RESETN or posedge CLK) 
begin 
    if (RESETN) 
     REG = 15; 
    else 
    begin 
    L <= L_CTRL; R <= R_CTRL; 
    if (L == 0 & L_CTRL & REG > 7) 
     REG = REG - 1; 
    else if (R == 0 & R_CTRL & REG < 23) 
     REG = REG + 1; 
    end 
end 

always @(CNT or REG) 
begin 
if (CNT < REG) 
    SERVO = 1; 
else 
    SERVO = 0; 
end 
endmodule 

및 I 4 개 모터를 제어하기위한 코드를 만들어 : 항상 블록이 에러를 야기 측 모듈을 호출 추측

module Servo_Motor(direction,CLK,RESETN,SERVO); 
    input [1:0]direction; 
    input CLK, RESETN; 

    reg L_CTRL, R_CTRL; 
    reg [3:0] SERVO; 
    output [3:0] SERVO; 
    //servo0, servo1->x_axis 
    //servo2, servo3->y_axis 

    always @(posedge RESETN or posedge CLK) 
    begin 
     if(direction==2'b01)//east 
     begin 
      L_CTRL<=0; R_CTRL<=1; 
      Servo S0(CLK, RESETN, L_CTRL, R_CTRL, SERVO[0], enable_0); 
      Servo S1(CLK, RESETN, L_CTRL, R_CTRL, SERVO[1], enable_1); 
      SERVO[2]<=0; 
      SERVO[3]<=0;    
     end 

     else if(direction==2'b11)//SOUTH 
     begin 
      L_CTRL<=1; R_CTRL<=0; 
      Servo S2(CLK, RESETN, L_CTRL, R_CTRL, SERVO[2], enable_2); 
      Servo S3(CLK, RESETN, L_CTRL, R_CTRL, SERVO[3], enable_3); 
      SERVO[0]<=0; 
      SERVO[1]<=0; 
     end 

     else if(direction==2'b10)//WEST 
     begin 
      L_CTRL<=1; R_CTRL<=0; 
      Servo S0(CLK, RESETN, L_CTRL, R_CTRL, SERVO[0], enable_0); 
      Servo S1(CLK, RESETN, L_CTRL, R_CTRL, SERVO[1], enable_1); 
      SERVO[2]<=0; 
      SERVO[3]<=0;  
     end 

     else if(direction==2'b00)//NORTH 
     begin 
      L_CTRL<=0; R_CTRL<=1; 
      Servo S2(CLK, RESETN, L_CTRL, R_CTRL, SERVO[2], enable_2); 
      Servo S3(CLK, RESETN, L_CTRL, R_CTRL, SERVO[3], enable_3); 
      SERVO[0]<=0; 
      SERVO[1]<=0; 
     end 
    end 
endmodule 

. 이 문제를 해결하기위한 대안 알고리즘/방법이 있습니까?

감사합니다.

답변

1

Servo_Motor 모듈에서 원하는 출력을 100 % 확신 할 수는 없지만 Verilog가 FPGA 구성으로 합성하는 방법에 대한 오해가 많이있는 것처럼 보입니다. 맨 먼저, 당신이 알고 있듯이 always 블록에 모듈을 인스턴스화 할 수 없습니다. 모듈의 설명과 어떻게 사용해야이 대답을 참조하십시오

How can i instantiate a module inside an if statement in verilog?

는 기본적으로 모듈은 특정 작업을 수행 설계 내에서 구조, 그들은 함수처럼 호출되지 않습니다. FPGA의 관점에서 하드웨어 블록과 동작 방식, 레지스터 등을 설명합니다. 현재 코드에서는 태스크를 수행하도록 호출 한 다음 결과를 "반환"합니다 , 당신이 그들을 인스턴스화 할 필요가있을 때 (따라서 그것들은 direction과 독립적으로 존재하며) direction에 따라 그들의 출력을 사용하는지 아닌지를 사용합니다.

다른 몇 가지 포인터 :

1) 라인을 사용하기 때문에 모듈을 인스턴스화 위치를 변경할 때 당신이 그것을 제거해야이 나던 Servo 모듈.

2) 레지스터에 대한 비 블로킹 할당 (<=)를 사용 (즉, always 블록 클럭) 및 조합 논리에 대한 차단 할당 (=) (당신이 Servo 모듈의 마지막 블록처럼, 올바른 이잖아). 참고 : REGCNT은 NBA로 전환해야합니다.

3) 마지막 블록 (및 기타 조합 always 블록), 그것의 더 나은

4) RESETN는 주장 로우 리셋을 제안 래치 피하기 위해 오히려 명시 적보다 암시 감도 목록을 가지고, always @(*)보다는 always @(CNT or REG)를 사용하기 위해 , 어설 션된 높은 재설정을 구현하는 동안. 어느 그들이, negedgeif (~RESETN)

5) integer 유형 만 시뮬레이션에 사용되도록 지정된 사용 당신이 정말로 필요로이 대신 reg [31:0] (또는 그러나 많은 비트)를 만들 수있는 RESET라는 이름의 네트를합니다.

이것이 도움이되기를 바랍니다. RTL에서 생각하는 것이 프로그래밍과 매우 다릅니다.