Line 119... 
Line 119... 
assign diff = r_dividend  r_divisor[(BW1):0];

assign diff = r_dividend  r_divisor[(BW1):0];

// assign xdiff= r_dividend  { 1'b0, r_divisor[(BW1):1] };

// assign xdiff= r_dividend  { 1'b0, r_divisor[(BW1):1] };



reg r_sign, pre_sign, r_z, r_c, last_bit;

reg r_sign, pre_sign, r_z, r_c, last_bit;

reg [(LGBW1):0] r_bit;

reg [(LGBW1):0] r_bit;



reg zero_divisor;

reg zero_divisor;

initial zero_divisor = 1'b0;


always @(posedge i_clk)


zero_divisor <= (r_divisor == 0)&&(r_busy);





// The Divide logic begins with r_busy. We use r_busy to determine


// whether or not the divide is in progress, vs being complete.


// Here, we clear r_busy on any reset and set it on i_wr (the request


// do to a divide). The divide ends when we are on the last bit,


// or equivalently when we discover we are dividing by zero.

initial r_busy = 1'b0;

initial r_busy = 1'b0;

always @(posedge i_clk)

always @(posedge i_clk)

if (i_rst)

if (i_rst)

r_busy <= 1'b0;

r_busy <= 1'b0;

else if (i_wr)

else if (i_wr)

r_busy <= 1'b1;

r_busy <= 1'b1;

else if ((last_bit)(zero_divisor))

else if ((last_bit)(zero_divisor))

r_busy <= 1'b0;

r_busy <= 1'b0;




// o_busy is very similar to r_busy, save for some key differences.


// Primary among them is that o_busy needs to (possibly) be true


// for an extra clock after r_busy clears. This would be that extra


// clock where we negate the result (assuming a signed divide, and that


// the result is supposed to be negative.) Otherwise, the two are


// identical.

initial o_busy = 1'b0;

initial o_busy = 1'b0;

always @(posedge i_clk)

always @(posedge i_clk)

if (i_rst)

if (i_rst)

o_busy <= 1'b0;

o_busy <= 1'b0;

else if (i_wr)

else if (i_wr)

Line 145... 
Line 152... 
else if (((last_bit)&&(~r_sign))(zero_divisor))

else if (((last_bit)&&(~r_sign))(zero_divisor))

o_busy <= 1'b0;

o_busy <= 1'b0;

else if (~r_busy)

else if (~r_busy)

o_busy <= 1'b0;

o_busy <= 1'b0;




// If we are asked to divide by zero, we need to halt. The sooner


// we halt and report the error, the better. Hence, here we look


// for a zero divisor while being busy. The always above us will then


// look at this and halt a divide in the middle if we are trying to


// divide by zero.


//


// Note that this works off of the 2BW1 length vector. If we can


// simplify that, it should simplify our logic as well.


initial zero_divisor = 1'b0;

always @(posedge i_clk)

always @(posedge i_clk)

if ((i_rst)(i_wr))

// zero_divisor <= (r_divisor == 0)&&(r_busy);


if (i_rst)


zero_divisor <= 1'b0;


else if (i_wr)


zero_divisor <= (i_denominator == 0);


else if (!r_busy)


zero_divisor <= 1'b0;




// o_valid is part of the ZipCPU protocol. It will be set to true


// anytime our answer is valid and may be used by the calling module.


// Indeed, the ZipCPU will halt (and ignore us) once the i_wr has been


// set until o_valid gets set.


//


// Here, we clear o_valid on a reset, and any time we are on the last


// bit while busy (provided the sign is zero, or we are dividing by


// zero). Since o_valid is selfclearing, we don't need to clear


// it on an i_wr signal.


initial o_valid = 1'b0;


always @(posedge i_clk)


if (i_rst)

o_valid <= 1'b0;

o_valid <= 1'b0;

else if (r_busy)

else if (r_busy)

begin

begin

if ((last_bit)(zero_divisor))

if ((last_bit)(zero_divisor))

o_valid <= (zero_divisor)(~r_sign);

o_valid <= (zero_divisor)(!r_sign);

end else if (r_sign)

end else if (r_sign)

begin

begin

o_valid <= (~zero_divisor); // 1'b1;

o_valid <= (!zero_divisor); // 1'b1;

end else

end else

o_valid <= 1'b0;

o_valid <= 1'b0;




// Division by zero error reporting. Anytime we detect a zero divisor,


