采用altera cyclone IV FPGA 设计的2048点FFT源码分享

部分代码如下,完整工程代码见文章末尾。

module fft_2048(
  rst,
  clk,
  inv_i,
  data_imag_in,
  data_real_in,
  master_sink_dav,
  master_sink_ena,
  master_sink_sop,
  fft_imag_out,
  fft_real_out,
  exponent_out,
  master_source_dav,
  master_source_ena,
  master_source_sop,
  master_source_eop
);

input  rst;
input  clk;
input  inv_i;
input  [9:0] data_imag_in;
input  [9:0] data_real_in;
input  master_sink_dav;
output  master_sink_ena;
input   master_sink_sop;
output  [9:0] fft_imag_out;
output  [9:0] fft_real_out;
output  [5:0] exponent_out;
input  master_source_dav;
output  master_source_ena;
output  master_source_sop;
output  master_source_eop;

wire  master_sink_ena;
wire  master_sink_sop;
wire  master_source_ena;
wire  master_source_sop;
wire  master_source_eop;
wire  [9:0] fft_imag_out;
wire  [9:0] fft_real_out;
wire  [5:0] exponent_out;

//-------------------------------------------
wire [11:0] real_sw_out, image_sw_out;
wire [11:0] xr,xi,yr,yi;
reg [11:0] wdata2_real_up, wdata2_image_up;
reg [11:0] wdata2_real_dn, wdata2_image_dn;

wire [11:0] real_output, image_output;

wire ram_up_wen, ram_dn_wen;
wire [9:0] ram_up_waddr, ram_dn_waddr;
wire [23:0] ram_up_wdata, ram_dn_wdata;

wire ram_up_ren, ram_dn_ren;
wire [9:0] ram_up_raddr, ram_dn_raddr;
wire [23:0] ram_up_rdata, ram_dn_rdata;

wire rom_ren;
wire [9:0] rom_raddr;
wire [9:0] rom_cos, rom_sin;

wire frame_out_enb,frame_out_sop,frame_out_eop;

wire ram_up_wsel, ram_up_rsel;
wire frame_input_on ;
wire ram_rdata_valid;
wire wr_stage_cmplt ;
wire bfly_finish    ;

wire shift_out_valid;
wire bfly_out_valid ;

wire [1:0] shift_ctrl;

fft_ctrl fft_ctrl_inst (
  .rst              ( rst              ),
  .clk              ( clk              ),
  .frame_in_dav     ( master_sink_dav  ),
  .frame_in_enb     ( master_sink_ena  ),
  .frame_in_sop     ( master_sink_sop  ),
  .frame_out_dav    ( master_source_dav),
  .frame_out_enb    ( frame_out_enb    ),
  .frame_out_sop    ( frame_out_sop    ),
  .frame_out_eop    ( frame_out_eop    ),
  .ram_up_wen       ( ram_up_wen       ),
  .ram_up_ren       ( ram_up_ren       ),
  .ram_up_waddr     ( ram_up_waddr     ),
  .ram_up_raddr     ( ram_up_raddr     ),
  .ram_dn_wen       ( ram_dn_wen       ),
  .ram_dn_ren       ( ram_dn_ren       ),
  .ram_dn_waddr     ( ram_dn_waddr     ),
  .ram_dn_raddr     ( ram_dn_raddr     ),
  .rom_ren          ( rom_ren          ),
  .rom_raddr        ( rom_raddr        ),
  .ram_up_wsel      ( ram_up_wsel      ), 
  .ram_up_rsel      ( ram_up_rsel      ), 
  .frame_input_on   ( frame_input_on   ), 
  .ram_rdata_valid  ( ram_rdata_valid  ),
  .wr_stage_cmplt   ( wr_stage_cmplt   ),
  .bfly_finish      ( bfly_finish      )
);


input_sw input_sw_inst (
  .inv_i         ( inv_i          ),
  .fft_real_in   ( data_real_in    ),
  .fft_image_in  ( data_imag_in   ),
  .fft_real_out  ( real_sw_out    ),
  .fft_image_out ( image_sw_out   )
);

