1. 直线插补基础模块

任务目标

设计并实现一个用于单轴直线插补的FPGA基础模块。该模块接收目标位置与运动方向,输出位置计数与方向控制信号,用于验证直线插补中最基本的“位置-方向”联动逻辑。本案例聚焦于插补运算的底层支撑——位置累加与方向判定,不涉及多轴协同或速度规划。

模块功能定义

模块输入:clk(系统时钟)、rst_n(异步复位,低有效)、target_pos[15:0](目标位置,无符号数)、go(启动脉冲,高电平有效一个周期)。
模块输出:current_pos[15:0](当前位置计数)、dir(运动方向,1为正向/远离原点,0为负向/朝向原点)、done(到位标志,高电平表示已到达目标位置)。

工作逻辑:当go有效时,模块锁存目标位置并清零内部运行标志;每个时钟周期比较当前计数值与目标值,若未到达则按方向步进(递增或递减)当前位置;当当前位置等于目标位置时,done置高一个周期并停止运动。

Verilog核心实现

<code>module line_interp_base #(
    parameter DATA_WIDTH = 16
)(
    input  wire                     clk,
    input  wire                     rst_n,
    input  wire [DATA_WIDTH-1:0]    target_pos,
    input  wire                     go,
    output reg  [DATA_WIDTH-1:0]    current_pos,
    output reg                      dir,
    output reg                      done
);

    reg [DATA_WIDTH-1:0] target_reg;
    reg                  running;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            current_pos <= {DATA_WIDTH{1'b0}};
            target_reg   <= {DATA_WIDTH{1'b0}};
            dir          <= 1'b1;
            done         <= 1'b0;
            running      <= 1'b0;
        end
        else begin
            // 默认输出
            done <= 1'b0;

            if (go) begin
                target_reg <= target_pos;
                // 方向判定:目标大于当前则正向,否则负向
                dir <= (target_pos > current_pos) ? 1'b1 : 1'b0;
                running <= (target_pos != current_pos) ? 1'b1 : 1'b0;
            end
            else if (running) begin
                if (current_pos == target_reg) begin
                    running <= 1'b0;
                    done    <= 1'b1;
                end
                else if (dir) begin
                    current_pos <= current_pos + 1'b1;
                end
                else begin
                    current_pos <= current_pos - 1'b1;
                end
            end
        end
    end

endmodule

仿真验证方法

使用Verilog testbench验证模块行为。测试流程:

  1. 复位后确认current_pos=0、done=0。
  2. 设置target_pos=100,拉高go一个周期,观察dir应为1,随后每个时钟周期current_pos递增1,直到等于100时done输出一个周期高电平。
  3. 再次设置target_pos=50(小于当前值100),触发go,确认dir=0,current_pos递减至50后done置位。

通过条件:仿真波形中current_pos严格按单步加减到达目标值,dir方向正确,done在到达时刻恰好拉高一个时钟周期,且到达后位置保持不变。

关键点说明

  • 方向判定在go有效瞬间完成,基于当前计数值与目标值的比较结果,避免运行中方向抖动。
  • 当target_pos等于当前值时,go触发后running不置位,done也不会拉高——这是边界情况,如需“零行程完成”指示,可在go分支中增加done输出逻辑。
  • 本模块为纯组合步进逻辑,未做加减速规划,实际插补系统中该模块作为位置环基础,由上层速度规划器控制go信号的触发间隔。