循环型除法器

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

判断余数的正负 temp[15]为符号位,这里就不在细解了位操作了,慢慢 消化下面的代码就通了。
算法是活的,代码也是活的,只要抓到老鼠的(结果正确),吃饭少的 (资源消耗小)都是好猫。
差点忘了: 正负数的处理了:在带余数除法中,我们习惯将被除数与除数都化为正 数来计算。得出的余数应与被除数同号。 余数可以为负数吗??带余除法定理不是规定余数恒正??纳尼~~~~~ 大家可以在仿真看$display 输出。 我的另一篇文章对带余除法进行了一定的探讨,是我的想法,如果其中 有什么不对的,多多指教哈。 资源消耗:
Veirlog 算法分析:
值得注意的是我们发现 A-Bx2^3=R 公式中在每一操作中 A 在变,Bx2^
3 也在变。我们希望恒数多一点,
例 2:
A=10,B=3;
2^0 x 10 – 3 x 2^3 = -14 < 0 Q3=0
2^1 x 10 – 3 x 2^3 = -4 < 0 Q2=0
2^2 x 10 – 3 x 2^3 = 16 > 0 Q1=1
output[7:0] reminder , //余数
//signe
input start ,
output done
);
reg[15:0] ospace ; //操作空间 reg[15:0] temp ; reg[8:0] divisor_n ; //divisor 的负数
reg neg ; reg neg1; reg done_r ;
例 1: A=10,B=3;
10 – 3 x 2^3 = -14 < 0 Q3=0 10 – 3 x 2^2 = -2 < 0 Q2=0
10 – 3 x 2^1 = 4 > 0 Q1=1
4 – 3 x 2^0 = 1 > 0 Q0=1 则商 Q=1100=3 余数 R=1; 其实就是 第一步:判断 Q3 是否为一,Q3 是第四位权重为 2^3=8。为一的话说明 A 至少有 8 个 B,即 A – 8B >= 0,并把余数 R 赋给 A 进行下一步操作; 第二步:判断 Q2 是否为一,Q2 是第四位权重为 2^2=4。为一的话说明 A 至少有 4 个 B,即 A – 4B >= 0,并把余数 R 赋给 A 进行下一步操作; 第三步:判断 Q1 是否为一,Q1 是第四位权重为 2^1=2。为一的话说明 A 至少有 2 个 B,即 A – 2B >= 0,并把余数 R 赋给 A 进行下一步操作; 第三步:判断 Q1 是否为一,Q1 是第四位权重为 2^0=1。为一的话说明 A 至少有 1 个 B,即 A – B >= 0,并把余数 R 赋给 A 进行下一步操作; 思考中……
因为被除数除数均为 8 位二进制数所以操作次数为 8 次。 temp = ospace + {divisor_n,7'd0}; 相当于上面的 A-Bx2^3=R 只不过是 Bx2^3 变成了 8 而已。 if(temp[15]) ospace <= {ospace[14:0],1'b0}; else ospace <= {temp[14:0],1'b1};
reg[3:0] i ;
always @(posedge clk or negedge rst_n) if(!rst_n) begin ospace <= 16'd0 ; temp <= 16'd0 ; divisor_n <= 8'd0 ; neg <= 1'b0 ; neg1 <= 1'b0 ; done_r <= 1'b0 ; i <= 4'd0; end else if(start) case(i) 4'd0 :
仿真 代码为:
`timescale 1 ns/ 1 ps module divisor_vlg_tst();
reg clk; reg [7:0] dividend; reg [7:0] divisor; reg rst_n; reg start; // wires
wire done; wire [7:0] quotient; wire [7:0] reminder;
if(done) begin start <= 1'b0; i <= i + 1'b1; end else begin dividend <= 8'd125; divisor <= 8'd11; start<=1'b1; end end 4'd1 : begin if(done) begin start <= 1'b0; i <= i + 1'b1; end else begin dividend <= 8'd158; divisor <= 8'd18; start<=1'b1; end end 4'd2 : begin if(done) begin start <= 1'b0; i <= i + 1'b1; end else begin dividend <= 8'd254; divisor <= 8'd136; start<=1'b1; end end 4'd3 : begin if(done) begin start <= 1'b0; i <= i + 1'b1; end else begin dividend <= 8'd248; divisor <= 8'd77; start<=1'b1; end end 4'd4 : begin if(done) begin start <= 1'b0; i <= i + 1'b1; end else begin dividend <= 8'd17; divisor <= 8'd18; start<=1'b1; end end 4'd5 : begin if(done) begin start <= 1'b0; i <= i + 1'b1; end else begin dividend <= 8'd125; divisor <= 8'd11; start<=1'b1; end end 4'd6 : $stop; default : i <= 4'd0; endcase
endmodule
5. 日积月累
Xxx
6. 综合出的电路
xxxx 代码综合出的电路如下:
2013-8-18
begin neg <= dividend[7] ^ divisor[7] ; neg1 <= dividend[7]; ospace <= dividend[7] ? {8'd0,(~dividend + 1'b1)} : {8'd0, dividend}; divisor_n <= divisor[7] ? {1'b1 ,divisor} : {1'b1 ,(~divisor + 1'b1)}; i <= i + 1'b1;
divisor 详细设计方案
1. 循环型除法器简介:
补码除法器。
2. 循环型除法器规格:
八位循环型除法器。
3. 实现原理
首先我们看小学时代的一个公式:被除数 = 除数 X 商 + 余数 应因小学我们没学过负数,这里假定被除数与除数都是自然数。能不能 为负数呢?下面在说。 循环型触发器的原理其实也很简单就是:判断被除数有多少个除数,满 足的条件是商小于除数。如果用 C 语言写的话
#10 clk = ~clk; end
reg[3:0] i;
always @(posedge clk Baidu Nhomakorabear negedge rst_n) if(!rst_n) begin dividend <= 8'd0; divisor <= 8'd0; start <= 1'b0; i <= 4'd0; end else case(i) 4'd0 : begin
Q = 0; while(rmin << dsor) {
rmin = rmin – dsor; Q ++; } 这里它们都是正数哈,则计算的结果:Q 是商,rmin 是余数。 但是我们发现,当 rmin 和 dsor 大小不一样时,计算所花费的步骤将不 一样,这里我们要做的是一个,时钟消耗一样的除法器。 假设 被除数 A,除数 B,商 Q=Q3 Q2 Q1 Q0,余数 R 都是四位二进制数
仿真结果:
4. Verilog HDL 源代码
Verilog HDL 代码为:
module divisor
(
//system
input clk ,
input rst_n ,
//
input[7:0] divisor , //除数
input[7:0] dividend ,
//被除数
output[7:0] quotient , //商
A-Bx2^3=R >= 0 ? A-Bx2^2=R >= 0 ? A-Bx2^1=R >= 0 ? A-Bx2^0=R>= 0 ?
Q3=1 Q2=1 Q1=1 Q0=1

下一操作 A=R 下一操作 A=R 下一操作 A=R 下一操作 A=R
Q3=0 Q2=0 Q1=0 Q0=0

下一操作 A 不变 下一操作 A 不变 下一操作 A 不变 下一操作 A 不变
end 4'd9 :
begin done_r <= 1'b1; i <= i + 1'b1;
end 4'd10 :
begin done_r <= 1'b0; i <= 4'd0;
end default : i <= 4'd0;
endcase
assign quotient = neg ? (~ospace[7:0]+1'b1) : ospace[7:0]; assign reminder = neg1 ? (~ospace[15:8]+1'b1) : ospace[15:8]; assign done = done_r; endmodule
rst_n = 1'b0; clk = 1'b1; #20 rst_n = 1'b1; $dis play("% d\n", -4/3); $dis play("% d\n", -4% 3); $dis play("% d\n",4/-3); $display("% d\n",4% -3); $dis play("% d\n", -2/-120); $dis play("% d\n", -2% -120); forever
2^3 x 4
– 3 x 2^3 = 8 > 0
Q0=1
则商 Q=1100=3 余数 R / 2^3=1;
我们将例 1 中的等式分别乘于 1 2 4 8,就能发现被减数不变了。
核心代码:
4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8 : begin temp = ospace + {divisor_n,7'd0}; // divisor * 2^7 if(temp[15]) ospace <= {ospace[14:0],1'b0}; else ospace <= {temp[14:0],1'b1}; i <= i + 1'b1; end
end 4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8 :
begin temp = ospace + {divisor_n,7'd0}; // divisor * 2^7 if(temp[15]) ospace <= {ospace[14:0],1'b0}; else ospace <= {temp[14:0],1'b1}; i <= i + 1'b1;
// assign statements (if any) divisor i1 (
.clk (clk ), .dividend(dividend), .divisor(divisor), .done(done), .quotient(quotient), .reminder(reminder), .rst_n(rst_n), .start(start) ); initial begin
相关文档
最新文档