Skip to content

Instantly share code, notes, and snippets.

@LIMPIX31
Created February 15, 2026 11:23
Show Gist options
  • Select an option

  • Save LIMPIX31/28353e3a5aaf6a97996cc831ab3128d7 to your computer and use it in GitHub Desktop.

Select an option

Save LIMPIX31/28353e3a5aaf6a97996cc831ab3128d7 to your computer and use it in GitHub Desktop.
Pipelined CORDIC
module cordic_pipeline #
( parameter string MODE = "rotate"
, parameter int ST = 16
, parameter int DW = 16
, parameter int AW = 16
)
( input logic clk
, input logic signed [DW-1:0] i_re
, input logic signed [DW-1:0] i_im
, input logic signed [AW-1:0] i_angle
, output logic signed [DW-1:0] o_re
, output logic signed [DW-1:0] o_im
, output logic signed [AW-1:0] o_angle
);
logic [DW-1:0] re [ST+1];
logic [DW-1:0] im [ST+1];
logic [AW-1:0] angle [ST+1];
assign o_re = re[ST];
assign o_im = im[ST];
assign o_angle = angle[ST];
cordic_prerotate #
( .MODE(MODE)
, .DW(DW)
, .AW(AW)
) u_prelim
( .i_re(i_re)
, .i_im(i_im)
, .i_angle(i_angle)
, .o_re(re[0])
, .o_im(im[0])
, .o_angle(angle[0])
);
generate for (genvar i = 0; i < ST; i++) begin : gen_stages
cordic_stage #
( .MODE(MODE)
, .S(i)
, .DW(DW)
, .AW(AW)
, .ANGLE(int'($atan(2.0 ** -i) / $atan(1.0) * (2.0 ** (AW - 3))))
) u_stage
( .clk(clk)
, .i_re(re[i])
, .i_im(im[i])
, .i_angle(angle[i])
, .o_re(re[i + 1])
, .o_im(im[i + 1])
, .o_angle(angle[i + 1])
);
end endgenerate
endmodule
module cordic_stage #
( parameter string MODE = "rotate"
, parameter int S = 0
, parameter int DW = 16
, parameter int AW = 16
, parameter logic signed [AW-1:0] ANGLE = 0
)
( input logic clk
, input logic signed [DW-1:0] i_re
, input logic signed [DW-1:0] i_im
, input logic signed [AW-1:0] i_angle
, output logic signed [DW-1:0] o_re
, output logic signed [DW-1:0] o_im
, output logic signed [AW-1:0] o_angle
);
wire sign = (MODE == "vector") ? ~i_im[DW-1] : i_angle[AW-1];
wire signed [DW-1:0] re_shr = i_re >>> S;
wire signed [DW-1:0] im_shr = i_im >>> S;
always_ff @(posedge clk) begin
o_re <= sign ? i_re + im_shr : i_re - im_shr;
o_im <= sign ? i_im - re_shr : i_im + re_shr;
o_angle <= sign ? i_angle + ANGLE : i_angle - ANGLE;
end
endmodule
module cordic_prerotate #
( parameter string MODE = "rotate"
, parameter int DW = 16
, parameter int AW = 16
)
( input logic signed [DW-1:0] i_re
, input logic signed [DW-1:0] i_im
, input logic signed [AW-1:0] i_angle
, output logic signed [DW-1:0] o_re
, output logic signed [DW-1:0] o_im
, output logic signed [AW-1:0] o_angle
);
always_comb begin
if (MODE == "vector") begin
unique case ({i_re[DW-1], i_im[DW-1]})
2'b00,
2'b01: begin
o_re = i_re;
o_im = i_im;
o_angle = i_angle;
end
2'b10: begin
o_re = i_im;
o_im = -i_re;
o_angle = {2'b01, i_angle[AW-3:0]};
end
2'b11: begin
o_re = -i_im;
o_im = i_re;
o_angle = {2'b11, i_angle[AW-3:0]};
end
endcase
end else begin
unique case (i_angle[AW-1:AW-2])
2'b00,
2'b11: begin
o_re = i_re;
o_im = i_im;
o_angle = i_angle;
end
2'b01: begin
o_re = -i_im;
o_im = i_re;
o_angle = {2'b00, i_angle[AW-3:0]};
end
2'b10: begin
o_re = i_im;
o_im = -i_re;
o_angle = {2'b11, i_angle[AW-3:0]};
end
endcase
end
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment