基于十级流水线的开立方根算法

/**************************************************************
binary bit:
( 2'b10*a + b )^2'b11 = 4'b1000 * a^2'b11 + b * { 3'b110*a*(2'b10*a +b) + 1'b1}
**************************************************************/
`timescale 10 ns/ 1 ns
module cube_root(
clk,rst_n,
numeral,
cube_root
);
input clk,rst_n;//clock and reset signals
input[31:0] numeral;
output reg[10:0] cube_root;//cube root

reg rst_n1,sys_rst_n;
always@(posedge clk or negedge rst_n)
 if(!rst_n) {sys_rst_n,rst_n1} <= 0;
 else  {sys_rst_n,rst_n1} <= {rst_n1,1'b1};
 
reg  cnt_p,cnt_n;
wire clk1,clk2;
always@(negedge clk or negedge sys_rst_n)
 if(!sys_rst_n)  cnt_p <= 0;
 else    cnt_p <= ~cnt_p;

always@(posedge clk or negedge sys_rst_n)
 if(!sys_rst_n)  cnt_n <= 0;
 else    cnt_n <= ~cnt_n;
 
assign clk1 = cnt_p && cnt_n;
assign clk2 = ~(cnt_p || cnt_n);

reg[10:0] bri_root[0:10];
reg[31:0] residue [0:9];
reg[31:0] mid_res [0:9];
reg[31:0] bri_res [0:10];
reg [2:0] part_3bits [0:10];
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//part10
always@(posedge clk1 or negedge sys_rst_n)     //NO.1
 if(!sys_rst_n)  part_3bits[10] <= 0;
 else   part_3bits[10] <= {1'b0,numeral[31:30]};
 
always@(posedge clk1 or negedge sys_rst_n)  //NO.2
begin
 if(!sys_rst_n) begin
  bri_res[10]  <= 0;
  bri_root[10] <= 0;
 end
 else begin
  if(!part_3bits[10]) begin
   bri_root[10] <= 0;
   bri_res[10]  <= 0;
  end
  else begin
   bri_root[10] <= 1;
   bri_res[10]  <= part_3bits[10]-1;
  end
 end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//part9
reg[2:0] part9;
always@(posedge clk1 or negedge sys_rst_n)  //NO.2
 if(!sys_rst_n)  {part_3bits[9],part9} <= 0;
 else   {part_3bits[9],part9} <= {part9,numeral[29:27]};

always@(posedge clk2 or negedge sys_rst_n) //NO.3
 if(!sys_rst_n)    residue[9] <= 0;
 else      residue[9] <= {bri_res[10][28:0],part_3bits[9]};

always@(posedge clk2 or negedge sys_rst_n)  //NO.3
 if(!sys_rst_n)    mid_res[9] <= 0;
 else if(!bri_root[10])  mid_res[9] <= 0;
 else      mid_res[9] <= ({bri_root[10],2'd0} + {bri_root[10],1'd0})*{bri_root[10],1'd1} + 1'd1 ;

always@(posedge clk1 or negedge sys_rst_n)  //NO.4
begin
 if(!sys_rst_n) begin
  bri_root[9] <= 0;
  bri_res[9]  <= 0;
 end
 else begin
  if(!bri_root[10]) begin
   if(!part_3bits[9]) begin
    bri_root[9]  <= 0;
    bri_res[9]  <= 0;
   end
   else begin
    bri_root[9]  <= 1;
    bri_res[9]  <= part_3bits[9]-1;
   end
  end
  else begin
   if(!bri_res[10]) begin
    bri_root[9] <= {bri_root[10][9:0],1'b0};
    bri_res[9] <= part_3bits[9];
   end
   else begin
    if(residue[9] >= mid_res[9]) begin
     bri_root[9] <= {bri_root[10][9:0],1'b1};
     bri_res[9]  <= residue[9] - mid_res[9];
    end
    else begin
     bri_root[9] <= {bri_root[10][9:0],1'b0};
     bri_res[9] <= residue[9];
    end
   end
  end
 end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//part8
reg[5:0] part8;
always@(posedge clk1 or negedge sys_rst_n) //NO.4
 if(!sys_rst_n)  {part_3bits[8],part8} <= 0;
 else   {part_3bits[8],part8} <= {part8,numeral[26:24]};

always@(posedge clk2 or negedge sys_rst_n)  //NO.5
 if(!sys_rst_n)     residue[8] <= 0;
 else       residue[8] <= {bri_res[9][28:0],part_3bits[8]};

always@(posedge clk2 or negedge sys_rst_n) //NO.5
 if(!sys_rst_n)    mid_res[8] <= 0;
 else if(!bri_root[9])  mid_res[8] <= 0;
 else      mid_res[8] <= ({bri_root[9],2'd0} + {bri_root[9],1'd0})*{bri_root[9],1'd1} + 1'd1;

always@(posedge clk1 or negedge sys_rst_n)  //NO.6
begin
 if(!sys_rst_n) begin
  bri_root[8] <=0;
  bri_res[8] <= 0;
 end
 else begin
  if(!bri_root[9]) begin
   if(!part_3bits[8]) begin
    bri_root[8] <= 0;
    bri_res[8]  <= 0;
   end
   else begin
    bri_root[8] <= 1;
    bri_res[8] <= part_3bits[8]-1;
   end
  end
  else begin
   if(!bri_res[9]) begin
    bri_root[8] <= {bri_root[9][9:0],1'b0};
    bri_res[8] <= part_3bits[8];
   end 
   else begin     
    if(residue[8] >= mid_res[8]) begin
     bri_root[8] <= {bri_root[9][9:0],1'b1};
     bri_res[8] <= residue[8] - mid_res[8];
    end
    else begin
     bri_root[8] <= {bri_root[9][9:0],1'b0};
     bri_res[8] <= residue[8];
    end
   end
  end
 end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//part7
reg[8:0] part7;
always@(posedge clk1 or negedge sys_rst_n)  //NO.6
 if(!sys_rst_n)  {part_3bits[7],part7} <= 0;
 else   {part_3bits[7],part7} <= {part7,numeral[23:21]};
 
always@(posedge clk2 or negedge sys_rst_n)  //NO.7
 if(!sys_rst_n)     residue[7] <= 0;
 else       residue[7] <={bri_res[8][28:0],part_3bits[7]};

always@(posedge clk2 or negedge sys_rst_n)  //NO.7
 if(!sys_rst_n)     mid_res[7] <= 0;
 else if(!bri_root[8])   mid_res[7] <= 0;
 else       mid_res[7] <= ({bri_root[8],2'd0} + {bri_root[8],1'd0})*{bri_root[8],1'd1} + 1'd1;

always@(posedge clk1 or negedge sys_rst_n)  //NO.8
begin
 if(!sys_rst_n) begin
  bri_root[7]<= 0;
  bri_res[7] <= 0;
 end
 else begin
  if(!bri_root[8]) begin
   if(!part_3bits[7]) begin
    bri_root[7] <= 0;
    bri_res[7]  <= 0;
   end
   else begin
    bri_root[7] <= 1;
    bri_res[7]  <= part_3bits[7]-1;
   end
  end
  else begin
   if(!bri_res[8]) begin
    bri_root[7] <= {bri_root[8][9:0],1'b0};
    bri_res[7]  <= part_3bits[7];
   end
   else begin 
    if(residue[7] >= mid_res[7]) begin
     bri_root[7] <= {bri_root[8][9:0],1'b1};
     bri_res[7]  <= residue[7] - mid_res[7];
    end
    else begin
     bri_root[7] <= {bri_root[8][9:0],1'b0};
     bri_res[7]  <= residue[7];
    end
   end
  end
 end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//part6
reg[11:0] part6;
always@(posedge clk1 or negedge sys_rst_n)  //NO.8
 if(!sys_rst_n)  {part_3bits[6],part6} <= 0;
 else   {part_3bits[6],part6} <= {part6,numeral[20:18]};

always@(posedge clk2 or negedge sys_rst_n)  //NO.9
 if(!sys_rst_n)     residue[6] <= 0;
 else       residue[6] <= {bri_res[7][28:0],part_3bits[6]};  //NO.9

always@(posedge clk2 or negedge sys_rst_n)
 if(!sys_rst_n)     mid_res[6] <= 0;
 else if(!bri_root[7])  mid_res[6] <= 0;
 else       mid_res[6] <= ({bri_root[7],2'd0} + {bri_root[7],1'd0})*{bri_root[7],1'd1} + 1'd1;

always@(posedge clk1 or negedge sys_rst_n)  //NO.10
begin
 if(!sys_rst_n) begin
  bri_root[6]<= 0;
  bri_res[6] <= 0;
 end
 else begin
  if(!bri_root[7]) begin
   if(!part_3bits[6]) begin
    bri_root[6] <= 0;
    bri_res[6]  <= 0;
   end
   else begin
    bri_root[6] <= 1;
    bri_res[6]  <= part_3bits[6]-1;
   end
  end
  else begin
   if(!bri_res[7]) begin
    bri_root[6] <= {bri_root[7][9:0],1'b0};
    bri_res[6]  <= part_3bits[6];
   end
   else begin   
    if(residue[6] >= mid_res[6]) begin
     bri_root[6] <= {bri_root[7][9:0],1'b1};
     bri_res[6]  <= residue[6] - mid_res[6];
    end
    else begin
     bri_root[6] <= {bri_root[7][9:0],1'b0};
     bri_res[6]  <= residue[6];
    end
   end
  end
 end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//part5
reg[14:0] part5;
always@(posedge clk1 or negedge sys_rst_n) //NO.10
 if(!sys_rst_n)  {part_3bits[5],part5} <= 0;
 else   {part_3bits[5],part5} <= {part5,numeral[17:15]};
 
always@(posedge clk2 or negedge sys_rst_n) //NO.11
 if(!sys_rst_n)    residue[5] <= 0;
 else      residue[5] <= {bri_res[6][28:0],part_3bits[5]};

always@(posedge clk2 or negedge sys_rst_n)  //NO.11
 if(!sys_rst_n)     mid_res[5] <= 0;
 else if(!bri_root[6])  mid_res[5] <= 0;
 else       mid_res[5] <= ({bri_root[6],2'd0} + {bri_root[6],1'd0})*{bri_root[6],1'd1} + 1'd1;

always@(posedge clk1 or negedge sys_rst_n)  //NO.12
begin
 if(!sys_rst_n) begin
  bri_root[5]<= 0;
  bri_res[5] <= 0;
 end
 else begin
  if(!bri_root[6]) begin
   if(!part_3bits[5]) begin
    bri_root[5] <= 0;
    bri_res[5]  <= 0;
   end
   else begin
    bri_root[5] <= 1;
    bri_res[5]  <= part_3bits[5]-1;
   end
  end
  else begin
   if(!bri_res[6]) begin
    bri_root[5] <= {bri_root[6][9:0],1'b0};
    bri_res[5]  <= part_3bits[5];
   end
   else begin     
    if(residue[5] >= mid_res[5]) begin
     bri_root[5] <= {bri_root[6][9:0],1'b1};
     bri_res[5]  <= residue[5] - mid_res[5];
    end
    else begin
     bri_root[5] <= {bri_root[6][9:0],1'b0};
     bri_res[5]  <= residue[5];
    end
   end
  end
 end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//part4
reg[17:0] part4;
always@(posedge clk1 or negedge sys_rst_n)  //NO.12
 if(!sys_rst_n)  {part_3bits[4],part4} <= 0;
 else   {part_3bits[4],part4} <= {part4,numeral[14:12]};

always@(posedge clk2 or negedge sys_rst_n)  //NO.13
 if(!sys_rst_n)     residue[4] <= 0;
 else       residue[4] <= {bri_res[5][28:0],part_3bits[4]};

always@(posedge clk2 or negedge sys_rst_n)   //NO.13
 if(!sys_rst_n)     mid_res[4] <= 0;
 else if(!bri_root[5])  mid_res[4] <= 0;
 else       mid_res[4] <= ({bri_root[5],2'd0} + {bri_root[5],1'd0})*{bri_root[5],1'd1} + 1'd1;

always@(posedge clk1 or negedge sys_rst_n)  //NO.14
begin
 if(!sys_rst_n) begin
  bri_root[4]<= 0;
  bri_res[4] <= 0;
 end
 else begin
  if(!bri_root[5]) begin
   if(!part_3bits[4]) begin
    bri_root[4] <= 0;
    bri_res[4]  <= 0;
   end
   else begin
    bri_root[4] <= 1;
    bri_res[4]  <= part_3bits[4]-1;
   end
  end
  else begin
   if(!bri_res[5]) begin
    bri_root[4] <= {bri_root[5][9:0],1'b0};
    bri_res[4] <= part_3bits[4];
   end
   else begin 
    if(residue[4] >= mid_res[4]) begin
     bri_root[4] <= {bri_root[5][9:0],1'b1};
     bri_res[4] <= residue[4] - mid_res[4];
    end
    else begin
     bri_root[4] <= {bri_root[5][9:0],1'b0};
     bri_res[4] <= residue[4];
    end
   end
  end
 end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//part3
reg[20:0] part3;
always@(posedge clk1 or negedge sys_rst_n)   //No.14
 if(!sys_rst_n)  {part_3bits[3],part3} <= 0;
 else   {part_3bits[3],part3} <= {part3,numeral[11:9]};
 
always@(posedge clk2 or negedge sys_rst_n) //NO.15
 if(!sys_rst_n)     residue[3] <= 0;
 else       residue[3] <= {bri_res[4][28:0],part_3bits[3]};

always@(posedge clk2 or negedge sys_rst_n) //No.15
 if(!sys_rst_n)     mid_res[3] <= 0;
 else if(!bri_root[4])   mid_res[3] <= 0;
 else       mid_res[3] <= ({bri_root[4],2'd0} + {bri_root[4],1'd0})*{bri_root[4],1'd1} + 1'd1;

always@(posedge clk1 or negedge sys_rst_n)  //No.16
begin
 if(!sys_rst_n) begin
  bri_root[3]<= 0;
  bri_res[3] <= 0;
 end
 else begin
  if(!bri_root[4]) begin
   if(!part_3bits[3]) begin
    bri_root[3] <= 0;
    bri_res[3]  <= 0;
   end
   else begin
    bri_root[3] <= 1;
    bri_res[3]  <= part_3bits[3]-1;
   end
  end
  else begin
   if(!bri_res[4]) begin
    bri_root[3] <= {bri_root[4][9:0],1'b0};
    bri_res[3] <= part_3bits[3];
   end
   else begin
    if(residue[3] >= mid_res[3]) begin
     bri_root[3] <= {bri_root[4][9:0],1'b1};
     bri_res[3] <= residue[3] - mid_res[3];
    end
    else begin
     bri_root[3] <= {bri_root[4][9:0],1'b0};
     bri_res[3] <= residue[3];
    end
   end
  end
 end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//part2
reg[23:0] part2;
always@(posedge clk1 or negedge sys_rst_n)  //NO.16
 if(!sys_rst_n)  {part_3bits[2],part2} <= 0;
 else   {part_3bits[2],part2} <= {part2,numeral[8:6]};

always@(posedge clk2 or negedge sys_rst_n) //NO.17
 if(!sys_rst_n)     residue[2] <= 0;
 else       residue[2] <= {bri_res[3][28:0],part_3bits[2]};

always@(posedge clk2 or negedge sys_rst_n)  //NO.17
 if(!sys_rst_n)     mid_res[2] <= 0;
 else if(!bri_root[3])  mid_res[2] <= 0;
 else       mid_res[2] <= ({bri_root[3],2'd0} + {bri_root[3],1'd0})*{bri_root[3],1'd1} + 1'd1;
 
always@(posedge clk1 or negedge sys_rst_n)  //NO.18
begin
 if(!sys_rst_n) begin
  bri_root[2]<= 0;
  bri_res[2] <= 0;
 end
 else begin
  if(!bri_root[3]) begin
   if(!part_3bits[2]) begin
    bri_root[2] <= 0;
    bri_res[2]  <= 0;
   end
   else begin
    bri_root[2] <= 1;
    bri_res[2]  <= part_3bits[2]-1;
   end
  end
  else begin
   if(!bri_res[3]) begin
    bri_root[2] <= {bri_root[3][9:0],1'b0};
    bri_res[2] <= part_3bits[2];
   end
   else begin
        
    if(residue[2] >= mid_res[2]) begin
     bri_root[2] <= {bri_root[3][9:0],1'b1};
     bri_res[2] <= residue[2] - mid_res[2];
    end
    else begin
     bri_root[2] <= {bri_root[3][9:0],1'b0};
     bri_res[2] <= residue[2];
    end
   end
  end
 end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//part1
reg[26:0] part1;
always@(posedge clk1 or negedge sys_rst_n)  //No.18
 if(!sys_rst_n)  {part_3bits[1],part1} <= 0;
 else   {part_3bits[1],part1} <= {part1,numeral[5:3]};

always@(posedge clk2 or negedge sys_rst_n)  //NO.19
 if(!sys_rst_n)     residue[1] <= 0;
 else       residue[1] <= {bri_res[2][28:0],part_3bits[1]};

always@(posedge clk2 or negedge sys_rst_n) //No.19
 if(!sys_rst_n)     mid_res[1]  <= 0;
 else if(!bri_root[2])   mid_res[1]  <= 0;
 else       mid_res[1]  <= ({bri_root[2],2'd0} + {bri_root[2],1'd0})*{bri_root[2],1'd1} + 1'd1;
 
always@(posedge clk1 or negedge sys_rst_n) //No.20
begin
 if(!sys_rst_n) begin
  bri_root[1]<= 0;
  bri_res[1] <= 0;
 end
 else begin
  if(!bri_root[2]) begin
   if(!part_3bits[1]) begin
    bri_root[1] <= 0;
    bri_res[1]  <= 0;
   end
   else begin
    bri_root[1] <= 1;
    bri_res[1]  <= part_3bits[1]-1;
   end
  end
  else begin
   if(!bri_res[2]) begin
    bri_root[1] <= {bri_root[2][9:0],1'b0};
    bri_res[1] <= part_3bits[1];
   end
   else begin
    if(residue[1] >= mid_res[1]) begin
     bri_root[1] <= {bri_root[2][9:0],1'b1};
     bri_res[1]  <= residue[1] - mid_res[1];
    end
    else begin
     bri_root[1] <= {bri_root[2][9:0],1'b0};
     bri_res[1]  <= residue[1];
    end
   end
  end
 end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//part0
reg[29:0] part0;
always@(posedge clk1 or negedge sys_rst_n) //No.20
 if(!sys_rst_n)  {part_3bits[0],part0} <= 0;
 else   {part_3bits[0],part0} <= {part0,numeral[2:0]};
 
always@(posedge clk2 or negedge sys_rst_n)  //NO.21
 if(!sys_rst_n)     residue[0]  <= 0;
 else       residue[0]  <= {bri_res[1][28:0],part_3bits[0]};

always@(posedge clk2 or negedge sys_rst_n)  //No.21
 if(!sys_rst_n)     mid_res[0]  <= 0;
 else if(!bri_root[1])   mid_res[0]  <= 0;
 else       mid_res[0]  <= ({bri_root[1],2'd0} + {bri_root[1],1'd0})*{bri_root[1],1'd1}  + 1'd1;

always@(posedge clk1 or negedge sys_rst_n) //No.22
begin
 if(!sys_rst_n) begin
  bri_root[0] <= 0;
  bri_res[0]  <= 0;
 end
 else begin
  if(!bri_root[1]) begin
   if(!part_3bits[0]) begin
    bri_root[0] <= 0;
    bri_res[0]  <= 0;
   end
   else begin
    bri_root[0] <= 1;
    bri_res[0]  <= part_3bits[0]-1;
   end
  end 
  else begin
   if(!bri_res[1]) begin
    bri_root[0] <= {bri_root[1][9:0],1'b0};
    bri_res[0]  <= part_3bits[0];
   end
   else begin
    if(residue[0] >= mid_res[0]) begin
     bri_root[0] <= {bri_root[1][9:0],1'b1};
     bri_res[0]  <= residue[0] - mid_res[0];
    end
    else begin
     bri_root[0] <= {bri_root[1][9:0],1'b0};
     bri_res[0]  <= residue[0];
    end
   end
  end
 end
end
////////////////////////////////////////////////////////////////////////////////////////////////////////////
always@(posedge clk2 or negedge sys_rst_n)  //NO.23
 if(!sys_rst_n)  cube_root <= 11'd0;
 else         cube_root <= bri_root[0];

endmodule


 /***********************************************************************/

`timescale 10 ns/ 1 ns
module tb_cube_root();
                                
