基于verilog的除法器
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
module divider(quotient,remainder,ready,error,word1,word2,start,clock,reset); parameter L_divn=8,
L_divr=4,
S_idle=0,S_adivr=1,S_adivn=2,S_div=3,S_err=4,
L_state=3,L_cnt=4,Max_cnt=L_divn-L_divr;
output [L_divn-1:0] quotient,remainder;
output ready,error;
input [L_divn-1:0] word1;//dividend
input [L_divr-1:0] word2;//divisor
input start,clock,reset;//0,start,1,reset
reg [L_state-1:0] state,next_state;
reg Load_words,Subtract,Shift_dividend,Shift_divisor;
reg [L_divn-1:0] quotient;
reg [L_divn:0] dividend;
reg [L_divr-1:0] divisor;
reg [L_cnt-1:0] num_Shift_dividend,num_Shift_divisor;
reg [L_divr:0] comparison;
wire MSB_divr=divisor[L_divr-1];
wire ready=((state==S_idle)&&reset);
wire error=(state==S_err);
wire Max=(num_Shift_dividend==Max_cnt+num_Shift_divisor);
wire sign_bit=comparison[L_divr];
assign remainder=(dividend[L_divn-1:L_divn-L_divr])>num_Shift_divisor;/////////
always @(state or dividend or divisor or MSB_divr)
case(state)
S_adivr: if(MSB_divr==0)
comparison=dividend[L_divn:L_divn-L_divr]+{1'b1,~(divisor<<1)}+1'b1;
else
comparison=dividend[L_divn:L_divn-L_divr]+{1'b1,~divisor[L_divr-1:0]}+1'b1;
default:
comparison=dividend[L_divn:L_divn-L_divr]+{1'b1,~divisor[L_divr-1:0]}+1'b1;
endcase
always @(posedge clock or negedge reset)
if(!reset) state<=S_idle; else state<=next_state;
always @(state or word1 or word2 or start or comparison or sign_bit or Max)
begin
Load_words=0;Subtract=0;Shift_dividend=0;Shift_divisor=0;
case(state)
S_idle: case(!start)
0: next_state=S_idle;
1: if(word2==0) next_state=S_err;
else if(word1) begin next_state=S_adivr;Load_words=1; end
else next_state=S_idle;
endcase
S_adivr: case(MSB_divr)
0: if(sign_bit==0) begin next_state=S_adivr;Shift_divisor=1; end
else if(sign_bit==1) next_state=S_adivn;
1: next_state=S_div;
endcase
S_adivn: case({Max,sign_bit})
2'b00: next_state=S_div;
2'b01: begin next_state=S_adivn;Shift_dividend=1; end
2'b10: begin next_state=S_idle;Subtract=1; end
2'b11: next_state=S_idle;
endcase
S_div: case({Max,sign_bit})
2'b00: begin next_state=S_div;Subtract=1; end
2'b01: next_state=S_adivn;
2'b10: begin next_state=S_div;Subtract=1; end
2'b11: begin next_state=S_div;Shift_dividend=1; end
endcase
default: next_state=S_err;
endcase
end
always @(posedge clock or negedge reset)
begin
if(!reset)
begin
divisor<=0;
dividend<=0;
quotient<=0;
num_Shift_dividend<=0;
num_Shift_divisor<=0;
end
else if(Load_words==1)
begin
dividend<=word1;
divisor<=word2;