使用FPGA控制4电动机



我正在尝试使用FPGA控制4电动机。(Verilog HDL)我使用Elways Block和自定义模块制作了一个代码(该模块控制一个伺服电机,并且它的输入值l_ctrl和r_ctrl确定伺服电动机是旋转是向左还是向右的一步)

这是自定义模块代码:

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

我制作了控制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

我猜我在侧面呼叫模块总是会导致错误。是否有其他算法/方法可以解决此问题?

谢谢。

虽然我不是100%确定您想要从Servo_Motor模块输出的输出,但似乎有很多误解Verilog如何合成FPGA配置。首先,正如您所认识的那样,您无法在always块中实例化模块;有关模块的解释以及如何使用它们:

,请参见此答案:

如何在Verilog中的IF语句中实例化模块?

基本上,模块是执行特定任务的设计中的结构,它们不像函数那样称为。就FPGA而言,它们是对硬件块的描述,以及它必须表现,它拥有的寄存器等。在当前代码中,您试图致电它们执行任务,然后"返回"结果,当您需要实例化它们(因此它们独立于direction)并使用其输出或不取决于direction

其他一些指针:

1)Servo模块没有启用行,因此在实例化模块的地方更改时,应将其删除。

2)使用非阻止分配(<=)进行寄存器(即时钟always块)和阻止分配(=)进行组合逻辑(就像您为Servo模块中的最后一个块所做的那样,这是正确的)。注意,REGCNT需要切换到NBA。

3)对于最后一个块(以及任何其他组合always块),请使用always @(*)而不是always @(CNT or REG),最好具有隐式灵敏度列表,而不是明确的,而不是避免闩锁

4)RESETN提出了一个断言的低重置,而您实现了一个主张的高复位。将网络命名为RESET或使用negedgeif (~RESETN)

5)integer类型仅用于模拟中,将这些reg [31:0]改为使用(或者您真正需要的许多位)。

希望这有助于澄清一些要点,思考RTL与编程大不相同。

相关内容

  • 没有找到相关文章

最新更新