/
                                                           
 FFT/IFFT 256 points transform                              
                                                           
 Authors: Anatoliy Sergienko, Volodya Lepeha                
 Company: Unicore Systems http://unicore.co.ua              
                                                           
 Downloaded from: http://www.opencores.org                  
                                                           
/
                                                           
Copyright (C) 2006-2010 Unicore Systems LTD                
www.unicore.co.ua                                          
o.uzenkov@unicore.co.ua                                    
                                                           
This source file may be used and distributed without        
restriction provided that this copyright statement is not  
removed from the file and that any derivative work contains
the original copyright notice and the associated disclaimer.
                                                           
THIS SOFTWARE IS PROVIDED "AS IS"                          
AND ANY EXPRESSED OR IMPLIED WARRANTIES,                    
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED                  
WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT              
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.        
IN NO EVENT SHALL THE UNICORE SYSTEMS OR ITS                
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,            
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL            
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT        
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,              
DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,              
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT              
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING                
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,                
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.          
                                                           
/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~        
// DESCRIPTION    :     Stage of FFT 256 processor
// FUNCTION:           16-point FFT
// FILES:                     FFT16.v -  stage, contains
//                    MPUC707.v - multiplier to the factor 0.707.
//  PROPERTIES: 1) Fully pipelined
//                            2) Each clock cycle complex datum is entered
//                           and complex result is outputted
//                             3) Has 16-clock cycle period starting with the START impulse
//                          and continuing forever
//                            4) rounding    is not used
//                            5)Algorithm is from the book "H.J.Nussbaumer FFT and convolution algorithms".
//                            6)IFFT is performed by substituting the output result order to the reversed one
//                                (by exchanging - to + and + to -)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Algorithm:
///procedure FFT16(
//        X: in MEMOC;  -- 怩钿眍爨耨桠 溧眄
//        y:out MEMOC)  -- 恹躅漤铋 爨耨桠 耧尻蝠钼
//        is   
//        variable t1,t2,t3,t4,t5,t6,t7,t8,t9,t10: complex;
//        variable t11,t12,t13,t14,t15,t16,t17,t18,t19,t20: complex;
//        variable t21,t22,t23,t24,t25,t26: complex;
//        variable m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10: complex;
//        variable m11,m12,m13,m14,m15,m16,m17: complex;
//        variable s1,s2,s3,s4,s5,s6,s7,s8,s9,s10: complex;
//        variable s11,s12,s13,s14,s15,s16,s17,s18,s19,s20: complex;
//    begin                             
//        t1:=x(0) + x(8);             m4:=x(0) - x(8);
//        t2:=x(4) + x(12);          m12:=-CBASE_j*(x(4)-x(12));
//        t3:=x(2) + x(10);            t4:=x(2) - x(10);
//        t5:=x(6) + x(14);            t6:=x(6) - x(14);
//        t7:=x(1) + x(9);            t8:=x(1) - x(9);
//        t9:=x(3) + x(11);            t10:=x(3) - x(11);
//        t11:=x(5) + x(13);        t12:=x(5) - x(13);
//        t13:=x(7) + x(15);        t14:=x(7) - x(15);
//        t15:=t1 + t2;                m3:= t1 - t2;
//        t16:=t3 + t5;                m11:= -CBASE_j*(t3 - t5);
//        t17:=t15 + t16;            m2:= t15 - t16;
//        t18:=t7 + t11;                t19:= t7 - t11;
//        t20:=t9 + t13;                t21:= t9 - t13;
//        t22:=t18 + t20;            m10:= -CBASE_j*(t18 - t20);
//        t23:=t8 + t14;                t24:= t8 - t14;
//        t25:=t12 + t10;            t26:= t12 - t10;
//        
//        m0:=t17 + t22;                m1:=t17 - t22;
//        m13:=-CBASE_j*c707*(t19 + t21);            m5:=c707*(t19 - t21);              
//        m6:=c707*(t4 - t6);          m14:=-CBASE_j*c707*(t4 + t6);        
//    
//        m7:=c3*(t24+t26);
//        m8:=c13*(t24);
//        m9:=-s1_3*(t26);  
//        s7:= m8 - m7;                     
//        s8:= m9 - m7;   
//        
//        m15:=-CBASE_j*c1*(t23 + t25);       
//        m16:= -CBASE_j*s1_3*(t23);       
//        m17:=-CBASE_j*c13*(t25);
//        s15:= m15 - m16;                             
//        s16:= m15 - m17;
//        
//        s1:=m3 + m5;            s2:=m3 - m5;
//        s3:=m13 + m11;        s4:=m13 - m11;                  
//        s5:=m4 + m6;            s6:=m4 - m6;
//        s9:=s5 + s7;                s10:=s5 - s7;
//        s11:=s6 + s8;            s12:=s6 - s8;
//        s13:=m12 + m14;        s14:=m12 - m14;                  
//        s17:=s13 + s15;        s18:=s13 - s15;      
//        s19:=s14 + s16;        s20:=s14 - s16;
//        
//        y(0):=m0;             y(8):=m1;
//        y(1):=s9 + s17;    y(15):=s9 - s17;
//        y(2):=s1 + s3;        y(14):=s1 - s3;
//        y(3):=s12 - s20;    y(13):=s12 + s20;
//        y(4):=m2 + m10;    y(12):=m2 - m10;
//        y(5):=s11 + s19;    y(11):=s11 - s19;
//        y(6):=s2 + s4;        y(10):=s2 - s4;
//        y(7):=s10 - s18;    y(9):=s10 + s18;
//    end procedure;    
//

`timescale 1ns / 1ps  
`include "FFT256_CONFIG.inc"     

module FFT16 ( DOR ,DII ,RST ,ED ,CLK ,DOI ,START ,DIR ,RDY );
    `FFT256paramnb    
    
    input ED ;          //slowdown impulse
    wire ED ;
    input RST ;
    wire RST ;
    input CLK ;
    wire CLK ;
    input [nb-1:0] DII ;
    wire [nb-1:0] DII ;
    input START ;
    wire START ;
    input [nb-1:0] DIR ;
    wire [nb-1:0] DIR ;
    
    output [nb+3:0] DOI ;
    wire [nb+3:0] DOI ;
    output [nb+3:0] DOR ;
    wire [nb+3:0] DOR ;
    output RDY ;
    reg RDY ;           
    
    reg [3:0] ct; //main phase counter
    reg [5:0] ctd; //delay counter
    
    always @(   posedge CLK) begin    //Control counter
            //
            if (RST)    begin
                    ct<=0; 
                    ctd<=63; 
                RDY<=0;  end
            else if (START)      begin
                    ct<=0; 
                    ctd<=0;    
                RDY<=0;   end
            else if (ED) begin    
                    RDY<=0; 
                    ct<=ct+1;    
                    if (ctd !=6'b111111)
                        ctd<=ctd+1;        
                    if (ctd==44-16 ) 
                        RDY<=1;
                end 
            
        end       
    
    reg signed    [nb-1: 0] dr,d1r,d2r,d3r,d4r,d5r,d6r,d7r,d8r,di,d1i,d2i,d3i,d4i,d5i,d6i,d7i,d8i;
    always @(posedge CLK)      // input register file
        begin
            if (ED)     begin
                    dr<=DIR;  
                    d1r<=dr;      d2r<=d1r;    d3r<=d2r;d4r<=d3r;
                    d5r<=d4r;d6r<=d5r;    d7r<=d6r;    d8r<=d7r;                
                    di<=DII;  
                    d1i<=di;     d2i<=d1i;    d3i<=d2i;    d4i<=d3i;
                    d5i<=d4i;    d6i<=d5i;d7i<=d6i;    d8i<=d7i;            
                end
        end     
    
    reg signed    [nb:0]    s1r,s1d1r,s1d2r,s1d3r,s1d4r,s1d5r,s1d6r,s1d7r,s1d8r;     //even result sums
    reg signed    [nb:0]    s1i,s1d1i,s1d2i,s1d3i,s1d4i,s1d5i,s1d6i,s1d7i,s1d8i;     //even result sums
    reg signed    [nb:0]    s2r,s2d1r,s2d2r,s2d3r,s2d4r,s2d5r,s2d6r,s2d7r,s2d8r,m4_12r;        //odd result sums
    reg signed    [nb:0]    s2i,s2d1i,s2d2i,s2d3i,s2d4i,s2d5i,s2d6i,s2d7i,s2d8i,m4_12i;        //odd result sums
    always @(posedge CLK)    begin           // S1,S2 =t1-t14,m4,m12' and delayed
            if (ED && ((ct==9) || (ct==10) || (ct==11) ||(ct==12) ||
                (ct==13) || (ct==14) ||(ct==15) || (ct==0))) begin
                    s1r<=d8r + dr ;
                    s1i<=d8i + di ;
                    s2r<=d8r - dr ;
                    s2i<= d8i - di;
                end    
            if    (ED)   begin            //delayed results
                    s1d1r<=s1r;    s1d2r<=s1d1r;    s1d1i<=s1i;       s1d2i<=s1d1i;      
                    s1d3r<=s1d2r;    s1d3i<=s1d2i;    s1d4r<=s1d3r;    s1d4i<=s1d3i;
                    s1d5r<=s1d4r;    s1d5i<=s1d4i;    s1d6r<=s1d5r;    s1d6i<=s1d5i;
                    s1d7r<=s1d6r;    s1d7i<=s1d6i;    s1d8r<=s1d7r;    s1d8i<=s1d7i;
                    
                    s2d1r<=s2r;    s2d2r<=s2d1r;    s2d1i<=s2i;        s2d2i<=s2d1i;      
                    s2d3r<=s2d2r;    s2d3i<=s2d2i;    s2d4r<=s2d3r;    s2d4i<=s2d3i;
                    s2d5r<=s2d4r;    s2d5i<=s2d4i;    s2d6r<=s2d5r;    s2d6i<=s2d5i;
                    s2d7r<=s2d6r;    s2d7i<=s2d6i;    s2d8r<=s2d7r;    s2d8i<=s2d7i;    
                    if (ct==2)  begin
                        m4_12r<=s2d8r;    m4_12i<=s2d8i;    end
                    else if  (ct==6)  begin
                            m4_12r<=s2d8i;    m4_12i<= 0 - s2d8r;    
                        end
                end
        end              
    ///
    //arm of even result calculations 
    
    reg signed [nb+1:0]    s3r,s3d1r,s3d2r,s3d3r,s3d4r,s3d5r,s3d6r;
    reg signed [nb+1:0]    s3i,s3d1i,s3d2i,s3d3i,s3d4i,s3d5i,s3d6i;
    always @(posedge CLK)    begin          //ALU    S3:    
            if (ED)        begin
                    case (ct) 
                        14 ,15 : begin s3r<=  s1d4r+s1r;            //t15 //t18
                            s3i<= s1d4i+ s1i ;end  
                        0 ,1 : begin s3r<=  s1d6r - s1d2r;            //m3, t19
                            s3i<= s1d6i - s1d2i ;end  
                        2 ,3  : begin s3r<= s1d6r +s1d2r;          //t16 ,t20
                            s3i<= s1d6i+ s1d2i ; end
                        4 ,5 : begin s3r<=  s1d8r - s1d4r;          //    m11',t21
                            s3i<= s1d8i - s1d4i ; end        
                    endcase
                    s3d1r<=s3r;     s3d1i<=s3i;     s3d2r<=s3d1r; s3d2i<=s3d1i;    
                    s3d3r<=s3d2r;    s3d3i<=s3d2i;    s3d4r<=s3d3r; s3d4i<=s3d3i;    
                    s3d5r<=s3d4r;    s3d5i<=s3d4i;    s3d6r<=s3d5r; s3d6i<=s3d5i;     
                end
        end           
    
    reg signed [nb+2:0]    s4r,s4d1r,s4d2r,s4d3r,s4d4r,s4d5r,s4d6r,s4d7r,m3r;
    reg signed [nb+2:0]    s4i,s4d1i,s4d2i,s4d3i,s4d4i,s4d5i,s4d6i,s4d7i,m3i;
    
    always @ (posedge CLK)    begin          // S4 
            if (ED)    begin
                    if ((ct==3) | (ct==4)) begin
                            s4r<= s3d4r + s3r; //t17       ,t22
                        s4i<= s3d4i + s3i; end
                    else if ((ct==5) | (ct==6) | (ct==8) ) begin
                            s4r<=s3d6r - s3d2r;                           //m2,m10', m5'
                        s4i<= s3d6i - s3d2i;  end
                    else if (ct==7) begin
                            s4r<=s3d1r + s3d5r;                         //m13
                            s4i<= s3d1i + s3d5i;
                        end   
                    s4d1r<=s4r;         s4d1i<=s4i;         s4d2r<=s4d1r; s4d2i<=s4d1i;    
                    s4d3r<=s4d2r;    s4d3i<=s4d2i;    s4d4r<=s4d3r; s4d4i<=s4d3i;    
                    s4d5r<=s4d4r;    s4d5i<=s4d4i;    s4d6r<=s4d5r; s4d6i<=s4d5i;      
                    s4d7r<=s4d6r;    s4d7i<=s4d6i;     
                    if (ct==7) begin 
                            m3r<=s3d6r;                     //m3
                        m3i<=s3d6i;  end
                end 
        end 
    
    wire em707,mpyj7;
    assign    em707 = ((ct==8) || (ct==10 )||(ct==1) || (ct==5));    //control signals for the multiplier 
    assign   mpyj7 = ((ct==8) || (ct==5));
    
    reg signed [nb+2:0]    s7r,s7d1r;
    reg signed [nb+2:0]    s7i,s7d1i;
    wire signed [nb+2:0] m707r,m707i,m70r,m70i;       
    assign m70r = ((ct==1) || (ct==5))? s7r :s4r;       //multiplexor at the multiplier input
    assign m70i = ((ct==1) || (ct==5))? s7i :s4i;
    
    MPUC707 #(nb+3) UM707(  .CLK(CLK),.EI(ED),.ED(em707), .MPYJ(mpyj7)
                            ,.DR(m70r),.DI(m70i) ,.DOR(m707r) ,.DOI(m707i));
    
    
    reg signed [nb+2:0]    s3jr,s3ji, m10r,m10i;
    always @ (posedge CLK)    begin           //multiply by J 
            if (ED) begin    
                    case  (ct) 
                        11: begin s3jr<= s3d6i;                    //m11
                            s3ji<=0 - s3d6r; end
                        14: begin s3jr<= s4d7i;    //m10 
                            s3ji<=0 - s4d7r; end
                    endcase
                    if (ct==1) begin
                            m10r<=s3jr;                 //m10
                            m10i<=s3ji;
                        end
                end 
        end     
    
    reg     signed [nb+3:0]    s5r,s5d1r,s5d2r,s5d3r,s5d4r,s5d5r,s5d6r,s5d7r,s5d8r,s5d9r, s5d10r,m2r,m2dr;
    reg     signed [nb+3:0]    s5i,s5d1i,s5d2i,s5d3i,s5d4i,s5d5i,s5d6i,s5d7i,s5d8i,s5d9i,s5d10i,m2i,m2di;
    always @ (posedge CLK)             //     S5:
        if (ED)     begin 
                case  (ct) 
                10: begin     s5r<=s4d5r + s4d6r;    //m0
                    s5i<=s4d5i + s4d6i; end
                11: begin     s5r<=s4d7r - s4d6r;     //m1
                    s5i<=s4d7i - s4d6i;    end                              
                12: begin     s5r<=m707r + s3jr;      //S3
                s5i<= m707i+s3ji;end
                13: begin     s5r<=m707r - s3jr;      //S4
                s5i<= m707i - s3ji;end
                14: begin     s5r<= m3r+m707r;      //S1
                s5i<= m3i+m707i ;end
                15: begin     s5r<=m3r-m707r ;      //S2
                s5i<= m3i -m707i ;end 
                6: begin      //S2
                    s5d10r<=s5d9r ;      //S2
                s5d10i<=s5d9i ;end 
                
                endcase             
                if      ((ct==4)||(ct==5)||(ct==6)||(ct==7)) begin    
                    s5d9r<=s5d8r ;     s5d9i<=s5d8i ;    end       
                
                s5d1r<=s5r;        s5d1i<=s5i;        s5d2r<=s5d1r;    s5d2i<=s5d1i;      
                s5d3r<=s5d2r;    s5d3i<=s5d2i;    s5d4r<=s5d3r;    s5d4i<=s5d3i;
                s5d5r<=s5d4r;    s5d5i<=s5d4i;    s5d6r<=s5d5r;    s5d6i<=s5d5i;
                s5d7r<=s5d6r;    s5d7i<=s5d6i;    s5d8r<=s5d7r;    s5d8i<=s5d7i;     
                
                if (ct==13)  begin
                    m2r<=s4d7r;    m2i<=s4d7i;    end
                if (ct==1)  begin
                    m2dr<=m2r;    m2di<=m2i;    end
                
            end
    
    
    
    reg     signed [nb+3:0]    s6r,s6i    ;
    
    `ifdef FFT256paramifft                // For IFFT
    always @ (posedge CLK)    begin         //  S6-- result adder
            if (ED)  
                case  (ct) 
                    13: begin s6r<=s5d2r;      // --     Y0
                        s6i<=(s5d2i);end       //--     Y0
                    15: begin  
                            s6r<=s5d2r - s5r ;                 //Y2
                        s6i<=s5d2i - s5i ;     end
                    1:  begin      
                            s6r<=m2r - s3jr ;                  //Y4
                        s6i<=m2i - s3ji ;      end
                    3:  begin 
                            s6r<=s5d3r - s5d5r ;                //Y6
                        s6i<= s5d3i -s5d5i ;    end   
                    5:begin    s6r<=(s5d9r) ;        //--     Y8
                        s6i<=(s5d9i) ; end
                    7: begin      
                            s6r<= s5d7r + s5d9r ;           //     Y10
                        s6i<= s5d7i + s5d9i ;       end
                    9: begin                                  //     Y12
                            s6r<=m2dr +m10r ;       
                            s6i<=m2di + m10i ;    
                        end       
                    11:   begin                                        //    Y14
                            s6r<= s5d9r + s5d10r ;       
                            s6i<= s5d9i + s5d10i ;      
                        end 
                endcase       
        end    
    
    `else
    always @ (posedge CLK)    begin         //  S6-- result adder
            if (ED)  
                case  (ct) 
                    13: begin s6r<=s5d2r;      // --     Y0
                        s6i<=s5d2i;end       //--     Y0
                    15: begin  
                            s6r<=s5d2r + s5r ;                 //Y2
                        s6i<=s5d2i + s5i ;     end
                    1:  begin      
                            s6r<=m2r + s3jr ;                  //Y4
                        s6i<=m2i + s3ji ;      end
                    3:  begin 
                            s6r<=s5d3r + s5d5r ;                //Y6
                        s6i<= s5d3i +s5d5i ;    end   
                    5:begin    s6r<=s5d9r;        //--     Y8
                        s6i<=s5d9i; end
                    7: begin      
                            s6r<= s5d7r - s5d9r ;           //     Y10
                        s6i<= s5d7i - s5d9i ;       end
                    9: begin                                  //     Y12
                            s6r<=m2dr -m10r ;       
                            s6i<=m2di - m10i ;    
                        end       
                    11:   begin                                        //    Y14
                            s6r<= s5d9r - s5d10r ;       
                            s6i<= s5d9i - s5d10i ;      
                        end 
                endcase       
        end    
    `endif         
    
    ///
    //arm of odd result calculations 
    //

    always @(posedge CLK)    begin          //ALU    S7:    
            if (ED)  
                case (ct)         
                    15:begin s7r<=  s2d2r-s2r;            //t26
                        s7i<= s2d2i- s2i ;end  
                    0: begin s7r<=  s2d4r-s2r;            //m6'
                            s7i<= s2d4i- s2i ;
                            s7d1r<=s7r;
                        s7d1i<=s7i;end  
                    1: begin s7r<=  s2d6r - s2r;          //t24
                        s7i<= s2d6i - s2i; end 
                    2: begin s7r<= s7r -s7d1r;          //m7'
                        s7i<= s7i- s7d1i ; end
                    3: begin s7r<=  s2d8r + s2d2r;          //    t23
                        s7i<= s2d8i + s2d2i ; end
                    4: begin s7r<=  s2d8r + s2d4r;          //    m14'
                            s7i<= s2d8i + s2d4i ;
                            s7d1r<=s7r;
                        s7d1i<=s7i;end
                    5: begin s7r<=  s2d8r + s2d6r;          //    t25
                        s7i<= s2d8i + s2d6i ; end
                    6: begin  s7r<= s7r + s7d1r;          //m15'
                        s7i<= s7i + s7d1i ; end
                endcase                                  
        end
    
    wire em541,mpyj541;
    wire signed [nb+2:0] m541r,m541i;      
    assign    em541 = ((ct==0) || (ct==4));    //control signals for the multiplier 
    assign   mpyj541 = ((ct==4));
    MPUC541 #(nb+3) UM541(  .CLK(CLK),.EI(ED),.ED(em541), .MPYJ(mpyj541),     //multiplier by 0.383
        .DR(s7r),.DI(s7i) ,.DOR(m541r) ,.DOI(m541i));
    
    
    wire em1307,mpyj1307;
    wire signed [nb+2:0] m1307r,m1307i;      
    assign    em1307 = ((ct==2) || (ct==6));    //control signals for the multiplier 
    assign   mpyj1307 = ((ct==6));
    MPUC1307 #(nb+3) UM1307(  .CLK(CLK),.EI(ED),.ED(em1307), .MPYJ(mpyj1307),     //multiplier by 1.306
        .DR(s7r),.DI(s7i) ,.DOR(m1307r) ,.DOI(m1307i));
    
    wire em383,mpyj383,c383;
    wire signed [nb+2:0] m383r,m383i;      
    assign    em383 = ((ct==3) || (ct==7));    //control signals for the multiplier 
    assign   mpyj383 = ((ct==7));  
    assign c383 = (ct==3);
    MPUC924_383  #(nb+3) UM383(.CLK(CLK),.EI(ED),.ED(em383),.MPYJ(mpyj383),.C383(c383),     //multiplier by 0.383
        .DR(s7r),.DI(s7i) ,.DOR(m383r) ,.DOI(m383i));
    
    reg signed [nb+2:0] m8_17r,m8_17i,m9_16r,m9_16i;      
    always @(posedge CLK)    begin          //Reg-s
            if    (ED) begin
                    if (ct==4 || ct==8) begin
                            m9_16r<=m541r;                        //M9_ M16
                            m9_16i<=m541i;
                        end 
                    if ( ct==6 || ct==10) begin
                            m8_17r<=m1307r;                      //M8_ M17
                            m8_17i<=m1307i;
                        end 
                end           
        end                   
    
    
    
    
    reg     signed [nb+2:0]    s8r,s8i,s8d1r,s8d2r,s8d3r,s8d4r,s8d1i,s8d2i,s8d3i,s8d4i    ;
    always @ (posedge CLK)    begin         //  S8--  adder
            if (ED)  
            begin
                case  (ct) 
                    5,9: begin s8r<=m4_12r +m707r ;      // --     S5     S13
                        s8i<=m4_12i +m707i  ;end       //--     
                    6,10: begin  
                            s8r<=m4_12r - m707r ;      // --     S6    , S14
                        s8i<=m4_12i - m707i  ; end
                    7:  begin      
                            s8r<=m8_17r - m383r ;      // --     S7     ,S15
                        s8i<=m8_17i -m383i  ;  end
                    8:  begin 
                            s8r<=m9_16r - m383r ;      // --     S8    ,    S16
                        s8i<=m9_16i -m383i  ;      end    
                    11:  begin      
                            s8r<=m383r - m9_16r  ;      // --     S7     ,S15
                        s8i<=m383i -   m9_16i;  end
                    12:  begin 
                            s8r<=m383r - m8_17r;      // --     S8    ,    S16
                        s8i<=m383i - m8_17i;      end   
                endcase      
            s8d1r<=s8r;        s8d1i<=s8i;        s8d2r<=s8d1r;    s8d2i<=s8d1i;      
            s8d3r<=s8d2r;    s8d3i<=s8d2i;    s8d4r<=s8d3r;    s8d4i<=s8d3i;
        end    
        end
    
    reg     signed [nb+3:0]    s9r,s9d1r,s9d2r,s9d3r,s9d4r,s9d5r,s9d6r,s9d7r,s9d8r,s9d9r, s9d10r,s9d11r,s9d12r,s9d13r;
    reg     signed [nb+3:0]    s9i,s9d1i,s9d2i,s9d3i,s9d4i,s9d5i,s9d6i,s9d7i,s9d8i,s9d9i,s9d10i,s9d11i,s9d12i,s9d13i;
    always @ (posedge CLK)             //     ALU s9:
        if (ED)     begin 
                case  (ct) 
                8,9,12: begin     s9r<=  s8r + s8d2r;    // S9,S11     , S17
                    s9i<=s8i + s8d2i  ; end
                13: begin     s9r<=  s8d2r - s8r;    // S20
                    s9i<=s8d2i - s8i ; end
                10,11,14: begin     s9r<=s8d4r - s8d2r;     //S10, S12,S18
                    s9i<=s8d4i - s8d2i;    end        
                15: begin     s9r<=s8d4r + s8d2r;     //S19
                s9i<=s8d4i + s8d2i;    end                              
                endcase             
                
                s9d1r<=s9r;        s9d1i<=s9i;        s9d2r<=s9d1r;    s9d2i<=s9d1i;      
                s9d3r<=s9d2r;    s9d3i<=s9d2i;    s9d4r<=s9d3r;    s9d4i<=s9d3i;
                s9d5r<=s9d4r;    s9d5i<=s9d4i;    s9d6r<=s9d5r;    s9d6i<=s9d5i;
                s9d7r<=s9d6r;    s9d7i<=s9d6i;    s9d8r<=s9d7r;    s9d8i<=s9d7i;     
                
                s9d9r<=s9d8r ;     s9d9i<=s9d8i ;    
                if ((ct!=8)) begin
                    s9d10r<=s9d9r ;     s9d10i<=s9d9i ;
                    s9d11r<=s9d10r ;     s9d11i<=s9d10i ;  end    
                if ((ct==4) ||(ct==5) ||(ct==7) ||(ct==9) )  begin
                    s9d12r<=s9d11r ;     s9d12i<=s9d11i ;    end
                if ((ct==5))begin
                    s9d13r<=s9d12r ;     s9d13i<=s9d12i ;    end
                
            end       

    reg     signed [nb+3:0]    s10r,s10i;
    reg     signed [nb+3:0]    s10dr,s10di;

            `ifdef FFT256paramifft        //For IFFT
    always @ (posedge CLK)    begin         //  S10-- result adder
            if (ED)  
                case  (ct) 
                    13: begin s10r<=s9d4r -s9r ;      // --     Y1
                        s10i<=s9d4i -s9i ;end       //
                    15:  begin 
                            s10r<=s9d3r + s9d1r ;                 //--     Y3
                        s10i<=s9d3i + s9d1i ; end     
                    1:   begin 
                            s10r<=s9d7r - s9d1r ;             //--     Y5
                        s10i<=s9d7i - s9d1i ;       end
                    3:   begin 
                            s10r<=s9d8r + s9d4r ;                   // --     Y7
                        s10i<= s9d8i + s9d4i ;end       
                    
                    5:begin    s10r<=s9d10r - s9d6r ;        //--     Y9
                        s10i<=s9d10i - s9d6i ; end
                    7:   begin 
                            s10r<=s9d12r + s9d7r ;                  //--     Y11
                        s10i<=s9d12i + s9d7i ; end       
                    
                    9:  begin 
                            s10r<= s9d12r - s9d10r ;            //     Y13
                        s10i<=s9d12i - s9d10i ;    end
                    
                    11:   begin 
                            s10r<= s9d13r + s9d12r ;             //     Y15
                        s10i<=  s9d13i + s9d12i ;    end
                    
                endcase         
            s10dr<=s10r; s10di<=s10i;
        end    
    `else
        
//    reg signed [nb+3:0]    s10r,s10i,s10dr,s10di;
    always @ (posedge CLK)    begin         //  S10-- result adder
            if (ED)  
                case  (ct) 
                    13: begin s10r<=s9d4r +s9r ;      // --     Y0
                        s10i<=s9d4i +s9i ;end       //
                    15:  begin 
                            s10r<=s9d3r - s9d1r ;                 //--     Y3
                        s10i<=s9d3i - s9d1i ; end     
                    1:   begin 
                            s10r<=s9d7r +s9d1r ;             //--     Y5
                        s10i<=s9d7i +s9d1i ;       end
                    3:   begin 
                            s10r<=s9d8r - s9d4r ;                   // --     Y7
                        s10i<= s9d8i - s9d4i ;end       
                    
                    5:begin    s10r<=s9d10r + s9d6r ;        //--     Y9
                        s10i<=s9d10i + s9d6i ; end
                    7:   begin 
                            s10r<=s9d12r - s9d7r ;                  //--     Y11
                        s10i<=s9d12i - s9d7i ; end       
                    
                    9:  begin 
                            s10r<= s9d12r + s9d10r ;            //     Y13
                        s10i<=s9d12i + s9d10i ;    end
                    
                    11:   begin 
                            s10r<= s9d13r - s9d12r ;             //     Y15
                        s10i<=  s9d13i - s9d12i ;    end
                    
                endcase         
            s10dr<=s10r; s10di<=s10i;
        end      
        `endif          
        
//wire signed [nb+3:0]    s6sr,s6si;      //saturation of results
//    assign s6sr = (~s6r[nb+4]&&s6r[nb+3])? ((1'b1 <<(nb+3))-1)    : s6r[nb+3:0];    
//    assign s6si = (~s6i[nb+4]&&s6i[nb+3])? ((1'b1<<(nb+3))-1)        : s6i[nb+3:0];    
//
    
    wire selo;
    assign selo = ct-(ct/2)*2;
        assign #1    DOR=selo? s10dr:s6r;
        assign #1    DOI= selo? s10di:s6i;
    
endmodule