OpenCores
URL https://opencores.org/ocsvn/fft2_size/fft2_size/trunk

Subversion Repositories fft2_size

[/] [fft2_size/] [fft_int_size/] [cascade_0.sv] - Rev 7

Compare with Previous | Blame | View Log

/*
Pre-processing cascade
It make bit-reversal permutation
First FFT cascade reads data from it
*/


`ifndef _cascade_0_
`define _cascade_0_
`include "bitrev_cnt.sv"

module cascade_0 #(parameter
        ADDR_WIDTH = 9,
        DATA_WIDTH = 32,
        POW_WIDTH = (2**$clog2(ADDR_WIDTH) > ADDR_WIDTH - 1) ? $clog2(ADDR_WIDTH) : $clog2(ADDR_WIDTH) + 1
)(
        input clk, aclr,
        
        // input data stream
        input sink_sop, sink_eop, sink_valid, // valid must be solid
        input signed [DATA_WIDTH-1:0] sink_Re, sink_Im,
        
        // current pow and last addr
        input [POW_WIDTH-1:0] pow,
        input [ADDR_WIDTH-1:0] addr_max,
        
        // access to output buffer
        input [ADDR_WIDTH-1:0] rdaddr, // read address
        output reg signed [DATA_WIDTH-1:0] q_Re, q_Im, // read data     
        output reg ready, // buffer ready
        input rdack, // read data acknowledge
        
        output reg error // input stream error
);
        reg wr_buf = 1'b0, rd_buf = 1'b0;
        reg signed [DATA_WIDTH-1:0] mem_Re[2][2**ADDR_WIDTH];
        reg signed [DATA_WIDTH-1:0] mem_Im[2][2**ADDR_WIDTH];
        
        wire [ADDR_WIDTH-1:0] wraddr, wraddr_rev;
        reg valid_reg = 1'b0, eop_reg = 1'b0;
        reg signed [DATA_WIDTH-1:0] Re_reg, Im_reg;
        
        bitrev_cnt #(.WIDTH(ADDR_WIDTH)) cnt_inst(
                .clk, .aclr,
                .clk_ena(sink_valid), .sclr(sink_sop),
                .width(pow), .cnt_max(addr_max),
                .cnt(wraddr), .cnt_rev(wraddr_rev)
        );
        
        always_ff @(posedge clk, posedge aclr)
                valid_reg <= (aclr) ? 1'b0 : sink_valid;
        
        always_ff @(posedge clk) begin
                Re_reg <= sink_Re;
                Im_reg <= sink_Im;
                eop_reg <= sink_eop;
                
                if (valid_reg) begin
                        mem_Re[wr_buf][wraddr_rev] <= Re_reg;
                        mem_Im[wr_buf][wraddr_rev] <= Im_reg;
                end
        end
        
        always_ff @(posedge clk) begin
                q_Re <= mem_Re[rd_buf][rdaddr];
                q_Im <= mem_Im[rd_buf][rdaddr];
        end
        
        always_ff @(posedge clk, posedge aclr)
                if (aclr)
                        ready <= 1'b0;
                else if (valid_reg && eop_reg && wraddr == addr_max)
                        ready <= 1'b1;
                else if (rdack)
                        ready <= 1'b0;
                        
        always_ff @(posedge clk, posedge aclr)
                if (aclr)
                        wr_buf <= 1'b0;
                else if (valid_reg && eop_reg && wraddr == addr_max)
                        wr_buf <= !wr_buf;
                        
        always_ff @(posedge clk, posedge aclr)
                if (aclr)
                        rd_buf <= 1'b0;
                else if (rdack)
                        rd_buf <= !rd_buf;
        
        always_ff @(posedge clk, posedge aclr)
                error <= (aclr) ? 1'b0 : (sink_sop || sink_eop) && !sink_valid || sink_eop && wraddr != addr_max - 1'b1;
endmodule :cascade_0

`endif

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.