reg clk;
reg [31:0] numeral;
reg rst_n;
// wires                                              
wire [10:0] cube_root;
  
cube_root u_cube_root (
 .clk(clk),
 .cube_root(cube_root),
 .numeral(numeral),
 .rst_n(rst_n)
);

initial                                               
begin                                                 
clk =0;
rst_n = 0;
#1 rst_n = 1;
#3;
#4 numeral = 1;
#4 numeral = 8;
#4 numeral = 27;
#4 numeral = 64;
#4 numeral = 5*5*5;
#4 numeral = 6*6*6;
#4 numeral = 7*7*7;
#4 numeral = 8*8*8;
#4 numeral = 9*9*9;
#4 numeral = 10*10*10;
#4 numeral = 11*11*11;
#4 numeral = 12*12*12;
#4 numeral = 13*13*13;
#4 numeral = 14*14*14;
#4 numeral = 15*15*15;
#4 numeral = 16*16*16;
#4 numeral = 17*17*17;
#4 numeral = 18*18*18;
#4 numeral = 19*19*19;


#3258 $stop;              
end

always #1 clk = ~clk;

initial                                               
begin
 $monitor($time,"\t%15d\t\t 's cube root is %6d",numeral,cube_root);             
end

                                   
endmodule

你可能感兴趣的:(算法)