← 2022 · 小米 笔试

推荐答案 测试一下

除法器的Verilog RTL实现。16bitA,8bitB。C=A/B (15分)

题目配图 题目配图
编程题 中等 笔试真题

参考答案

采用基于移位减法的恢复余数除法器实现无符号除法。算法步骤:将16位被除数A扩展为32位(高16位为0,低16位为A),8位除数B左对齐至16位(即B<<8)。重复8次循环:每次将当前余数左移一位,将商左移一位,比较当前余数的高16位与除数B;若余数高16位≥B,则余数减B并将商的最低位设为1,否则商最低位为0。8次循环后,得到16位商C和16位余数。考虑到除法器需要组合逻辑或有限状态机实现,以下给出基于FSM的RTL代码框架: module divider ( input clk, rst_n, input start, // 启动信号 input [15:0] A, // 被除数 input [7:0] B, // 除数 output reg [15:0] C, // 商 output reg [15:0] rem, // 余数 output reg done // 完成标志 ); reg [4:0] cnt; // 循环计数器,0~7 reg state; localparam IDLE=0, CALC=1; reg [31:0] tmp_A; // 32位,低16位为被除数,高16位为当前余数 reg [15:0] tmp_C; reg [15:0] divisor; // 除数左对齐至16位 always @(posedge clk or negedge rst_n) begin if(!rst_n) begin state <= IDLE; done <= 0; cnt <= 0; C <= 0; rem <= 0; tmp_A <= 0; tmp_C <= 0; divisor <= 0; end else begin case(state) IDLE: begin if(start) begin tmp_A <= {16'd0, A}; divisor <= {B, 8'd0}; cnt <= 0; tmp_C <= 0; state <= CALC; done <= 0; end end CALC: begin if(cnt < 8) begin // 左移一位 tmp_A <= {tmp_A[30:0], 1'b0}; tmp_C <= {tmp_C[14:0], 1'b0}; // 比较高16位与除数 if(tmp_A[31:16] >= divisor) begin tmp_A[31:16] <= tmp_A[31:16] - divisor; tmp_C[0] <= 1'b1; end cnt <= cnt + 1; end else begin C <= tmp_C; rem <= tmp_A[31:16]; done <= 1; state <= IDLE; end end endcase end end endmodule 注意:除法器输入需考虑除数为0的情况,可在开始前判断B是否为0,若为0则产生错误标志;本实现为无符号除法,对于有符号除法需额外处理符号位;为简化代码,未做流水线优化,实际应用中可增加流水寄存器提升吞吐量;易错点包括位宽对齐、循环次数正确性、比较器件选择(使用大于等于而非大于)以及组合逻辑与时序逻辑的混用。

涉及知识点

  • 恢复余数除法算法
  • 状态机设计方法
  • 移位减法实现原理
  • Verilog时序逻辑建模
  • 除数为0的处理
← 上一题
登录后反馈错题
下一题 →