自己做的除法器
这是本人做的除法器是32位除以32位(根据小学除法的原理写的),可以看到商和余数。
在modelsim上可以通过功能验证,但是用synplify综合总是出错,希望各位同胞不吝赐教。
本人的编程风格很是问题,不知道有什么好的编程风格,望请推荐。
本人是在校学生,没有任何流片经验,很困惑前段的代码如何写才能方便后面的布局布线,不知道要是优化的话应该从何下手,请赐教。非常谢谢
感谢小编解答,按照小编的要求改后,又遇到问题,问题如图所示

module division(reset,clk,a,b,load,quotient,remainder);
input reset,clk,load;
input [31:0] a,b;
output [31:0] quotient,remainder;
reg [31:0] bshift,remainder_temp,quotient,remainder;
wire [11:0] a_dec;
wire [11:0] b_dec;
wire [31:0] atemp,btemp;
reg [4:0] num,number;
wire [4:0] counter0;
wire [4:0] counter1;
reg shift_start,start;
genvar i;
//minusend bit width
p_decoder8 p80(reset,a[31:24],a_dec[11:9]);
p_decoder8 p81(reset,a[23:16],a_dec[8:6]);
p_decoder8 p82(reset,a[15:8],a_dec[5:3]);
p_decoder8 p83(reset,a[7:0],a_dec[2:0]);
assign counter0[4]=a_dec[11]|a_dec[10]|a_dec[9]|a_dec[8]|a_dec[7]|a_dec[6],
counter0[3]=a_dec[11]|a_dec[10]|a_dec[9]|a_dec[5]|a_dec[4]|a_dec[3],
counter0[2]=counter0[4]?(counter0[3]?a_dec[11]:a_dec[8])counter0[3]?a_dec[5]:a_dec[2]),
counter0[1]=counter0[4]?(counter0[3]?a_dec[10]:a_dec[7])counter0[3]?a_dec[4]:a_dec[1]),
counter0[0]=counter0[4]?(counter0[3]?a_dec[9]:a_dec[6])counter0[3]?a_dec[3]:a_dec[0]);
//subtrahend bit width
p_decoder8 p84(reset,b[31:24],b_dec[11:9]);
p_decoder8 p85(reset,b[23:16],b_dec[8:6]);
p_decoder8 p86(reset,b[15:8],b_dec[5:3]);
p_decoder8 p87(reset,b[7:0],b_dec[2:0]);
assign counter1[4]=b_dec[11]|b_dec[10]|b_dec[9]|b_dec[8]|b_dec[7]|b_dec[6],
counter1[3]=b_dec[11]|b_dec[10]|b_dec[9]|b_dec[5]|b_dec[4]|b_dec[3],
counter1[2]=counter0[4]?(counter0[3]?b_dec[11]:b_dec[8]):(counter0[3]?b_dec[5]:b_dec[2]),
counter1[1]=counter0[4]?(counter0[3]?b_dec[10]:b_dec[7]):(counter0[3]?b_dec[4]:b_dec[1]),
counter1[0]=counter0[4]?(counter0[3]?b_dec[9]:b_dec[6]):(counter0[3]?b_dec[3]:b_dec[0]);
//temporary regiser
generate
for (i=0;i<32;i=i+1) begin:g1
load l0(a,atemp,load,reset);
load l1(b,btemp,load,reset);
end
endgenerate
always @(posedge clk)
if(reset)
begin
num=5'b0;
number=5'b0;
bshift=32'b0;
shift_start=0;
quotient=32'b0;
remainder=32'b0;
end
else
if(load)
if(a>=b)
begin
num=counter0-counter1;
shift_start=1;
bshift=btemp;
remainder_temp=atemp;
number=counter0-counter1+1;
end
else
begin
shift_start=0;
quotient=32'b0;
remainder_temp=atemp;
end
else if(shift_start)
begin
if(!num)
begin
shift_start=0;
start=1;
num=5'b0;
end
else
begin
shift_start=1;
bshift=bshift<<1;
start=0;
end
num=num-1;
end
else if(start)
begin
if(number)
if(remainder_temp>=bshift)
begin
remainder_temp=remainder_temp-bshift;
quotient[number-1]=1'b1;
bshift=bshift>>1;
end
else
begin
remainder_temp=remainder_temp;
quotient[number-1]=1'b0;
bshift=bshift>>1;
end
else if(!number)
start=0;
number=number-1;
end
else if(start==0)
remainder=remainder_temp;
endmodule
//submodule priority decoder
module p_decoder8(reset,a,b);
input [7:0] a;
input reset;
output [2:0] b;
reg [2:0] b;
always @(a,reset)
if(reset)
b=3'b000;
else
begin
if(a[7]==1'b1)
b=3'b111;
else if(a[6]==1'b1)
b=3'b110;
else if(a[5]==1'b1)
b=3'b101;
else if(a[4]==1'b1)
b=3'b100;
else if(a[3]==1'b1)
b=3'b011;
else if(a[2]==1'b1)
b=3'b010;
else if(a[1]==1'b1)
b=3'b001;
else
b=3'b000;
end
endmodule
//submodule load
module load(a,b,load,reset);
input a,load,reset;
output b;
reg b;
always @(posedge load,posedge reset)
if(reset)
b=1'b0;
else
b=a;
endmodule
一个信号只在一个always里赋值。
想清楚这个always是要做组合逻辑还是时序逻辑,决定用= 还是 <=赋值。
不是时钟或复位信号不要用posedge 或 negedge触发
算法方面,很惭愧,看不懂,能说说思路么。
直接代码复制粘贴上来,解决的人会比较多的。
不好意思我写得程序比较乱
就是小学的做除法时候用的算法
移位比较的除法器
小学的时候用的是10进制,现在换成2进制就可以了
说的也是
多谢赐教
但是我想用一个复位信号能复位全部的,这样就不能分开写了,并且分开写还要有更多的判断条件,岂不是更麻烦
你这段描述是要写D-flop吗?如果是的话问题来了,clock呢?flop有load端吗?
module dff(a,b,load,reset);
input a,load,reset;
output b;
reg b;
always @(posedge load,posedge reset)
if(reset)
b=1'b0;
else
b=a;
endmodule
供参考
http://fpgaw.com/home/space.php?uid=2634
抱歉,忘记改了,应该是load模块,因为我想做一个载入模块,不是所有的信号都会要
看了你贴的报错的地方,这个不是错误啊,只是warning,警告而已嘛。说有一些逻辑被优化掉了,你检查一下,这些是否可以被优化掉。没有功能的信号本来就是可以被优化的。
贴一个MIPS789里面用到的乘除法器。还有一个是 UCORE里面用的 ,下 一帖子上。
module muldiv(ready,rst,op1,op2,clk,dout,func);
input clk,rst;
wire sign;
input [4:0] func ;
input [31:0] op2, op1;
output [31:0] dout;
output ready;
reg [31:0] quotient, quotient_temp;
reg [63:0] dividend_copy, divider_copy, diff;
reg negative_output;
reg [63:0] product, product_temp;
reg [31:0] multiplier_copy;
reg [63:0] multiplicand_copy;
reg [6:0] mul_bit,div_bit;
wire ready = ((mul_bit==0)&&(div_bit==0));
wire [31:0] dividend, divider;
wire [31:0] remainder;
wire [31:0] multiplier,multiplicand;
reg [31:0] hi,lo;
assign dout = (func==`ALU_MFHI)?hifunc==`ALU_MFLO)?lo:0;
assign remainder = (!negative_output) ?
dividend_copy[31:0] :
~dividend_copy[31:0] + 1'b1;
assign multiplier=op2;
assign multiplicand=op1;
assign dividend=op1;
assign divider = op2;
assign sign = ((func==`ALU_MULT)||(func==`ALU_div));
initial
begin
hi=0;
lo=0;
end
always @( posedge clk /*or negedge rst */)
if (~rst)
begin
mul_bit=0;
div_bit=0;
/*
hi=0;
lo=0;
*/
negative_output = 0;
end
else
begin
if((ready)&&((func==`ALU_MULT)||(func==`ALU_MULTTU)))
begin
mul_bit = 33;
product = 0;
product_temp = 0;
multiplicand_copy = (!sign || !multiplicand[31]) ?
{ 32'd0, multiplicand } :
{ 32'd0, ~multiplicand + 1'b1};
multiplier_copy = (!sign || !multiplier[31]) ?multiplier :~multiplier + 1'b1;
negative_output = sign &&
((multiplier[31] && !multiplicand[31])
||(!multiplier[31] && multiplicand[31]));
end
if ( mul_bit > 1 )
begin
if( multiplier_copy[0] == 1'b1 )
product_temp = product_temp +multiplicand_copy;
product = (!negative_output) ?
product_temp :
~product_temp + 1'b1;
multiplier_copy = multiplier_copy >> 1;
multiplicand_copy = multiplicand_copy << 1;
mul_bit = mul_bit - 1'b1;
end
else if (mul_bit == 1)
begin
hi = product[63:32];
lo = product[31:0];
mul_bit=0;
end
if((ready)&&((func==`ALU_div)||(func==`ALU_divU)))
begin
div_bit = 33;
quotient = 0;
quotient_temp = 0;
dividend_copy = (!sign || !dividend[31]) ?
{32'd0,dividend} :
{32'd0,~dividend + 1'b1};
divider_copy = (!sign || !divider[31]) ?
{1'b0,divider,31'd0} :
{1'b0,~divider + 1'b1,31'd0};
negative_output = sign &&
((divider[31] && !dividend[31])
||(!divider[31] && dividend[31]));
end
else if (div_bit > 1)
begin
diff = dividend_copy - divider_copy;
quotient_temp = quotient_temp << 1;
if( !diff[63] )
begin
dividend_copy = diff;
quotient_temp[0] = 1'd1;
end
quotient = (!negative_output) ?quotient_temp :~quotient_temp + 1'b1;
divider_copy = divider_copy >> 1;
div_bit = div_bit - 1'b1;
end
else if (div_bit == 1)
begin
lo = quotient;
hi = remainder;
div_bit=0;
end
end
endmodule
抱歉,最近有考试所以没上网
谢谢,我发现问题了,因为计数器number改变时number的第一个值没有赋给quotient[number],所以才会出警告。已经修改完毕
谢谢,参考了,不过好像算法差不多
