除法计算器(补码一位除法)

文章详细描述了一个改进的笔算除法器的电路设计,包括操作码处理、寄存器结构、计数器控制和结果更新。作者指出原始版本存在控制问题,并提出将移位操作与是否加回原码和上商控制分离。同时还展示了相关仿真的过程。
摘要由CSDN通过智能技术生成

笔算除法

在这里插入图片描述

第一个版本的除法器

在这里插入图片描述
缺点
在这里插入图片描述

第二个版本的除法器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
实现代码

module alu  (
    input                   rst         ,
    input                   clk         ,
    input       [ 2:0]      Opcode      ,
    // multiplication Opcode is 110
    // add code is 100
    // sub code is 101
    // div code is 110 
    input       [31:0]      Operand_X   ,
    input       [31:0]      Operand_Y   ,
    output reg              Busy        ,
    output reg              Cout        ,
    output reg  [63:0]      Result
);

// Complement one digit div, the default input is already a complement!
reg     [31:0]      Add_A                        ;
reg     [31:0]      Add_Result = 32'b0           ;
reg     [ 4:0]      Mul_Counter                  ;
reg     [31:0]      Dividend, Operand_Y_inner    ;

// just sub
always @(Add_A) begin  
    {Cout, Add_Result} <= Add_A + ~Operand_Y_inner + 1'b1;
end

// Mul_Counter register
always @(posedge rst or posedge clk) begin
    if (rst) begin
        Mul_Counter <= 5'b00000;
    end else if (Opcode == 3'b111) begin
        Mul_Counter <= 5'b11111;
    end else if (Busy) begin
        Mul_Counter <= Mul_Counter - 1;
    end
end

// Busy
always @(posedge rst or posedge clk) begin
    if (rst) begin
        Busy <= 1'b0;
    end else if (Opcode == 3'b111) begin
        Busy <= 1'b1;
    end else if (Busy == 1'b1 & Mul_Counter == 5'b00000) begin
        Busy <= 1'b0;
    end
end

// divisor register in_Y
always @(posedge rst or posedge clk) begin
    if (rst) begin
        Dividend <= 32'b0;
    end else if (Opcode == 3'b111) begin
        Dividend <= Operand_Y;
    end
end

// Result register
always @(posedge rst or posedge clk) begin
    if (rst) begin
        Result <= 64'b0;
    end else if (Opcode == 3'b111) begin
        // initial Result
        Result <= {31'b0, Operand_X, 1'b0};
    end else if (~Add_Result[31]) begin
        // if 0, quotient is 1
        Result <= {Add_Result[30:0], Result[31:0], 1'b1};
    end else begin
        // if 1, just shift, quotient is 0
        Result <= {Result[62:0], 1'b0};
    end
end

// adder inA is Add_A
always @(Result or Operand_X or Operand_Y) begin
    if (Busy) begin
        Add_A <= Result[63:32];
    end else begin
        Add_A <= Operand_X    ;
    end
end

// Operand_Y_inner
always @(Busy or Dividend or Operand_Y) begin
    if (Busy) begin
        Operand_Y_inner <= Dividend;
    end else begin
        Operand_Y_inner <= Operand_Y   ;
    end
end

endmodule

虽然代码能跑通,结果也对,但是感觉写的不是很好。
我的理解是,不要在移位时控制是否要加回原码和上商为1或0,最好能和移位控制分离。

仿真

`timescale  1ns / 1ps

module tb_alu();

// alu Parameters
parameter PERIOD  = 20;


// alu Inputs
reg   rst                                  = 0 ;
reg   clk                                  = 0 ;
reg   [ 2:0]  Opcode                       = 0 ;
reg   [31:0]  Operand_X                    = 0 ;
reg   [31:0]  Operand_Y                    = 0 ;

// alu Outputs
wire  Busy                                 ;
wire  Cout                                 ;
wire  [63:0]  Result                       ;


initial begin
    forever #(PERIOD/2)  clk=~clk;
end

initial begin
    rst = 1'b1;
    #25 rst = 1'b0;
    Opcode = 3'b111;
    Operand_X = 32'h0006;
    Operand_Y = 32'h0002;
    #10 Opcode = 3'b000;
end


alu  u_alu (
    .rst                     ( rst               ),
    .clk                     ( clk               ),
    .Opcode                  ( Opcode     [ 2:0] ),
    .Operand_X               ( Operand_X  [31:0] ),
    .Operand_Y               ( Operand_Y  [31:0] ),

    .Busy                    ( Busy              ),
    .Cout                    ( Cout              ),
    .Result                  ( Result     [63:0] )
);

endmodule

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值