/**************************************************************
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