Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

What's wrong with divider

Status
Not open for further replies.

VitalyM4

Junior Member level 3
Joined
Jan 18, 2008
Messages
28
Helped
1
Reputation
2
Reaction score
0
Trophy points
1,281
Activity points
1,459
Hi !

I created divider (255/divisor), it works well for all the cases except one when divisor equal to 1, then result is 0 instead of 255.

Code:
module div (
	SCAN_EN_SCLK ,              /*Scan Enable*/
	SCAN_IN_SCLK ,              /*Scan Input*/
	SCAN_OUT_SCLK,			   /*Scan output */
	rb_por_cr , 			       /*Asynchronous reset*/
	SCLK ,                 /*Divider Clock*/	
	divisor ,			   /*divisor*/
	we ,				   /*write enable - initiate dividing*/
	result				   /*division result*/
	);
	/*Port direction and types*/
	output [6:0] result ;
	reg [6:0] result ;
	
	input [7:0] divisor ;  
	wire [7:0] divisor;
	input SCLK ;
	wire SCLK ;								   
	input we ;
	wire we;
	input rb_por_cr;
	input SCAN_EN_SCLK;
	input SCAN_IN_SCLK; 	 
	output SCAN_OUT_SCLK; 
	
	
	/*Internal signal declaration*/
	reg [8:0] cur_divident;
	reg [6:0] cur_divisor;
	reg [2:0] bit_count;
	integer i;
	reg [2:0] max;
	
	/*Functional description*/	
	
	/*Create logic finding  MSB 1*/
	always@(divisor)  
		begin 
			max=0;	
			for(i=7;i>0;i=i-1)
				if(divisor[i]==1'b1 & i>=max)
					max=i;		
		end		
	
	wire [7:0] tmp_div=divisor<<(8-max);	 
	/*Division*/
	always@(negedge rb_por_cr or posedge SCLK)  
		if(!rb_por_cr)	
			begin
				cur_divident<=8'd0;
				cur_divisor<=8'd0;   
				bit_count<=3'd0; 
				result<=7'd0;
			end	
		else if(we)
			begin
				cur_divident<=9'd255-tmp_div;
				cur_divisor<=tmp_div>>1;   
				bit_count<=8-max; 
				result<=7'd0;
			end
		else if (bit_count>3'b000)
			begin
				if (cur_divident[8]==1'b0)
					begin
						cur_divident <= cur_divident-cur_divisor;	 
						result[bit_count-1'b1]<=1'b1;					
					end	
				else
					begin
					    result[bit_count-1'b1]<=1'b0;	
				   cur_divident <= cur_divident+cur_divisor;
			end
	
	bit_count<=bit_count-1;	  
	cur_divisor<= cur_divisor>>1; 	  
	end		
	
	
	
endmodule

I know that exists some page where you can set divident and divisor and see all the stages of non-restoring division. Does someone know adress?

Thanks in advance!
 

VitalyM4 said:
Hi !

I created divider (255/divisor), it works well for all the cases except one when divisor equal to 1, then result is 0 instead of 255.


module div (
SCAN_EN_SCLK , /*Scan Enable*/
SCAN_IN_SCLK , /*Scan Input*/
SCAN_OUT_SCLK, /*Scan output */
rb_por_cr , /*Asynchronous reset*/
SCLK , /*Divider Clock*/
divisor , /*divisor*/
we , /*write enable - initiate dividing*/
result /*division result*/
);
/*Port direction and types*/
output [6:0] result ;
reg [6:0] result ;

input [7:0] divisor ;
wire [7:0] divisor;
input SCLK ;
wire SCLK ;
input we ;
wire we;
input rb_por_cr;
input SCAN_EN_SCLK;
input SCAN_IN_SCLK;
output SCAN_OUT_SCLK;


/*Internal signal declaration*/
reg [8:0] cur_divident;
reg [6:0] cur_divisor;
reg [2:0] bit_count;
integer i;
reg [2:0] max;

/*Functional description*/

/*Create logic finding MSB 1*/
always@(divisor)
begin
max=0;
for(i=7;i>0;i=i-1)
if(divisor==1'b1 & i>=max)
max=i;
end

wire [7:0] tmp_div=divisor<<(8-max); u r making it zero if the max is zero... thats what its happening for 1..... so u can work out with other stuff......
thats the reason u r getting zero all the time!!!!!!!

/*Division*/
always@(negedge rb_por_cr or posedge SCLK)
if(!rb_por_cr)
begin
cur_divident<=8'd0;
cur_divisor<=8'd0;
bit_count<=3'd0;
result<=7'd0;
end
else if(we)
begin
cur_divident<=9'd255-tmp_div;
cur_divisor<=tmp_div>>1;
bit_count<=8-max;
result<=7'd0;
end
else if (bit_count>3'b000)
begin
if (cur_divident[8]==1'b0)
begin
cur_divident <= cur_divident-cur_divisor;
result[bit_count-1'b1]<=1'b1;
end
else
begin
result[bit_count-1'b1]<=1'b0;
cur_divident <= cur_divident+cur_divisor;
end

bit_count<=bit_count-1;
cur_divisor<= cur_divisor>>1;
end



endmodule

I know that exists some page where you can set divident and divisor and see all the stages of non-restoring division. Does someone know adress?

Thanks in advance!



There is problem in ur code!
check the bold comments in ur code[/b]
 

    VitalyM4

    Points: 2
    Helpful Answer Positive Rating
Thx.
I fixed like this. For all who might need it!

Code:
module div (
	SCAN_EN_SCLK ,              /*Scan Enable*/
	SCAN_IN_SCLK ,              /*Scan Input*/
	SCAN_OUT_SCLK,			   /*Scan output */
	rb_por_cr , 			       /*Asynchronous reset*/
	SCLK ,                 /*Divider Clock*/	
	divisor ,			   /*divisor*/
	we ,				   /*write enable - initiate dividing*/
	result				   /*division result*/
	);
	/*Port direction and types*/
	output [7:0] result ;
	reg [7:0] result ;
	
	input [7:0] divisor ;  
	wire [7:0] divisor;
	input SCLK ;
	wire SCLK ;								   
	input we ;
	wire we;
	input rb_por_cr;
	input SCAN_EN_SCLK;
	input SCAN_IN_SCLK; 	 
	output SCAN_OUT_SCLK; 
	
	
	/*Internal signal declaration*/
	reg [8:0] cur_divident;
	reg [6:0] cur_divisor;
	reg [2:0] bit_count;
	integer i;
	reg [2:0] max;
	
	/*Functional description*/	
	
	/*Create logic finding  MSB 1*/
	always@(divisor)  
		begin 
			max=0;	
			for(i=7;i>0;i=i-1)
				if(divisor[i]==1'b1 & i>=max)
					max=i;		
		end		
	
	wire [7:0] tmp_div=divisor<<(7-max);	 
	/*Division*/
	always@(negedge rb_por_cr or posedge SCLK)  
		if(!rb_por_cr)	
			begin
				cur_divident<=8'd0;
				cur_divisor<=8'd0;   
				bit_count<=3'd0; 
				result<=7'd0;
			end	
		else if(we)
			begin
				cur_divident<=9'd255-tmp_div;
				cur_divisor<=tmp_div>>1;   
				bit_count<=8-max;  
				if (max==0)
					result<=8'hFF;
				else	
					result<=7'd0;
			end
		else if (bit_count>3'b000)
			begin
				if (cur_divident[8]==1'b0)
					begin
						cur_divident <= cur_divident-cur_divisor;	 
						`ifdef debug_modeling
						assert (bit_count!=3'b000) result[bit_count-1'b1]<=1'b1;	else $fatal(0,"Division error selected out of range");
						`else
						result[bit_count-1'b1]<=1'b1;	
						`endif
					end	
				else
					begin
					`ifdef debug_modeling
				assert (bit_count!=3'b000) result[bit_count-1'b1]<=1'b0;	else $fatal(0,"Division error selected out of range");
				`else
				result[bit_count-1'b1]<=1'b0;	
				`endif
				cur_divident <= cur_divident+cur_divisor;
			end
	
	bit_count<=bit_count-1;	  
	cur_divisor<= cur_divisor>>1; 	  
	end		
	
	
	
endmodule
 

Are you sure this will works for all the scenarios??

Is there any difference between the divisors 8'b10001000 & 10001011???
 

pra said:
Are you sure this will works for all the scenarios??

Is there any difference between the divisors 8'b10001000 & 10001011???

I think there is a difference, because variable max finds first 1'b1 MSB in byte and defines number of stages needed for divison. max equal to 0 only in cases 8'b0000_0001 or 8'b0000_0000, so I check for division on 8'd0 and 8'd1, when result equal 8'd255, for all other cases normal divison is performed.

And as I don't need remainder result of division on your divisors the same 8'd1.

So there is no mistake I think.
 

May be I m in hurry n overlooked the actual problem! :D

Yeah you are right!!

I am thinking that the result is remainder of 255/divisor :(

If you are using the same in real design, then you need to recode it efficiently to get rid of extra comparators! :|
 

pra said:
If you are using the same in real design, then you need to recode it efficiently to get
rid of extra comparators! :|

Could you give an example how to do that? You are talking about finding max?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top