Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.naic.edu/~phil/hardware/pdev/fpga/gx/jfft/pdev/rtl/xfft_stage_1.v
Дата изменения: Thu Jun 26 04:28:51 2008
Дата индексирования: Sat Sep 6 20:36:16 2008
Кодировка:

Поисковые слова: внешние планеты
// Stage 1 of radix-2 FFT
// Stage 1 is a butterfly with a degenerate case for
// the twiddle factor. The twiddle is either 1 or -j,
// so the multiplication is done with an adder and a
// multiplexer.
//
// Generated by mkjfft_stage
// Programmable downshift with rounding
//
module xfft_stage_1 (
ck,
reset,
bypassb,
pshift,
sync_i,
sync_o,

a_re,
a_im,
b_re,
b_im,

ovf,
x_re,
x_im,
y_re,
y_im
);
parameter width=18;

input ck;
input reset;
input bypassb;
input pshift;
input sync_i;
output sync_o;

input [width-1:0] a_re;
input [width-1:0] a_im;
input [width-1:0] b_re;
input [width-1:0] b_im;

output ovf;
output [width-1:0] x_re;
output [width-1:0] x_im;
output [width-1:0] y_re;
output [width-1:0] y_im;

wire [width-1:0] ca_re;
wire [width-1:0] ca_im;
wire [width-1:0] cb_re;
wire [width-1:0] cb_im;

// Delay sync output by appropropriate pipeline stages
//
xfft_sync_5 pdel (
.ck ( ck ),
.reset ( reset ),
.i ( sync_i ),
.o ( sync_o )
);

reg [1:0] phase, phase_n;
reg [5:0] ph_drv;
// reg reset_d;

always @(sync_i or reset or phase) begin
if (sync_i | reset)
phase_n = 2'd0;
else
phase_n = phase + 2'd1;
end
always @(posedge ck) begin
// reset_d <= reset;
phase <= phase_n;
ph_drv[0] <= phase_n[1];
ph_drv[1] <= phase_n[1];
ph_drv[2] <= phase_n[1];
ph_drv[3] <= phase_n[1];
ph_drv[4] <= phase_n[0];
ph_drv[5] <= phase_n[0];
end

// Add 1 to input for rounding before downshift
//
wire [width-1:0] as_re;
wire [width-1:0] as_im;
wire [width-1:0] bs_re;
wire [width-1:0] bs_im;
assign as_re = a_re + 18'd1;
assign as_im = a_im + 18'd1;
assign bs_re = b_re + 18'd1;
assign bs_im = b_im + 18'd1;

reg [width-1:0] ax_re;
reg [width-1:0] ax_im;
reg [width-1:0] bx_re;
reg [width-1:0] bx_im;
always @(posedge ck) begin
ax_re <= pshift ? { as_re[width-1], as_re[width-1:1] } : a_re;
ax_im <= pshift ? { as_im[width-1], as_im[width-1:1] } : a_im;
bx_re <= pshift ? { bs_re[width-1], bs_re[width-1:1] } : b_re;
bx_im <= pshift ? { bs_im[width-1], bs_im[width-1:1] } : b_im;
end

// Delay B side by 2 clocks
//
reg [width-1:0] b_re_del1;
reg [width-1:0] b_im_del1;
reg [width-1:0] b_re_del;
reg [width-1:0] b_im_del;
always @(posedge ck) begin
b_re_del1 <= bx_re;
b_im_del1 <= bx_im;
b_re_del <= b_re_del1;
b_im_del <= b_im_del1;
end

// A/B commutator
//
assign ca_re = ph_drv[0] ? b_re_del : ax_re;
assign ca_im = ph_drv[1] ? b_im_del : ax_im;
assign cb_re = ph_drv[2] ? ax_re : b_re_del;
assign cb_im = ph_drv[3] ? ax_im : b_im_del;

// Delay A side by 2 clocks
//
reg [width-1:0] ca_re_del1;
reg [width-1:0] ca_im_del1;
reg [width-1:0] ca_re_del;
reg [width-1:0] ca_im_del;
always @(posedge ck) begin
ca_re_del1 <= ca_re;
ca_im_del1 <= ca_im;
ca_re_del <= ca_re_del1;
ca_im_del <= ca_im_del1;
end

// The butterfly, a single pipeline delay
//
wire [width-1:0] x_bf_re;
wire [width-1:0] x_bf_im;
wire [width-1:0] y_bf_re;
wire [width-1:0] y_bf_im;
xfft_bf bf (
.ck ( ck ),
.a_re ( ca_re_del ),
.a_im ( ca_im_del ),
.b_re ( cb_re ),
.b_im ( cb_im ),

.ovf ( ovf ),
.x_re ( x_bf_re ),
.x_im ( x_bf_im ),
.y_re ( y_bf_re ),
.y_im ( y_bf_im )
);

// In the next to the last stage there are two twiddle factors,
// 1 and -j. Neither of these require an actual complex multiplier
// so I special case it with a single adder. One pipeline delay
//
reg [width-1:0] x_mj_re;
reg [width-1:0] x_mj_im;
reg [width-1:0] y_mj_re;
reg [width-1:0] y_mj_im;
always @(posedge ck) begin
x_mj_re <= x_bf_re;
x_mj_im <= x_bf_im;
y_mj_re <= ph_drv[4] ? y_bf_re : y_bf_im;
y_mj_im <= ph_drv[5] ? y_bf_im : -y_bf_re;
end

assign x_re = x_mj_re;
assign x_im = x_mj_im;
assign y_re = y_mj_re;
assign y_im = y_mj_im;
endmodule