// we set our output error, and then hold it until we are valid and


// everything clears.

initial o_err = 1'b0;

initial o_err = 1'b0;

always @(posedge i_clk)

always @(posedge i_clk)

if((i_rst)(o_valid))

if((i_rst)(o_valid))

o_err <= 1'b0;

o_err <= 1'b0;

else if (((r_busy)(r_sign))&&(zero_divisor))

else if (((r_busy)(r_sign))&&(zero_divisor))

o_err <= 1'b1;

o_err <= 1'b1;

else

else

o_err <= 1'b0;

o_err <= 1'b0;




// r_bit


//


// Keep track of which "bit" of our divide we are on. This number


// ranges from 31 down to zero. On any write, we set ourselves to


// 5'h1f. Otherwise, while we are busy (but not within the presign


// adjustment stage), we subtract one from our value on every clock.


always @(posedge i_clk)


if ((r_busy)&&(!pre_sign))


r_bit <= r_bit + {(LGBW){1'b1}};


else


r_bit <= {(LGBW){1'b1}};




// last_bit


//


// This logic replaces a lot of logic that was inside our giant state


// machine with ... something simpler. In particular, we'll use this


// logic to determine we are processing our last bit. The only trick


// is, this bit needs to be set whenever (r_busy) and (r_bit == 0),


// hence we need to set on (r_busy) and (r_bit == 1) so as to be set


// when (r_bit == 0).

initial last_bit = 1'b0;

initial last_bit = 1'b0;

always @(posedge i_clk)

always @(posedge i_clk)

if ((i_wr)(pre_sign)(i_rst))

if (r_busy)

last_bit <= 1'b0;


else if (r_busy)


last_bit <= (r_bit == {{(LGBW1){1'b0}},1'b1});

last_bit <= (r_bit == {{(LGBW1){1'b0}},1'b1});


else


last_bit <= 1'b0;




// pre_sign


//


// This is part of the state machine. pre_sign indicates that we need


// a extra clock to take the absolute value of our inputs. It need only


// be true for the one clock, and then it must clear itself.


initial pre_sign = 1'b0;

always @(posedge i_clk)

always @(posedge i_clk)

// if (i_rst) r_busy <= 1'b0;


// else


if (i_wr)

if (i_wr)

begin


//


// Set our values upon an initial command. Here's


// where we come in and start.


//


// r_busy <= 1'b1;


//


o_quotient <= 0;


r_bit <= {(LGBW){1'b1}};


r_divisor <= { i_denominator, {(BW1){1'b0}} };


r_dividend <= i_numerator;


r_sign <= 1'b0;


pre_sign <= i_signed;

pre_sign <= i_signed;


else


pre_sign <= 1'b0;




// As a result of our operation, we need to set the flags. The most


// difficult of these is the "Z" flag indicating that the result is


// zero. Here, we'll use the same logic that sets the loworder


// bit to clear our zero flag, and leave the zero flag set in all


// other cases. Well ... not quite. If we need to flip the sign of


// our value, then we can't quite clear the zero flag ... yet.


always @(posedge i_clk)


if((r_busy)&&(r_divisor[(2*BW2):(BW)] == 0)&&(!diff[BW]))


// If we are busy, the upper bits of our divisor are


// zero (i.e., we got the shift right), and the top


// (carry) bit of the difference is zero (no overflow),


// then we could subtract our divisor from our dividend


// and hence we add a '1' to the quotient, while setting


// the zero flag to false.


r_z <= 1'b0;


else if ((!r_busy)&&(!r_sign))

r_z <= 1'b1;

r_z <= 1'b1;

end else if (pre_sign)



// r_dividend


// This is initially the numerator. On a signed divide, it then becomes


// the absolute value of the numerator. We'll subtract from this value


// the divisor shifted as appropriate for every output bit we are


// looking forjust as with traditional long division.


always @(posedge i_clk)


if (pre_sign)

begin

begin

//

// If we are doing a signed divide, then take the

// Note that we only come in here, for one clock, if

// absolute value of the dividend

// our initial value may have been signed. If we are


// doing an unsigned divide, we then skip this step.


//


r_sign <= ((r_divisor[(2*BW2)])^(r_dividend[(BW1)]));


// Negate our dividend if necessary so that it becomes


// a magnitude only value


if (r_dividend[BW1])

if (r_dividend[BW1])

r_dividend <= r_dividend;

r_dividend <= r_dividend;

// Do the same with the divisorrendering it into

// The begin/end block is important so we don't lose

// a magnitude only.

// the fact that on an else we don't do anything.


end else if((r_busy)&&(r_divisor[(2*BW2):(BW)]==0)&&(!diff[BW]))


// This is the condition whereby we set a '1' in our


// output quotient, and we subtract the (current)


// divisor from our dividend. (The difference is


// already kept in the diff vector above.)


r_dividend <= diff[(BW1):0];


else if (!r_busy)


// Once we are done, and r_busy is no longer high, we'll


// always accept new values into our dividend. This


// guarantees that, when i_wr is set, the new value


// is already set as desired.


r_dividend <= i_numerator;




initial r_divisor = 0;


always @(posedge i_clk)


if (pre_sign)


begin

if (r_divisor[(2*BW2)])

if (r_divisor[(2*BW2)])

r_divisor[(2*BW2):(BW1)] <= r_divisor[(2*BW2):(BW1)];

r_divisor[(2*BW2):(BW1)]

//

<= r_divisor[(2*BW2):(BW1)];

// We only do this stage for a single clock, so go on


// with the rest of the divide otherwise.


pre_sign <= 1'b0;


end else if (r_busy)

end else if (r_busy)

begin


// While the divide is taking place, we examine each bit


// in turn here.


//


r_bit <= r_bit + {(LGBW){1'b1}}; // r_bit = r_bit  1;


r_divisor <= { 1'b0, r_divisor[(2*BW2):1] };

r_divisor <= { 1'b0, r_divisor[(2*BW2):1] };

if (r_divisor[(2*BW2):(BW)])

else


r_divisor <= { i_denominator, {(BW1){1'b0}} };




// r_sign


// is a flag for our state machine control(s). r_sign will be set to


// true any time we are doing a signed divide and the result must be


// negative. In that case, we take a final logic stage at the end of


// the divide to negate the output. This flag is what tells us we need


// to do that. r_busy will be true during the divide, then when r_busy


// goes low, r_sign will be checked, then the idle/reset stage will have


// been reached. For this reason, we cannot set r_sign unless we are


// up to something.


initial r_sign = 1'b0;


always @(posedge i_clk)


if (pre_sign)


r_sign <= ((r_divisor[(2*BW2)])^(r_dividend[(BW1)]));


else if (r_busy)


r_sign <= (r_sign)&&(!zero_divisor);


else


r_sign <= 1'b0;




always @(posedge i_clk)


if (r_busy)

begin

begin

end else if (diff[BW])

o_quotient <= { o_quotient[(BW2):0], 1'b0 };


if ((r_divisor[(2*BW2):(BW)] == 0)&&(!diff[BW]))

begin

begin

//

o_quotient[0] <= 1'b1;

// diff = r_dividend  r_divisor[(BW1):0];


//


// If this value was negative, there wasn't


// enough value in the dividend to support


// pulling off a bit. We'll move down a bit


// therefore and try again.


//


end else begin


//


// Put a '1' into our output accumulator.


// Subtract the divisor from the dividend,


// and then move on to the next bit


//


r_dividend <= diff[(BW1):0];


o_quotient[r_bit[(LGBW1):0]] <= 1'b1;


r_z <= 1'b0;


end

end

r_sign <= (r_sign)&&(~zero_divisor);


end else if (r_sign)

end else if (r_sign)

begin


r_sign <= 1'b0;


o_quotient <= o_quotient;

o_quotient <= o_quotient;

end

else


o_quotient <= 0;



// Set Carry on an exact divide

// Set Carry on an exact divide

wire w_n;

// Perhaps nothing uses this, but ... well, I suppose we could remove


// this logic eventually, just ... not yet.

always @(posedge i_clk)

always @(posedge i_clk)

r_c <= (r_busy)&&((diff == 0)(r_dividend == 0));

r_c <= (r_busy)&&((diff == 0)(r_dividend == 0));




// The last flag: Negative. This flag is set assuming that the result


// of the divide was negative (i.e., the high order bit is set). This


// will also be true of an unsigned divideif the high order bit is


// ever set upon completion. Indeed, you might argue that there's no


// logic involved.


wire w_n;

assign w_n = o_quotient[(BW1)];

assign w_n = o_quotient[(BW1)];



assign o_flags = { 1'b0, w_n, r_c, r_z };

assign o_flags = { 1'b0, w_n, r_c, r_z };

endmodule

endmodule



No newline at end of file

No newline at end of file