ram1024x24_dp  ram1024x24_dp_up_inst (
    .clock     ( clk          ),
    .wren      ( ram_up_wen   ),
    .wraddress ( ram_up_waddr ),
    .data      ( ram_up_wdata ),
    .rden      ( ram_up_ren   ),
    .rdaddress ( ram_up_raddr ),
    .q         ( ram_up_rdata )
);

ram1024x24_dp  ram1024x24_dp_dn_inst (
    .clock     ( clk          ),
    .wren      ( ram_dn_wen   ),
    .wraddress ( ram_dn_waddr ),
    .data      ( ram_dn_wdata ),
    .rden      ( ram_dn_ren   ),
    .rdaddress ( ram_dn_raddr ),
    .q         ( ram_dn_rdata )
);

wire [8:0] rom_raddr_2;
wire [9:0] rom_cos_2,rom_sin_2;
reg [1:0] d2t_reg;

always @(posedge rst or posedge clk) begin
    if(rst)
        d2t_reg <= 2'b00;
    else
        d2t_reg <= {d2t_reg[0],rom_raddr[9]};
end

assign rom_raddr_2 = rom_raddr[9] ? ~rom_raddr[8:0] : rom_raddr[8:0];

assign rom_cos = d2t_reg[1] ? (~rom_cos_2 + 10'h1) : rom_cos_2;
assign rom_sin = rom_sin_2 ;

rom512x10_cos_sp    rom512x10_cos_sp_inst (
    .clock   ( clk       ),
    .clken   ( rom_ren   ),
    .address ( rom_raddr_2 ),
    .q       ( rom_cos_2   )
);

rom512x10_sin_sp    rom512x10_sin_sp_inst (
    .clock   ( clk       ),
    .clken   ( rom_ren   ),
    .address ( rom_raddr_2 ),
    .q       ( rom_sin_2   )
);

wire [9:0] up_out_real, up_out_image;
wire [9:0] dn_out_real, dn_out_image;

shift_process shift_process_inst (
  .rst              ( rst                 )  ,
  .clk              ( clk                 )  ,
  .shift_in_valid   ( ram_rdata_valid     )  ,
  .shift_out_valid  ( shift_out_valid     )  ,
  .shift_ctrl       ( shift_ctrl          )  ,
  .up_in_real       ( ram_up_rdata[23:12] )  ,
  .up_in_image      ( ram_up_rdata[11:0]   )  ,
  .dn_in_real       ( ram_dn_rdata[23:12] )  ,
  .dn_in_image      ( ram_dn_rdata[11:0]   )  ,
  .up_out_real      ( up_out_real         )  ,
  .up_out_image     ( up_out_image        )  ,
  .dn_out_real      ( dn_out_real         )  ,
  .dn_out_image     ( dn_out_image        )   
);

bfly_r2dit bfly_r2dit_inst (
  .rst       ( rst             ),
  .clk       ( clk             ),
  .din_av    ( shift_out_valid ),
  .out_enb   ( bfly_out_valid  ),
  .ar        ( up_out_real     ),
  .ai        ( up_out_image    ),
  .br        ( dn_out_real     ),
  .bi        ( dn_out_image    ),
  .wc        ( rom_cos         ),
  .ws        ( rom_sin         ),
  .xr        ( xr              ),
  .xi        ( xi              ),
  .yr        ( yr              ),
  .yi        ( yi              ) 
);

always @(posedge rst or posedge clk) begin
  if(rst) begin
    wdata2_real_up  <= 12'h0;
    wdata2_image_up <= 12'h0;
  end
  else if(bfly_out_valid && ram_up_wsel) begin
    wdata2_real_up  <= yr;
    wdata2_image_up <= yi;
  end
end

always @(posedge rst or posedge clk) begin
  if(rst) begin
    wdata2_real_dn  <= 12'h0;
    wdata2_image_dn <= 12'h0;
  end
  else if(bfly_out_valid && !ram_up_wsel) begin
    wdata2_real_dn  <= yr;
    wdata2_image_dn <= yi;
  end
end

assign ram_up_wdata = (frame_input_on) ? {real_sw_out,image_sw_out} : 
                                     (ram_up_wsel) ? {xr,xi} : {wdata2_real_up,wdata2_image_up};
assign ram_dn_wdata = (frame_input_on) ? {real_sw_out,image_sw_out} : 
                                     (ram_up_wsel) ? {wdata2_real_dn,wdata2_image_dn} : {xr,xi};

overflow_detect overflow_detect_inst (
  .rst               ( rst            )  ,
  .clk               ( clk            )  ,
  .bfly_out_valid    ( bfly_out_valid )  ,
  .wr_stage_cmplt    ( wr_stage_cmplt )  ,
  .xr_h3             ( xr[11:9]        )  ,
  .xi_h3             ( xi[11:9]        )  ,
  .yr_h3             ( yr[11:9]        )  ,
  .yi_h3             ( yi[11:9]        )  ,
  .shift_ctrl_clr    ( frame_out_eop  )  ,
  .shift_ctrl        ( shift_ctrl     )  
);

// output
assign real_output =  (frame_out_enb && ram_up_rsel) ? ram_up_rdata[23:12] :
                                                   ram_dn_rdata[23:12];
assign image_output = (frame_out_enb && ram_up_rsel) ? ram_up_rdata[11:0] :
                                                   ram_dn_rdata[11:0];

output_sw output_sw_inst (
  .rst               ( rst               ),
  .clk               ( clk               ),
  .inv_i             ( inv_i             ),
  .exp_clr           ( master_sink_sop   ),
  .wr_stage_cmplt    ( wr_stage_cmplt    ),
  .frame_out_enb     ( frame_out_enb     ),
  .frame_out_sop     ( frame_out_sop     ),
  .frame_out_eop     ( frame_out_eop     ),
  .shift_ctrl        ( shift_ctrl        ),
  .fft_real_in       ( real_output       ),
  .fft_image_in      ( image_output      ),
  .fft_real_out      ( fft_real_out      ),
  .fft_image_out     ( fft_imag_out      ),
  .exponent_out      ( exponent_out      ),
  .master_source_enb ( master_source_ena ),
  .master_source_sop ( master_source_sop ),
  .master_source_eop ( master_source_eop )
);

endmodule

`
// FFT controll

// point=512
//`define THE_LAST_STAGE 4'b1000   // 9-1=8
//`define THE_LAST_BFLY  8'hFF     // 512/2-1=255
//point = 2048
//`define THE_LAST_STAGE 4'b1010;   // point=2048
//`define THE_LAST_BFLY  10'h3FF;   // 2048/2-1=1023



module fft_ctrl (
  rst,
  clk,
  frame_in_dav,
  frame_in_enb,
  frame_in_sop,
  frame_out_dav,
  frame_out_enb,
  frame_out_sop,
  frame_out_eop,

  ram_up_wen,
  ram_up_ren,
  ram_up_waddr,
  ram_up_raddr,

  ram_dn_wen,
  ram_dn_ren,
  ram_dn_waddr,
  ram_dn_raddr,

  rom_ren,
  rom_raddr,

  ram_up_wsel,
  ram_up_rsel,
  frame_input_on,   // to input multiplexer
  ram_rdata_valid,
  wr_stage_cmplt,
  bfly_finish
);

input rst, clk;
input frame_in_dav, frame_out_dav;
output frame_in_enb,frame_out_enb;
input frame_in_sop;
output frame_out_sop, frame_out_eop;
output ram_up_wen, ram_up_ren;
output [9:0] ram_up_waddr, ram_up_raddr;
output ram_dn_wen, ram_dn_ren;
output [9:0] ram_dn_waddr, ram_dn_raddr;
output rom_ren;
output [9:0] rom_raddr;
output ram_up_wsel;
output ram_up_rsel;
output frame_input_on;
output ram_rdata_valid;
output wr_stage_cmplt, bfly_finish;

reg frame_in_enb, frame_out_enb;
reg frame_out_sop, frame_out_eop;
wire ram_up_wsel;
reg ram_up_rsel;
wire frame_input_on;
reg ram_rdata_valid;
wire wr_stage_cmplt;
wire bfly_finish;

//=================================================
// Input control
//=================================================
reg ram_full;
reg [10:0] frame_in_cnt;  //2^11= 2048
reg frame_in_cnt_enb;
wire frame_in_eop;

always @(posedge rst or posedge clk) begin
  if(rst)
      ram_full <= 1'b0;
  else if(frame_in_eop)
      ram_full <= 1'b1;
  else if(frame_out_eop)
      ram_full <= 1'b0;
end

always @(posedge rst or posedge clk) begin
  if(rst)
      frame_in_enb <= 1'b0;
  else if(frame_in_eop)
      frame_in_enb <= 1'b0;
  else if(frame_in_dav && !ram_full)
      frame_in_enb <= 1'b1;
end

always @(posedge rst or posedge clk) begin
  if(rst)
      frame_in_cnt_enb <= 1'b0;
  else if(frame_in_eop)
      frame_in_cnt_enb <= 1'b0;
  else if(frame_in_enb && frame_in_sop)
      frame_in_cnt_enb <= 1'b1;
end

// input switch control
assign frame_input_on = frame_in_sop | frame_in_cnt_enb;

// fram_in_cnt
always @(posedge rst or posedge clk) begin
  if(rst)
      frame_in_cnt <= 11'h0;  // point=2048
  else if(frame_in_enb && frame_input_on)
      frame_in_cnt <= frame_in_cnt + 1'b1;
end

assign frame_in_eop = (frame_in_cnt==11'h7FF);  // 2^11=2048

// input writing address
wire [10:0] ram_input_addr;

assign ram_input_addr = { frame_in_cnt[0],
                      frame_in_cnt[1],
                      frame_in_cnt[2],
                      frame_in_cnt[3],
                      frame_in_cnt[4],
                      frame_in_cnt[5],
                      frame_in_cnt[6],
                      frame_in_cnt[7],
                      frame_in_cnt[8],
                      frame_in_cnt[9],
                      frame_in_cnt[10]
             };

//=================================================
// RAM read control in butterfly
//=================================================
reg [13:0] rd_cnt;
reg rd_cnt_enb;
wire [3:0] rd_stage;
wire [9:0] rd_index;
wire rd_index_eop;
wire rd_stage_eop;
reg [2:0] stage_end_delay;
reg rd_cnt_wait;

always @(posedge rst or posedge clk) begin
  if(rst)
    rd_cnt <= 14'h0;
  else if(frame_in_eop)
    rd_cnt <= 14'h0;
  else if(rd_cnt_enb && !rd_cnt_wait )
    rd_cnt <= rd_cnt + 1'b1;
end

assign rd_stage = rd_cnt[13:10];
assign rd_index = rd_cnt[9:0];

assign rd_index_eop = (rd_index==10'b11_1111_1111) && rd_cnt_enb;    // the last butterfly in the stage  
assign rd_stage_eop = (rd_stage==4'b1010) && rd_index_eop;    // the last stage 11-1=10

always @(posedge rst or posedge clk) begin
  if(rst)
      stage_end_delay <= 3'b111;
  else if(rd_index_eop)            
      stage_end_delay <= 3'b000;
  else if(stage_end_delay!=3'b111)
      stage_end_delay <= stage_end_delay + 1'b1;
end 

always @(posedge rst or posedge clk) begin
  if(rst)
      rd_cnt_wait <= 1'b0;
  else if(rd_index_eop)            
      rd_cnt_wait <= 1'b1;
  else if(stage_end_delay==3'b101)  // end of writing delay 6clk(0~5)
      rd_cnt_wait <= 1'b0;
end 

always @(posedge rst or posedge clk) begin
  if(rst)
    rd_cnt_enb <= 1'b0;
  else if(frame_in_eop)
    rd_cnt_enb <= 1'b1;
  else if(rd_stage_eop )
    rd_cnt_enb <= 1'b0;
end

//-------------------------------------------------
// map the RAM read address
reg [9:0] raddr_up;  //1024
wire [9:0] raddr_dn;
wire ren_up;
wire ren_dn;

assign ren_up = rd_cnt_enb & ~rd_cnt_wait;

// circle left shift
always @(rd_stage or rd_index) begin
    case(rd_stage)
            4'b0000,
        4'b1010: raddr_up <= rd_index[9:0];
            4'b0001: raddr_up <= {rd_index[8:0],rd_index[9]};
            4'b0010: raddr_up <= {rd_index[7:0],rd_index[9:8]};
            4'b0011: raddr_up <= {rd_index[6:0],rd_index[9:7]};
            4'b0100: raddr_up <= {rd_index[5:0],rd_index[9:6]};
            4'b0101: raddr_up <= {rd_index[4:0],rd_index[9:5]};
            4'b0110: raddr_up <= {rd_index[3:0],rd_index[9:4]};
            4'b0111: raddr_up <= {rd_index[2:0],rd_index[9:3]};
            4'b1000: raddr_up <= {rd_index[1:0],rd_index[9:2]};
            4'b1001: raddr_up <= {rd_index[0],rd_index[9:1]};
            default: raddr_up <= 10'b00_0000_0000;
    endcase
end

assign ren_dn = ren_up;
assign raddr_dn = raddr_up;

//=================================================
// RAM write control in butterfly
//=================================================
reg [13:0] wr_cnt;
reg wr_cnt_enb;
wire [3:0] wr_stage;
wire [9:0] wr_index;
wire wr_index_sop;
wire wr_index_eop;
wire wr_stage_eop;
reg [2:0] stage_start_delay;
reg wr_cnt_wait;

wire wen_up;
reg wen_dn;

always @(posedge rst or posedge clk) begin
  if(rst)
    wr_cnt <= 14'h0;
  else if(frame_in_eop)   // cleared by input finish
    wr_cnt <= 14'h0;
  else if(wr_cnt_enb && !wr_cnt_wait )
    wr_cnt <= wr_cnt + 1'b1;
end

assign wr_stage = wr_cnt[13:10];
assign wr_index = wr_cnt[9:0];

assign wr_index_sop = ((stage_end_delay==3'b101) && wr_cnt_enb) || frame_in_eop;   // the last butterfly in the stage 

assign wr_index_eop = (wr_index==10'b11_1111_1111) && wr_cnt_enb;
assign wr_stage_eop = (wr_stage==4'b1010) && wr_index_eop; // 11-1=10  

always @(posedge rst or posedge clk) begin
  if(rst)
      stage_start_delay <= 3'b111;
  //else if(wr_index_sop || frame_in_eop)  // the start of each write stage or the end of frame_in   
  else if(wr_index_sop)  // the start of each write stage or the end of frame_in   
      stage_start_delay <= 3'b000;
  else if(stage_start_delay!=3'b111)
      stage_start_delay <= stage_start_delay + 1'b1;
end 

always @(posedge rst or posedge clk) begin
  if(rst)
      wr_cnt_wait <= 1'b0;
  else if(wr_index_eop || frame_in_eop)            
      wr_cnt_wait <= 1'b1;
  else if(stage_start_delay==3'b100)  // end of writing delay 5clk(0~4)
      wr_cnt_wait <= 1'b0;
end 

always @(posedge rst or posedge clk) begin
  if(rst)
    wr_cnt_enb <= 1'b0;
else if(frame_in_eop)
    wr_cnt_enb <= 1'b1;
  else if(wr_stage_eop )  // the last writing stage
    wr_cnt_enb <= 1'b0;
end

assign wen_up = wr_cnt_enb & ~wr_cnt_wait;

always @(posedge rst or posedge clk) begin
  if(rst)
      wen_dn <= 1'b0;
  else 
      wen_dn <= wen_up;  // 1clk dealy
end 

//assign ram_up_wsel = ~wr_cnt[0] & wen_up;
//assign ram_up_wsel = ~wr_cnt[0] & wen_up & ~wr_index_eop;  // avoid glach at the end of every stage
assign ram_up_wsel = ~wr_cnt[0] & (wen_up | wen_dn); 

//-------------------------------------------------
// map the RAM write address
reg [9:0] waddr1, waddr2;

always @(wr_stage or wr_index) begin
    case(wr_stage)
            4'b0000,4'b1010: begin
            waddr1 <= {wr_index[9:1],1'b0};
            waddr2 <= {wr_index[9:1],1'b1};
        end
            4'b0001: begin
            waddr1 <= {wr_index[8:1],1'b0,wr_index[9]};
            waddr2 <= {wr_index[8:1],1'b1,wr_index[9]};
        end
            4'b0010: begin
            waddr1 <= {wr_index[7:1],1'b0,wr_index[9:8]};
            waddr2 <= {wr_index[7:1],1'b1,wr_index[9:8]};
        end
            4'b0011: begin
            waddr1 <= {wr_index[6:1],1'b0,wr_index[9:7]};
            waddr2 <= {wr_index[6:1],1'b1,wr_index[9:7]};
        end
            4'b0100: begin
            waddr1 <= {wr_index[5:1],1'b0,wr_index[9:6]};
            waddr2 <= {wr_index[5:1],1'b1,wr_index[9:6]};
        end
            4'b0101: begin
            waddr1 <= {wr_index[4:1],1'b0,wr_index[9:5]};
            waddr2 <= {wr_index[4:1],1'b1,wr_index[9:5]};
        end
            4'b0110: begin
            waddr1 <= {wr_index[3:1],1'b0,wr_index[9:4]};
            waddr2 <= {wr_index[3:1],1'b1,wr_index[9:4]};
        end
            4'b0111: begin
            waddr1 <= {wr_index[2:1],1'b0,wr_index[9:3]};
            waddr2 <= {wr_index[2:1],1'b1,wr_index[9:3]};
        end
            4'b1000: begin
            waddr1 <= {wr_index[1],1'b0,wr_index[9:2]};
            waddr2 <= {wr_index[1],1'b1,wr_index[9:2]};
        end
            4'b1001: begin
            waddr1 <= {1'b0,wr_index[9:1]};
            waddr2 <= {1'b1,wr_index[9:1]};
        end
            default: begin
            waddr1 <= 10'b00_0000_0000;
            waddr2 <= 10'b00_0000_0000;
        end
    endcase
end

// waddr2 buffer
reg [9:0] waddr2_d1t_up, waddr2_d1t_dn;

always @(posedge rst or posedge clk) begin
  if(rst)
    waddr2_d1t_up = 10'h0;
  else if(!wr_cnt[0] && wr_cnt_enb)
    waddr2_d1t_up = waddr2;  // write after 1 clk delay
end

always @(posedge rst or posedge clk) begin
  if(rst)
    waddr2_d1t_dn = 10'h0;
  else if(wr_cnt[0] && wr_cnt_enb)
    waddr2_d1t_dn = waddr2;  // write after 1 clk delay
end

//=================================================
// output control
//=================================================
reg bfly_finish_flg;
reg [10:0] frame_out_cnt; //2^11=2048
reg frame_out_cnt_enb;
wire frame_out_cnt_sop;
wire frame_out_cnt_eop;

//assign bfly_finish = (wr_stage==4'b1000) && (waddr2_d1t_dn==8'b1111_1111);
assign bfly_finish = (wr_stage==4'b1010) && (waddr2==10'b11_1111_1111);

always @(posedge rst or posedge clk) begin
  if(rst)
      bfly_finish_flg <= 1'b0;
  else if(bfly_finish)
      bfly_finish_flg <= 1'b1;
  else if(frame_out_dav)
      bfly_finish_flg <= 1'b0;
end

always @(posedge rst or posedge clk) begin
  if(rst)
      frame_out_cnt_enb <= 1'b0;
  else if(frame_out_dav && bfly_finish_flg)
      frame_out_cnt_enb <= 1'b1;
  else if(frame_out_cnt_eop)
      frame_out_cnt_enb <= 1'b0;
end

assign frame_out_cnt_sop = (frame_out_cnt==11'h000) && frame_out_cnt_enb;
assign frame_out_cnt_eop = (frame_out_cnt==11'h7FF) && frame_out_cnt_enb;

always @(posedge rst or posedge clk) begin
  if(rst)
      frame_out_cnt <= 11'h0;
  else if(frame_out_cnt_eop)
      frame_out_cnt <= 11'h0;
  else if(frame_out_cnt_enb)
      frame_out_cnt <= frame_out_cnt + 1'b1;
end

// delay 2clk output
reg frame_out_cnt_enb_d1t;
reg frame_out_cnt_sop_d1t;
reg frame_out_cnt_eop_d1t;

always @(posedge rst or posedge clk) begin
  if(rst) begin
      frame_out_cnt_enb_d1t <= 1'b0;
      frame_out_cnt_sop_d1t <= 1'b0;
      frame_out_cnt_eop_d1t <= 1'b0;
      frame_out_enb <= 1'b0;
      frame_out_sop <= 1'b0;
      frame_out_eop <= 1'b0;
  end
  else begin
      frame_out_cnt_enb_d1t <= frame_out_cnt_enb;
      frame_out_cnt_sop_d1t <= frame_out_cnt_sop;
      frame_out_cnt_eop_d1t <= frame_out_cnt_eop;
      frame_out_enb <= frame_out_cnt_enb_d1t;
      frame_out_sop <= frame_out_cnt_sop_d1t;
      frame_out_eop <= frame_out_cnt_eop_d1t;
  end
end


//=================================================
// RAM control output 
//=================================================
assign ram_up_ren = ren_up | (frame_out_cnt_enb & ~frame_out_cnt[0]);
assign ram_dn_ren = ren_dn | (frame_out_cnt_enb &  frame_out_cnt[0]);
assign ram_up_raddr = (frame_out_cnt_enb) ? {frame_out_cnt[9:1],frame_out_cnt[10]} : 
                                        raddr_up;
assign ram_dn_raddr = (frame_out_cnt_enb) ? {frame_out_cnt[9:1],frame_out_cnt[10]} : 
                                        raddr_dn;

assign ram_up_wen = (~ram_input_addr[0] & frame_input_on) | wen_up ; 
assign ram_dn_wen = ( ram_input_addr[0] & frame_input_on) | wen_dn ; 
assign ram_up_waddr = (frame_input_on) ? ram_input_addr[10:1] : 
                                    (wr_cnt[0]) ? waddr2_d1t_up : waddr1;
assign ram_dn_waddr = (frame_input_on) ? ram_input_addr[10:1] : 
                                    (wr_cnt[0]) ? waddr1 : waddr2_d1t_dn;


//=================================================
// map the ROM read address
//=================================================
reg rom_ren;
reg [10:0] right_shift;
reg [9:0] rom_raddr;
wire [9:0] rom_offset;
reg [9:0] tw_cnt;
wire [9:0] field_num;

always @(posedge rst or posedge clk) begin
  if(rst)
        rom_ren <= 1'b0;
  else if(stage_start_delay==3'b000)  // 1clk delay with ram_ren
        rom_ren <= 1'b1;
  else if(stage_end_delay==3'b000)
        rom_ren <= 1'b0;
end

always @(posedge rst or posedge clk) begin
  if(rst)
    right_shift <= 11'b000_0000_0000;
  else if(frame_in_eop)
    right_shift <= 11'b100_0000_0000;
  //else if(rd_index_eop)
  else if(stage_end_delay==3'b001)
    right_shift <= {1'b0,right_shift[10:1]};
end

assign rom_offset = right_shift[9:0];

assign field_num = rom_offset - 1'b1;

always @(posedge rst or posedge clk) begin
  if(rst) begin
      tw_cnt <= 9'h0;
  end
  else begin 
      if( (tw_cnt == field_num) && rom_ren )
          tw_cnt <= 9'h0;
      else if (rom_ren)
          tw_cnt <= tw_cnt + 1'b1;
  end
end

always @(posedge rst or posedge clk) begin
  if(rst)
    rom_raddr <= 10'b00_0000_0000;
  else if(frame_in_eop)
    rom_raddr <= 10'b00_0000_0000;
  else if(rom_ren && (tw_cnt == field_num) )
    rom_raddr <= rom_raddr + rom_offset;
end

//=================================================
// internal control out
//=================================================
reg frame_out_ram_up;

always @(posedge rst or posedge clk) begin
  if(rst)
      ram_rdata_valid <= 1'b0;
  else if(stage_start_delay==3'b001) // 2clk delay after ram_ren
      ram_rdata_valid <= 1'b1;
  else if(stage_end_delay==3'b001)
      ram_rdata_valid <= 1'b0;
end 

assign wr_stage_cmplt = wr_index_eop;

always @(posedge rst or posedge clk) begin
  if(rst) begin
        frame_out_ram_up <= 1'b0;
    ram_up_rsel      <= 1'b0;
  end
  else begin
        frame_out_ram_up <= frame_out_cnt_enb & ~frame_out_cnt[0];
    ram_up_rsel      <= frame_out_ram_up;
  end
end

endmodule

工程下载如下
FFT_2048.7z

编辑 重设标签(回车键确认) 标为违禁 关闭 合并 删除
匿名用户

匿名