谁能告诉我顺序除法中除数和除数的宽度应该是多少。到目前为止,我已经设计了 WIDTH_DIVID=2*wIDTH_DIVIS 的分隔线。如果我破坏这种关系,我的分裂就会失败。谁能帮我这个我的verilog代码如下所示
// Description: module for serial Divider
// The dividend is loaded into the accumulator along with the guard bit.
// Then the 2's complement of the divisor is added to the upperpart of the
// accumulator along with the guard bit.Then the MSB of the accumulator is
// tested.
// 1. If it is cleared then 1 bit left shift of the accumulator is done and
// one is concantinated to the LSB of the accumulator.
// 2. If is is not cleared then the accumulator contents are shifted 1 bit
// left.
// After the division upper part of the accumulator contains the remainder
// and lower part contains the quotient.
//------------------------------------------------ --------------------------
module division(//global inputs
i_clk,i_rst,
//outputs
o_quotient,o_remainder,o_done,o_overflow,
//input
i_dividend,i_divisor,i_start
);
//parameter declarations
parameter DIVIS_WIDTH =2; //width for divisor
parameter DIVID_WIDTH =2*DIVIS_WIDTH; //width for dividend,DIVID_WIDTH=2*DIVIS_WIDTH
localparam NPOWER = 6; //divisor width<=2**NPOWER
localparam NULL_VECTOR_S=32'h00000000;
localparam S0= 2'd0;
localparam S1= 2'd1;
localparam S2= 2'd2;
//global inputs
input i_clk;
input i_rst;
//outputs
output reg [DIVIS_WIDTH:0] o_quotient;
output reg [DIVIS_WIDTH-1:0] o_remainder;
output reg o_overflow;
output reg o_done;
//input
input [DIVID_WIDTH-1:0] i_dividend;
input [DIVIS_WIDTH-1:0] i_divisor;
input i_start; //indicates start of division
// reg and wire declarations
reg [DIVID_WIDTH:0] dividend_i; //Add extra guard bit
reg [DIVIS_WIDTH:0] divisor_i; //Add extra guard bit
reg [DIVIS_WIDTH-1:0] divisor_rect_i; //divisor used to check overflow
wire signquot_i; //Sign of quotient
wire signremain_i; //Sign of remainder
reg [DIVID_WIDTH+DIVIS_WIDTH-1:0] accumulator_i; // Shift register which holds both remainder and quotient
reg [DIVIS_WIDTH:0] aluout_i; //Used to add the upperpart of the shift register and the divisor
reg [NPOWER-1:0] count_i; //No.of iterations
reg pos_i;
reg neg_i;
reg [2:0] state;
reg [2:0] nextstate;
reg done_i;
//Sign product of quotient and remainder
assign signquot_i=((i_dividend[DIVID_WIDTH-1] ^ i_divisor[DIVIS_WIDTH-1]));
assign signremain_i=(i_dividend[DIVID_WIDTH-1]);
always@(posedge i_clk or posedge i_rst)
begin
if(i_rst==1)begin
dividend_i<=0;
divisor_i<=0;
divisor_rect_i<=0;
end else begin
divisor_rect_i<=i_divisor;
dividend_i<=({1'b0,i_dividend});
divisor_i<=(~({1'b0,i_divisor})+1);
end
end // else: !if(i_rst==1)
//Sequential Division
always@(posedge i_clk or posedge i_rst)
begin
if (i_rst==1)
accumulator_i <=0;
else begin
if(i_start==1)
accumulator_i<={dividend_i[DIVID_WIDTH-1:0],1'b0}; // Load Dividend in shift register
else if(pos_i==1)
accumulator_i<=({aluout_i[DIVIS_WIDTH-1:0],accumulator_i[DIVID_WIDTH-DIVIS_WIDTH-1:0],1'b1});//({newaccu_i[DIVID_WIDTH-1:0],1'b1});//shiting the new register value by one bit left and concantinatinf one at the LSB
else if(neg_i==1)
accumulator_i<=({accumulator_i[DIVID_WIDTH-1:0],1'b0});//Use the previous register value and shift 1 bit left
end
end // always@ (posedge i_clk or posedge i_rst or posedge i_start)
//Adding the divisor to the upper part of the Shift register
always@(accumulator_i,divisor_i)
begin
aluout_i<=accumulator_i[DIVID_WIDTH : DIVID_WIDTH-DIVIS_WIDTH]+ divisor_i;
// newaccu_i<= ({aluout_i, accumulator_i[DIVID_WIDTH-DIVIS_WIDTH-1:0]});
end
//Control of states for division
always@(posedge i_clk or posedge i_rst)
begin
if (i_rst == 1) begin
state <= S0;
count_i <=0;
end else begin
state <= nextstate;
if (state==S1)
count_i <= count_i - 1;
else if (state==S0)
count_i <= (DIVIS_WIDTH);
end
end // always@ (posedge i_clk or posedge i_rst)
//generating the control signals pos_i and neg_i to control division
always@(state,i_start,aluout_i,count_i)
begin
case (state)
S0 :begin
pos_i <= 0;
neg_i <= 0;
if (i_start==1)
nextstate <= S1;
else
nextstate <= S0;
end
S1 : begin
neg_i <= aluout_i[DIVIS_WIDTH];
pos_i <= ~(aluout_i[DIVIS_WIDTH]);
if (count_i==NULL_VECTOR_S[NPOWER_WIDTH-1])
nextstate <= S2; // Done
else
nextstate <= S1;// Next sub&shift
end
S2 : begin
pos_i <= 0;
neg_i <= 0;
nextstate <= S0;
end
default: begin
pos_i <= 0;
neg_i <= 0;
nextstate <= S0;
end
endcase // case (state)
end // always@ (state,i_start,aluout_i,count_i)
//done signal to indicate end of division
always@(posedge i_clk or posedge i_rst)
begin
if(i_rst==1) begin
done_i<= 0;
end else begin
done_i <= (count_i==1)? 1'b1 : 1'b0;
end
end
//Assigning the outputs for unsigned division
always@(accumulator_i,done_i)
begin
o_done<=done_i;
o_remainder<=accumulator_i[DIVID_WIDTH:DIVID_WIDTH-DIVIS_WIDTH+1];
o_quotient<=(accumulator_i[DIVIS_WIDTH:0]);
o_overflow<=(((accumulator_i[DIVID_WIDTH:DIVID_WIDTH-DIVIS_WIDTH+1])>=divisor_rect_i))? 1'b1 : 1'b0;
end
endmodule // division