循环型的除法器(实现两个8位整数的除法)

来源:互联网 发布:薛之谦抄袭 知乎 编辑:程序博客网 时间:2024/04/27 19:40

循环型的除法器,如果用笔者的话来说,就是位操作的除法器。循环型的除法器是典型的硬件除法器,假设除数和被除数的位宽为N 位,那么除法器就需要循环N 次完成除法操作,结果取得“N 位商和N 位余”。假设被除数A =10,除数B = 3,为了使除数B大于除数A,让B‘  = B*2^m, 假设m  = 6,R为余数,Q为商。


循环结束,R = 64*2 =128 ,正确的R '= R/2^(m+1) = 128/128 =1,Q = 0000011

/*************************************************************************************************************
作者:冬瓜
时间:2015.7.16
功能:两个8位数(整数)的除法,

************************************************************************************************************/
module cycle_divider
(
clk,rst_n,
a,b,c,d,
is_start_sig,
is_done_sig
);
input clk,rst_n;//时钟,复位信号
input [ 7:0 ]a;//被除数
input [ 7:0 ]b;//除数
output [ 7:0 ]c,d;//商,余数
input is_start_sig;//开始信号
output is_done_sig;//结束信号

reg [ 3:0 ]state;
reg [ 7:0 ]s;
reg [ 7:0 ]q;
reg [ 15:0 ]_s;
reg rDone,rNeg;
reg [ 15:0 ]r;

always @( posedge clk or negedge rst_n )
if( !rst_n )
begin 
state <= 'd0;
s <= 'd0;
_s <= 'd0;
r <= 'd0;
q <= 'd0;
rDone <= 'd0;
rNeg <= 'd0;
end
else if( is_start_sig )
case( state )
'd0: begin 
rNeg <= a[ 7 ]^b[ 7 ];
s <= b[ 7 ]? ( ~b + 1'b1 ): b;//取除数的绝对值
state <= state + 1'b1;
_s <= b[ 7 ]?{ 8'hff,b }:{ 8'hff,~b + 1'b1 };
r <= a[ 7 ]?{ 8'd0,~a + 1'b1 }:{ 8'd0,a }; end

         'd1,'d2,'d3,'d4,         'd5,'d6,'d7,'d8:                 if( r < ( s<<7 ) ) begin q[ 8-state ] <= 1'b0; r <= r<<1; state <= state + 1'b1; end                else begin q[ 8-state ] <= 1'b1; r <= ( r + ( _s<<7) )<<1; state <= state + 1'b1; end         'd9: begin rDone <= 1'b1; state <= state + 1'b1;  end         'd10:begin rDone <= 1'b0; state <= 'd0; end         default: state <= 'd0;         endcase

assign c = rNeg ? ( ~q + 1'b1 ): q;
assign d = r[ 15:8 ];
assign is_done_sig = rDone;
endmodule

//激励文件
`timescale 1ns / 1ns
module cycle_divider_test();
reg [ 7:0 ]a,b;
reg clk,rst_n;
reg is_start_sig;

wire [ 7:0 ]c,d;
wire is_done_sig;

cycle_divider I1
(
.clk( clk ),
.rst_n( rst_n ),
.a( a ),
.b( b ),
.c( c ),
.d( d ),
.is_start_sig( is_start_sig ),
.is_done_sig( is_done_sig )
);

initial 
begin
clk = 0;
rst_n = 1;
#200;
rst_n = 0;
#200;
rst_n = 1;
forever #20 clk = ~clk;
end

reg [ 3:0 ]i;
always @( posedge clk or negedge rst_n )
if( !rst_n )
begin 
i <= 'd0;
is_start_sig <= 'd0;
a <= 'd0;
b <= 'd0;
end
else 
case( i )
'd0: if( is_done_sig ) begin is_start_sig <= 1'b0; i <= i+ 1'b1; end
else begin is_start_sig <= 1'b1; a <= 'd12; b <= 'd3; end

   'd0: if( is_done_sig ) begin is_start_sig <= 1'b0; i <= i+ 1'b1; end        else begin is_start_sig <= 1'b1; a <= -'d25; b <= 'd5; end   'd1: if( is_done_sig ) begin is_start_sig <= 1'b0; i <= i+ 1'b1; end        else begin is_start_sig <= 1'b1; a <= 'd36; b <= 'd6; end   'd2: if( is_done_sig ) begin is_start_sig <= 1'b0; i <= i+ 1'b1; end        else begin is_start_sig <= 1'b1; a <= 'd12; b <= 'd5; end   'd3: if( is_done_sig ) begin is_start_sig <= 1'b0; i <= i+ 1'b1; end        else begin is_start_sig <= 1'b1; a <= -'d34; b <= -'d3; end   'd4: if( is_done_sig ) begin is_start_sig <= 1'b0; i <= i+ 1'b1; end        else begin is_start_sig <= 1'b1; a <= 'd67; b <= 'd7; end   'd5: if( is_done_sig ) begin is_start_sig <= 1'b0; i <= i+ 1'b1; end        else begin is_start_sig <= 1'b1; a <= -'d19; b <= 'd8; end   'd6: if( is_done_sig ) begin is_start_sig <= 1'b0; i <= i+ 1'b1; end        else begin is_start_sig <= 1'b1; a <= -'d19; b <= 'd38; end   'd7: i <= 'd7;  default: i <= 'd0;  endcase

endmodule

default


0 0
原创粉丝点击