`timescale 1ns / 100ps
module cordic_sqrt(
rst_n,
clk,
din,
sqrt_valid_in,
dout,
sqrt_valid_out
);
//=========================================================
// Interface definition
//=========================================================
input rst_n;
input clk;
input [17:0] din;
input sqrt_valid_in;
output [17:0] dout;
output sqrt_valid_out;
//=========================================================
// Interface type
//=========================================================
reg [17:0] dout;
reg sqrt_valid_out;
//=========================================================
// Local parameters
//=========================================================
parameter FRAC_LEN = 9;
//=========================================================
// Internal signal definition
//=========================================================
reg [18:0] x1;
reg [18:0] y1;
reg [19:0] x2;
reg [19:0] y2;
reg [21:0] x3;
reg [21:0] y3;
reg [24:0] x4;
reg [24:0] y4;
reg [28:0] x5;
reg [28:0] y5;
reg [31:0] x6;
reg [31:0] y6;
reg [32:0] x7;
reg [32:0] y7;
reg [33:0] x8;
wire [17:0] xs1, ys1;
wire [18:0] xs2, ys2;
wire [20:0] xs3, ys3;
wire [23:0] xs4, ys4;
wire [25:0] xs5, ys5;
wire [25:0] xs6, ys6;
wire [25:0] xs7, ys7;
wire [25:0] xs8;
reg [3:0] shift_cnt;
reg [3:0] shift_cnt_d1;
reg [3:0] shift_cnt_d2;
reg [9:0] valid_d;
//=========================================================
// shift_cnt process
//=========================================================
always @(posedge clk or negedge rst_n)
if (!rst_n)
shift_cnt <= 4'd0;
else if (sqrt_valid_in) begin
if (din[17])
shift_cnt <= 4'd8;
else if (din[16] || din[15])
shift_cnt <= 4'd7;
else if (din[14] || din[13])
shift_cnt <= 4'd6;
else if (din[12] || din[11])
shift_cnt <= 4'd5;
else if (din[10] || din[9])
shift_cnt <= 4'd4;
else if (din[8] || din[7])
shift_cnt <= 4'd3;
else if (din[6] || din[5])
shift_cnt <= 4'd2;
else if (din[4] || din[3])
shift_cnt <= 4'd1;
else
shift_cnt <= 4'd0;
end
//=========================================================
// shift_cnt_d1 process
//=========================================================
always @ (posedge clk or negedge rst_n)
if (!rst_n) begin
shift_cnt_d1 <= 4'd0;
shift_cnt_d2 <= 4'd0;
end
else begin
shift_cnt_d1 <= shift_cnt;
shift_cnt_d2 <= shift_cnt_d1;
end
//=========================================================
// x1, y1 process
//=========================================================
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
x1 <= 19'd0;
y1 <= 19'd0;
end
else if (sqrt_valid_in) begin
if (din[16] || din[15]) begin
x1 <= {1'b0, din} + 19'b0_0001_0000_0000_0000_00;
y1 <= {1'b0, din} - 19'b0_0001_0000_0000_0000_00;
end
else if (din[14] || din[13]) begin
x1 <= {1'b0, din} + 19'b0_0000_0100_0000_0000_00;
y1 <= {1'b0, din} - 19'b0_0000_0100_0000_0000_00;
end
else if (din[12] || din[11]) begin
x1 <= {1'b0, din} + 19'b0_0000_0001_0000_0000_00;
y1 <= {1'b0, din} - 19'b0_0000_0001_0000_0000_00;
end
else if (din[10] || din[9]) begin
x1 <= {1'b0, din} + 19'b0_0000_0000_0100_0000_00;
y1 <= {1'b0, din} - 19'b0_0000_0000_0100_0000_00;
end
else if (din[8] || din[7]) begin
x1 <= {1'b0, din} + 19'b0_0000_0000_0001_0000_00;
y1 <= {1'b0, din} - 19'b0_0000_0000_0001_0000_00;
end
else if (din[6] || din[5]) begin
x1 <= {1'b0, din} + 19'b0_0000_0000_0000_0100_00;
y1 <= {1'b0, din} - 19'b0_0000_0000_0000_0100_00;
end
else if (din[4] || din[3]) begin
x1 <= {1'b0, din} + 19'b0_0000_0000_0000_0001_00;
y1 <= {1'b0, din} - 19'b0_0000_0000_0000_0001_00;
end
else begin
x1 <= {1'b0, din} + 19'b0_0000_0000_0000_0000_01;
y1 <= {1'b0, din} - 19'b0_0000_0000_0000_0000_01;
end
end
//=========================================================
// xs1, ys1 process
//=========================================================
RndTrim #(.IB(19),.NT(1),.NR(0))RndRrim_inst1(.din(x1),.dout(xs1));
RndTrim #(.IB(19),.NT(1),.NR(0))RndTrim_inst2(.din(y1),.dout(ys1));
//=========================================================
// x2, y2 process
//=========================================================
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
x2 <= 20'd0;
y2 <= 20'd0;
end
else if (!ys1[17]) begin
x2 <= {1'b0, xs1, 1'b0} - {2'b00, ys1};
y2 <= {1'b0, ys1, 1'b0} - {2'b00, xs1};
end
else begin
x2 <= {1'b0, xs1, 1'b0} + {2'b00, ys1};
y2 <= {1'b0, ys1, 1'b0} + {2'b00, xs1};
end
//=========================================================
// xs2, ys2 process
//=========================================================
RndTrim #(.IB(20),.NT(1),.NR(0))RndRrim_inst3(.din(x2),.dout(xs2));
RndTrim #(.IB(20),.NT(1),.NR(0))RndTrim_inst4(.din(y2),.dout(ys2));
//=========================================================
// x3, y3 process
//=========================================================
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
x3 <= 22'd0;
y3 <= 22'd0;
end
else if (!ys2[18]) begin
x3 <= {xs2[18], xs2, 2'b00} - {{3{ys2[18]}}, ys2};
y3 <= {ys2[18], ys2, 2'b00} - {{3{xs2[18]}}, xs2};
end
else begin
x3 <= {xs2[18], xs2, 2'b00} + {{3{ys2[18]}}, ys2};
y3 <= {ys2[18], ys2, 2'b00} + {{3{xs2[18]}}, xs2};
end
//=========================================================
// xs3, ys3 process
//=========================================================
RndTrim #(.IB(22),.NT(1),.NR(0))RndRrim_inst5(.din(x3),.dout(xs3));
RndTrim #(.IB(22),.NT(1),.NR(0))RndTrim_inst6(.din(y3),.dout(ys3));
//=========================================================
// x4, y4 process
//=========================================================
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
x4 <= 25'd0;
y4 <= 25'd0;
end
else if (!ys3[20]) begin
x4 <= {xs3[20], xs3, 3'b000} - {{4{ys3[20]}}, ys3};
y4 <= {ys3[20], ys3, 3'b000} - {{4{xs3[20]}}, xs3};
end
else begin
x4 <= {xs3[20], xs3, 3'b000} + {{4{ys3[20]}}, ys3};
y4 <= {ys3[20], ys3, 3'b000} + {{4{xs3[20]}}, xs3};
end
//=========================================================
// xs4, ys4 process
//=========================================================
RndTrim #(.IB(25),.NT(1),.NR(0))RndRrim_inst7(.din(x4),.dout(xs4));
RndTrim #(.IB(25),.NT(1),.NR(0))RndTrim_inst8(.din(y4),.dout(ys4));
//=========================================================
// x5, y5 process
//=========================================================
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
x5 <= 29'd0;
y5 <= 29'd0;
end
else if (!ys4[23]) begin
x5 <= {xs4[23], xs4, 4'b0000} - {{5{ys4[23]}}, ys4};
y5 <= {ys4[23], ys4, 4'b0000} - {{5{xs4[23]}}, xs4};
end
else begin
x5 <= {xs4[23], xs4, 4'b0000} + {{5{ys4[23]}}, ys4};
y5 <= {ys4[23], ys4, 4'b0000} + {{5{xs4[23]}}, xs4};
end
//=========================================================
// xs5, ys5 process
//=========================================================
RndTrim #(.IB(29),.NT(1),.NR(2))RndRrim_inst9 (.din(x5),.dout(xs5));
RndTrim #(.IB(29),.NT(1),.NR(2))RndTrim_inst10(.din(y5),.dout(ys5));
//=========================================================
// x6, y6 process
//=========================================================
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
x6 <= 32'd0;
y6 <= 32'd0;
end
else if (!ys5[25]) begin
x6 <= {xs5[25], xs5, 5'b00000} - {{6{ys5[25]}}, ys5};
y6 <= {ys5[25], ys5, 5'b00000} - {{6{xs5[25]}}, xs5};
end
else begin
x6 <= {xs5[25], xs5, 5'b00000} + {{6{ys5[25]}}, ys5};
y6 <= {ys5[25], ys5, 5'b00000} + {{6{xs5[25]}}, xs5};
end
//=========================================================
// xs6, ys6 process
//=========================================================
RndTrim #(.IB(32),.NT(1),.NR(5))RndRrim_inst11(.din(x6),.dout(xs6));
RndTrim #(.IB(32),.NT(1),.NR(5))RndTrim_inst12(.din(y6),.dout(ys6));
//=========================================================
// x7, y7 process
//=========================================================
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
x7 <= 33'd0;
y7 <= 33'd0;
end
else if (!ys6[25]) begin
x7 <= {xs6[25], xs6, 6'b000000} - {{7{ys6[25]}}, ys6};
y7 <= {ys6[25], ys6, 6'b000000} - {{7{xs6[25]}}, xs6};
end
else begin
x7 <= {xs6[25], xs6, 6'b000000} + {{7{ys6[25]}}, ys6};
y7 <= {ys6[25], ys6, 6'b000000} + {{7{xs6[25]}}, xs6};
end
//=========================================================
// xs7, ys7 process
//=========================================================
RndTrim #(.IB(33),.NT(1),.NR(6))RndRrim_inst13(.din(x7),.dout(xs7));
RndTrim #(.IB(33),.NT(1),.NR(6))RndTrim_inst14(.din(y7),.dout(ys7));
//=========================================================
// x8 process
//=========================================================
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
x8 <= 34'd0;
end
else if (!ys7[25]) begin
x8 <= {xs7[25], xs7, 7'b0000000} - {{8{ys7[25]}}, ys7};
end
else begin
x8 <= {xs7[25], xs7, 7'b0000000} + {{8{ys7[25]}}, ys7};
end
//=========================================================
// xs8 process
//=========================================================
RndTrim #(.IB(34),.NT(1),.NR(7))RndRrim_inst15(.din(x8),.dout(xs8));
// K = 10011010010000001
// K = 78977
// <<7 <<10 <<12 <<13 <<16
reg [33 : 0] sum1;
reg [38 : 0] sum2;
reg [42 : 0] sum3;
wire [39 : 0] sum4;
reg [43 : 0] sum;
//=========================================================
// sum1 process
//=========================================================
always @ (posedge clk or negedge rst_n)
if (!rst_n)
sum1 <= 34'd0;
else
sum1 <= {{8{xs8[25]}}, xs8} + {xs8[25], xs8, 7'b0000_000};
//=========================================================
// sum2 process
//=========================================================
always @ (posedge clk or negedge rst_n)
if (!rst_n)
sum2 <= 39'd0;
else
sum2 <= {{3{xs8[25]}}, xs8, 10'b0000_0000_00} + {xs8[25], xs8, 12'b0000_0000_0000};
//=========================================================
// sum3 process
//=========================================================
always @ (posedge clk or negedge rst_n)
if (!rst_n)
sum3 <= 43'd0;
else
sum3 <= {{4{xs8[25]}}, xs8, 13'b0000_0000_0000_0} + {xs8[25], xs8, 16'b0000_0000_0000_0000};
//=========================================================
// sum4 process
//=========================================================
assign sum4 = {{6{sum1[33]}}, sum1} + {sum2[38], sum2};
//=========================================================
// sum process
//=========================================================
always @ (posedge clk or negedge rst_n)
if (!rst_n)
sum <= 44'd0;
else
sum <= {sum3[42], sum3} + {{4{sum4[39]}}, sum4};
wire [17: 0] result_0;
wire [17: 0] result_1;
wire [17: 0] result_2;
wire [17: 0] result_3;
wire [17: 0] result_4;
wire [17: 0] result_5;
wire [17: 0] result_6;
wire [17: 0] result_7;
//=========================================================
// result_i process
//=========================================================
RndTrim #(.IB(44),.NT(10),.NR(16))RndRrim_inst16(.din(sum),.dout(result_0));
RndTrim #(.IB(44),.NT(9 ),.NR(17))RndRrim_inst17(.din(sum),.dout(result_1));
RndTrim #(.IB(44),.NT(8 ),.NR(18))RndRrim_inst18(.din(sum),.dout(result_2));
RndTrim #(.IB(44),.NT(7 ),.NR(19))RndRrim_inst19(.din(sum),.dout(result_3));
RndTrim #(.IB(44),.NT(6 ),.NR(20))RndRrim_inst20(.din(sum),.dout(result_4));
RndTrim #(.IB(44),.NT(5 ),.NR(21))RndRrim_inst21(.din(sum),.dout(result_5));
RndTrim #(.IB(44),.NT(4 ),.NR(22))RndRrim_inst22(.din(sum),.dout(result_6));
RndTrim #(.IB(44),.NT(3 ),.NR(23))RndRrim_inst23(.din(sum),.dout(result_7));
//=========================================================
// dout process
//=========================================================
always @ (posedge clk or negedge rst_n)
if (!rst_n)
dout <= 18'd0;
else if (valid_d[9]) begin
if (shift_cnt_d2 == 4'd0)
dout <= result_0;
else if (shift_cnt_d2 == 4'd1)
dout <= result_1;
else if (shift_cnt_d2 == 4'd2)
dout <= result_2;
else if (shift_cnt_d2 == 4'd3)
dout <= result_3;
else if (shift_cnt_d2 == 4'd4)
dout <= result_4;
else if (shift_cnt_d2 == 4'd5)
dout <= result_5;
else if (shift_cnt_d2 == 4'd6)
dout <= result_6;
else if (shift_cnt_d2 == 4'd7)
dout <= result_7;
else if (shift_cnt_d2 == 4'd8)
dout <= 18'd0;
end
else
dout <= 18'd0;
//=========================================================
// valid_d process
//=========================================================
always @ (posedge clk or negedge rst_n)
if (!rst_n)
valid_d <= 1'b0;
else
valid_d <= {valid_d[8:0], sqrt_valid_in};
//=========================================================
// sqrt_valid_out process
//=========================================================
always @ (posedge clk or negedge rst_n)
if (!rst_n)
sqrt_valid_out <= 1'b0;
else if (valid_d[9])
sqrt_valid_out <= 1'b1;
else
sqrt_valid_out <= 1'b0;
endmodule