当前位置: 首页 > article >正文

数字图像处理(6):除法运算、除法器

(1)当除数是常数时,可以先转化为乘法,再右移,乘法的N越大,计算误差越小。

        如:计算x/122,可以看成(x * 67)>>13,N=13,使用verilog实现:

reg     [15:0]  x;
reg     [9:0]   y;
//y= x /122
assign y = ((x << 6) + (x << 1) + x) >> 13;

(2)使用状态机实现一个除法器

预算规则:

  • 将除数扩大到和被除数同位宽,比较其大小。
  • 如果被除数更大,则上位1;反之,上位0。如果被除数更大,临时除数要等于被除数减掉对应扩大后的除数,反之不用。
  • 继续前两步骤,直至被除数同临时被除数同位宽。
module divide #(
    parameter IW = 32,      // 被除数位宽
    parameter DW = 9,       // 除数位宽
    parameter OW = IW-DW    // 商的位宽
)(
    input  wire             clk,
    input  wire             reset,
    input  wire             valid_i,
    input  wire [IW-1:0]    dividend,    // 被除数
    input  wire [DW-1:0]    divisor,     // 除数
    output reg              valid_o,      // 输出有效信号
    output reg  [OW-1:0]    quotient,    // 商
    output reg  [DW-1:0]    remainder    // 余数
);

// 内部信号定义
reg [IW-1:0]    dividend_reg;    // 被除数寄存器
reg [DW-1:0]    divisor_reg;     // 除数寄存器
reg [OW-1:0]    quotient_temp;   // 临时商
reg [IW-1:0]    diff;            // 差值
reg [5:0]       count;           // 计数器
reg             busy;            // 除法器忙状态
reg [IW-1:0]    shifted_divisor; // 移位后的除数

// 状态定义
localparam IDLE = 3'b001;
localparam CALC = 3'b010;
localparam DONE = 3'b100;
reg [2:0] state;

// 状态机和除法逻辑
always @(posedge clk or posedge reset) begin
    if (reset) begin
        state <= IDLE;
        busy <= 1'b0;
        valid_o <= 1'b0;
        quotient <= {OW{1'b0}};
        remainder <= {DW{1'b0}};
        count <= 6'd0;
    end
    else begin
        case (state)
            IDLE: begin
                if (valid_i && !busy) begin
                    if (divisor == 0) begin  // 除数为0检查
                        state <= DONE;
                        quotient <= {OW{1'b1}};  // 设置为最大值表示错误
                        remainder <= {DW{1'b1}};
                        valid_o <= 1'b1;
                    end
                    else begin
                        state <= CALC;
                        busy <= 1'b1;
                        valid_o <= 1'b0;
                        dividend_reg <= dividend;
                        divisor_reg <= divisor;
                        quotient_temp <= {OW{1'b0}};
                        count <= OW;
                        shifted_divisor <= divisor << (OW-1);  // 初始移位
                    end
                end
            end

            CALC: begin
                if (count > 0) begin
                    if (dividend_reg >= shifted_divisor) begin
                        dividend_reg <= dividend_reg - shifted_divisor;
                        quotient_temp[count-1] <= 1'b1;
                    end
                    else begin
                        quotient_temp[count-1] <= 1'b0;
                    end
                    
                    shifted_divisor <= shifted_divisor >> 1;
                    count <= count - 1;
                end
                else begin
                    state <= DONE;
                end
            end

            DONE: begin
                quotient <= quotient_temp;
                remainder <= dividend_reg[DW-1:0];
                valid_o <= 1'b1;
                busy <= 1'b0;
                state <= IDLE;
            end

            default: begin
                state <= IDLE;
            end
        endcase
    end
end

endmodule


http://www.kler.cn/a/411576.html

相关文章:

  • Jmeter中的测试片段和非测试原件
  • webrtc支持h265
  • web day03 Maven基础 Junit
  • C++ 优先算法 —— 无重复字符的最长子串(滑动窗口)
  • 第十六届蓝桥杯模拟赛第二期题解—Java
  • 计算机网络的功能
  • 【C++知识总结1】c++第一篇,简单了解一下命名空间是什么
  • C++设计模式之组合模式中适用缓存机制提高遍历与查找速度
  • lc 146. LRU 缓存
  • 【系统架构设计师】真题论文: 论软件系统架构评估(包括解题思路和素材)
  • HDR视频技术之四:HDR 主要标准
  • 跨子网通信的具体流程
  • 【后端面试总结】MySQL索引
  • 学习日记_20241126_聚类方法(聚合聚类Agglomerative Clustering)
  • 构建与优化数据仓库-实践指南
  • ES6的第四天
  • huggingface使用
  • 【C++】读取数量不定的输入数据
  • 结构方程模型(SEM)入门到精通:lavaan VS piecewiseSEM、全局估计/局域估计;潜变量分析、复合变量分析、贝叶斯SEM在生态学领域应用
  • 无人机舵机转速运行原理!
  • Django 路由层
  • java——Tomcat调优策略
  • Prometheus从二进制部署迁移Docker中更新到v3.0.0版本
  • 【前端】ES6基础
  • 【二叉树】【2.1遍历二叉树】【刷题笔记】【灵神题单】
  • 【小白学机器学习36】关于独立概率,联合概率,交叉概率,交叉概率和,总概率等 概念辨析的例子