首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用FPGA控制4台电动机

用FPGA控制4台电动机
EN

Stack Overflow用户
提问于 2016-12-10 14:51:34
回答 1查看 463关注 0票数 0

我正试图用FPGA控制4台电机。(Verilog )我用始终块和自定义模块(它控制一个伺服电机,它的输入值-L_CTRL和R_CTRL确定伺服电机是向左或向右旋转一步)编写了一个代码。

以下是自定义模块代码:

代码语言:javascript
复制
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台电机的代码:

代码语言:javascript
复制
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

我想在侧调用模块总是会导致错误。是否有其他算法/方法来解决这个问题?

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-12 02:10:49

虽然我不能百分之百地确定你想从你的Servo_Motor模块中得到什么输出,但是对于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块),使用always @(*)而不是always @(CNT or REG),最好使用隐式灵敏度列表,而不是显式的,以避免锁存。

4) RESETN建议进行断言的低重置,而实现断言的高重置。要么将网络命名为RESET,要么使用negedgeif (~RESETN)

5) integer类型被指定为只用于模拟,而使这些reg [31:0] (或无论您真正需要多少位)。

希望这有助于澄清一些要点,在RTL中的思考与编程是非常不同的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41076823

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档