вот генератор sin/cos на кордике, на вход дайте пилу со счетчика. разрядность любая до 32 включительно
CODE
/********************************************************************************
*************/
module cordic_rotate
/********************************************************************************
*************/
#(parameter dw = 12)
/********************************************************************************
*************/
(
input clk,
input reset_n,
input signed [dw-1:0] phase,
input signed [dw-1:0] mag,
input dv,
output signed [dw-1:0] sin_out,
output signed [dw-1:0] cos_out,
output out_valid
);
/********************************************************************************
*************/
typedef logic signed [dw:0] d_type;
localparam p_level = dw-1;
localparam odw = dw+1;
localparam d_type atan_table [0:30] =
'{
pr_round(536870912),
pr_round(316933406),
pr_round(167458907),
pr_round(85004756),
pr_round(42667331),
pr_round(21354465),
pr_round(10679838),
pr_round(5340245),
pr_round(2670163),
pr_round(1335087),
pr_round(667544),
pr_round(333772),
pr_round(166886),
pr_round(83443),
pr_round(41722),
pr_round(20861),
pr_round(10430),
pr_round(5215),
pr_round(2608),
pr_round(1304),
pr_round(652),
pr_round(326),
pr_round(163),
pr_round(81),
pr_round(41),
pr_round(20),
pr_round(10),
pr_round(5),
pr_round(3),
pr_round(1),
pr_round(1)
};
/********************************************************************************
*************/
function integer pr_round;
input integer full_data;
logic one;
logic flag;
begin
one = |full_data[2:0];
flag = ( (!full_data[31])&&(full_data[3]) ) || ( (full_data[31])&&(full_data[3])&&(one) );
pr_round = (flag) ? full_data[31:32-dw-1] + 1 : full_data[31:32-dw-1];
end
endfunction
/********************************************************************************
*************/
reg signed [odw-1:0] x[p_level-1:0];
reg signed [odw-1:0] y[p_level-1:0];
reg signed [odw-1:0] z[p_level-1:0];
integer i;
reg [p_level-1:0] valid_reg;
reg flag[p_level-1:0];
/********************************************************************************
*************/
always_ff @(posedge clk)
begin
if (!reset_n) begin
for(i=0;i<p_level;i++) begin
x[i] <= '0;
y[i] <= '0;
z[i] <= '0;
flag[i] <= 1'b0;
end
end
else if ((dv)||(valid_reg[p_level-1])) begin
x[0] <= mag;
y[0] <= '0;
z[0] <= (phase[dw-1]^phase[dw-2]) ? (2**dw)-2*phase: 2*phase;
flag[0] <= phase[dw-1]^phase[dw-2];
for(i=1;i<p_level;i++) begin
if (z[i-1]<0) begin
x[i] <= x[i-1] + (y[i-1]>>>i);
y[i] <= y[i-1] - (x[i-1]>>>i);
z[i] <= z[i-1] + atan_table[i];
end
else begin
x[i] <= x[i-1] - (y[i-1]>>>i);
y[i] <= y[i-1] + (x[i-1]>>>i);
z[i] <= z[i-1] - atan_table[i];
end
flag[i] <= flag[i-1];
end
end
end
/********************************************************************************
*************/
always_ff @(posedge clk)
begin
if (!reset_n) begin
for(i=0;i<p_level;i++) begin
valid_reg[i] <= 1'b0;
end
end
else begin
valid_reg[0] <= dv;
for(i=1;i<p_level;i++) begin
valid_reg[i] <= valid_reg[i-1];
end
end
end
/********************************************************************************
*************/
assign sin_out = y[p_level-1][odw-1:odw-dw];
assign cos_out = (flag[p_level-1]) ? -$signed(x[p_level-1][odw-1:odw-dw]) : x[p_level-1][odw-1:odw-dw];
assign out_valid = valid_reg[p_level-1];
/********************************************************************************
*************/
endmodule