【原创】基于DE2-115的8点FFT实现

 

说明:

KEY[3]——复位

KEY[2]——允许接收数据并开始fft

KEY[1]——允许读取SRAM指定地址中的数据,地址由SW指定。

datar/datai——输入数据的实部和虚部,用于实验的8个数据为0~7,依时钟逐个输入。

DOR/DOI——fft变换结果的实部和虚部,数据位数=18位

rWR——写SRAM允许信号(sram_controller.v中的相关语句if (iWR),说明这个写允许信号需要保持住高电平,是否可以考虑在always的敏感条件中加posedge iWR?)

hdata——SRAM指定地址中的数据,数据位数=16位。

SW——指定SRAM的读取地址。

 

验证:

1、modelsim

 

变为二进制的结果:

DOR:第一个是   0000 0000 0000 0011 100(28)

后7个都是1111 1111 1111 1111 100(-4)

以DOR[18:5]作为输出,则依次显示的是:0003、FFFF(7个)

DOI:第一个:0000 0000 0000 0000 000(0)

             0000 0000 0000 0001 010(10)

             0000 0000 0000 0000 100(4)

             0000 0000 0000 0000 010(2)

             0000 0000 0000 0000 000(0)

             1111 1111 1111 1111 110(-2)

             1111 1111 1111 1111 100(-4)

             1111 1111 1111 1110 110(-10)

以DOI[18:5]作为输出,依次显示:0000、0001、0000、0000、0000、FFFF、FFFF、FFFE。

 

Step1:用DE2_115_SystemBuilder生成工程及顶层文件。

 

//=======================================================

//  This code is generated by Terasic System Builder

//=======================================================

 

module SRAM_115(

 

         //////////// CLOCK //////////

         CLOCK_50,

         CLOCK2_50,

         CLOCK3_50,

 

         //////////// LED //////////

         LEDG,

         LEDR,

 

         //////////// KEY //////////

         KEY,

 

         //////////// SW //////////

         SW,

 

         //////////// SEG7 //////////

         HEX0,

         HEX1,

         HEX2,

         HEX3,

         HEX4,

         HEX5,

         HEX6,

         HEX7,

 

         //////////// SRAM //////////

         SRAM_ADDR,

         SRAM_CE_N,

         SRAM_DQ,

         SRAM_LB_N,

         SRAM_OE_N,

         SRAM_UB_N,

         SRAM_WE_N

);

 

//=======================================================

//  PARAMETER declarations

//=======================================================

 

 

//=======================================================

//  PORT declarations

//=======================================================

 

//////////// CLOCK //////////

input                                          CLOCK_50;

input                                          CLOCK2_50;

input                                          CLOCK3_50;

 

//////////// LED //////////

output                    [8:0]                 LEDG;

output                   [17:0]                 LEDR;

 

//////////// KEY //////////

input                       [3:0]                 KEY;

 

//////////// SW //////////

input                      [17:0]                 SW;

 

//////////// SEG7 //////////

output                    [6:0]                 HEX0;

output                    [6:0]                 HEX1;

output                    [6:0]                 HEX2;

output                    [6:0]                 HEX3;

output                    [6:0]                 HEX4;

output                    [6:0]                 HEX5;

output                    [6:0]                 HEX6;

output                    [6:0]                 HEX7;

 

//////////// SRAM //////////

output                   [19:0]                 SRAM_ADDR;

output                                       SRAM_CE_N;

inout                      [15:0]                 SRAM_DQ;

output                                       SRAM_LB_N;

output                                       SRAM_OE_N;

output                                       SRAM_UB_N;

output                                       SRAM_WE_N;

 

 

//=======================================================

//  REG/WIRE declarations

//=======================================================

 

 

 

 

//=======================================================

//  Structural coding

//=======================================================

 

 

 

endmodule

 

step2:8点fft程序——FFT8.v

/////////////////////////////////////////////////////////////////////

////                                                             ////

////  8-point FFT, First stage of FFT 64 processor               ////

////                                                             ////

////  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                                           ////

//// [email protected]                                     ////

////                                                             ////

//// 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.          ////

////                                                             ////

/////////////////////////////////////////////////////////////////////

// Design_Version       : 1.0

// File name            : FFT8.v

// File Revision        :

// Last modification    : Sun Sep 30 20:11:56 2007

/////////////////////////////////////////////////////////////////////

// FUNCTION: 8-point FFT

// FILES: FFT8.v - 1-st stage, contains

//        MPU707.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 8-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 FFT8(

//               D: in MEMOC8;  -- input array

//               DO:out MEMOC8)  -- output ARRAY

//               is  

//               variable t1,t2,t3,t4,t5,t6,t7,t8,m0,m1,m2,m3,m4,m5,m6,m7: complex;

//               variable s1,s2,s3,s4: complex;

//      begin                                                        

//               t1:=D(0) + D(4);

//               m3:=D(0) - D(4);

//               t2:=D(6) + D(2);

//         m6:=CBASE_j*(D(6)-D(2));

//               t3:=D(1) + D(5);

//               t4:=D(1) - D(5);

//               t5:=D(3) + D(7);

//               t6:=D(3) - D(7);

//               t8:=t5 + t3;

//               m5:=CBASE_j*(t5-t3);

//               t7:=t1 + t2;

//               m2:=t1 - t2;

//               m0:=t7 + t8;

//               m1:=t7 - t8;       

//               m4:=SQRT(0.5)*(t4 - t6);

//               m7:=-CBASE_j*SQRT(0.5)*(t4 + t6);          

//               s1:=m3 + m4;

//               s2:=m3 - m4;

//               s3:=m6 + m7;

//               s4:=m6 - m7;

//               DO(0):=m0;

//               DO(4):=m1;

//               DO(1):=s1 + s3;

//               DO(7):=s1 - s3;

//               DO(2):=m2 + m5;

//               DO(6):=m2 - m5;

//               DO(5):=s2 + s4;

//               DO(3):=s2 - s4;

//      end procedure;        

/////////////////////////////////////////////////////////////////////

`timescale 1ps / 1ps 

`include "FFT64_CONFIG.inc"

 

module FFT8 ( DOR ,DII ,RST ,ED ,CLK ,DOI ,START ,DIR ,RDY );

         `USFFT64paramnb  

        

         input ED ;

         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+2:0] DOI ;

         wire [nb+2:0] DOI ;

         output [nb+2:0] DOR ;

         wire [nb+2:0] DOR ;

         output RDY ;

         reg RDY ;            

        

         reg [2:0] ct; //main phase counter

         reg [3:0] ctd; //delay counter

        

         always @(   posedge CLK) begin  //Control counter

                            //

                            if (RST)      begin

                                               ct<=0;

                                               ctd<=15;

                                     RDY<=0;  end

                            else if (START)    begin

                                               ct<=0;

                                               ctd<=0;   

                                     RDY<=0;   end

                            else if (ED) begin     

                                               RDY<=0;

                                               ct<=ct+1'b1;   

                                               if (ctd !=4'b1111)

                                                        ctd<=ctd+1'b1;                 

                                               if (ctd==12 )

                                                        RDY<=1;

                                     end

                           

                   end    

        

         reg signed        [nb-1: 0] dr,d1r,d2r,d3r,d4r,di,d1i,d2i,d3i,d4i;

         always @(posedge CLK)    // input register file

                   begin

                            if (ED)      begin

                                              dr<=DIR; 

                                               d1r<=dr; 

                                               d2r<=d1r;

                                               d3r<=d2r;

                                               d4r<=d3r;                                    

                                               di<=DII; 

                                               d1i<=di; 

                                               d2i<=d1i;

                                               d3i<=d2i;

                                               d4i<=d3i;                            

                                     end

                   end         

        

         reg signed        [nb:0]        s1r,s2r,s1d1r,s1d2r,s1d3r,s2d1r,s2d2r,s2d3r;

         reg signed        [nb:0]        s1i,s2i,s1d1i,s1d2i,s1d3i,s2d1i,s2d2i,s2d3i;

         always @(posedge CLK)  begin                     // S1,S2 =t1-t6,m3 and delayed

                            if (ED && ((ct==5) || (ct==6) || (ct==7) || (ct==0))) begin

                                               s1r<=d4r + dr ;

                                               s1i<=d4i + di ;

                                               s2r<=d4r - dr ;

                                               s2i<= d4i - di;

                                     end 

                            if       (ED)   begin

                                               s1d1r<=s1r;

                                               s1d2r<=s1d1r;  

                                               s1d1i<=s1i;

                                               s1d2i<=s1d1i;   

                                               if (ct==0 || ct==1)    begin        //## note for vhdl

                                                                 s1d3r<=s1d2r;

                                                                 s1d3i<=s1d2i;

                                                        end

                                               if (ct==6 || ct==7 || ct==0) begin

                                                                 s2d1r<=s2r;

                                                                 s2d2r<=s2d1r;

                                                                 s2d1i<=s2i;

                                                                 s2d2i<=s2d1i;

                                                        end             

                                               if (ct==0) begin

                                                                 s2d3r<=s2d2r;

                                                                 s2d3i<=s2d2i;

                                                        end

                                     end

                   end                      

        

        

         reg signed [nb+1:0] s3r,s4r,s3d1r,s3d2r,s3d3r;

         reg signed [nb+1:0] s3i,s4i,s3d1i,s3d2i,s3d3i;

         always @(posedge CLK)  begin                    //ALU   S3:   

                            if (ED) 

                                     case (ct)

                                               0: begin s3r<=  s1d2r+s1r;              //t7

                                                        s3i<= s1d2i+ s1i ;end 

                                               1: begin s3r<=  s1d3r - s1d1r;                //m2

                                                        s3i<= s1d3i - s1d1i; end

                                              2: begin s3r<= s1d3r +s1r;               //t8

                                                        s3i<= s1d3i+ s1i ; end

                                               3: begin s3r<=  s1d3r - s1r;           //

                                                        s3i<= s1d3i - s1i ; end

                                     endcase

                           

                            if       (ED) begin

                                               if (ct==1 || ct==2 || ct==3) begin

                                                                 s3d1r<=s3r;                                                    //t8

                                                                 s3d1i<=s3i;

                                                        end

                                               if ( ct==2 || ct==3) begin

                                                                 s3d2r<=s3d1r;                                    //m2

                                                                 s3d3r<=s3d2r;                                //t7

                                                                 s3d2i<=s3d1i;   

                                                                 s3d3i<=s3d2i;

                                                        end

                                     end                      

                   end                                   

        

         always @ (posedge CLK) begin                    // S4

                            if (ED)       begin

                                               if (ct==1) begin

                                                                 s4r<= s2d2r + s2r;

                                                        s4i<= s2d2i + s2i; end

                                               else if (ct==2) begin

                                                                 s4r<=s2d2r - s2r;

                                                                 s4i<= s2d2i - s2i;

                                                        end

                                     end

                   end

        

         wire em;

         assign       em = ((ct==2 || ct==3 || ct==4)&& ED);

        

         wire signed [nb+1:0] m4m7r,m4m7i;

         MPU707 #(nb) UMR( .CLK(CLK),.EI(em),.DI(s4r),.DO(m4m7r));     //  UMR

         MPU707 #(nb) UMI( .CLK(CLK),.EI(em),.DI(s4i),     .DO(m4m7i));  //  UMR

        

         reg signed [nb+1:0] sjr,sji, m6r,m6i;

         always @ (posedge CLK) begin                     //multiply by J

                            if (ED) begin    

                                               case  (ct)

                                                        3: begin sjr<= s2d1i;                         //m6

                                                                 sji<=0 - s2d1r; end

                                                        4: begin sjr<= m4m7i;      //m7

                                                                 sji<=0 - m4m7r;end

                                                        6: begin sjr<= s3i;              //m5

                                                                 sji<=0 - s3r;        end

                                               endcase

                                               if (ct==4) begin

                                                                 m6r<=sjr;                                      //m6

                                                                 m6i<=sji;

                                                        end

                                     end

                   end         

        

         reg signed [nb+2:0]        s5r,s5d1r,s5d2r,q1r;

         reg signed [nb+2:0]        s5i,s5d1i,s5d2i,q1i;

         always @ (posedge CLK)               // S5:

                   if (ED)        

                            case  (ct)

                                     5: begin q1r<=s2d3r +m4m7r ;           //        S1

                                                        q1i<=s2d3i +m4m7i ;       

                                                        s5r<=m6r + sjr;

                                               s5i<=m6i + sji; end

                                     6: begin s5r<=m6r - sjr;

                                                        s5i<=m6i - sji;                                                                     

                                                        s5d1r<=s5r;

                                               s5d1i<=s5i; end

                                     7: begin    s5r<=s2d3r - m4m7r;

                                                        s5i<=s2d3i - m4m7i;          

                                                        s5d1r<=s5r;

                                                        s5d1i<=s5i;

                                                        s5d2r<=s5d1r;

                                                        s5d2i<=s5d1i;

                                               end

                            endcase

        

         reg signed [nb+3:0]        s6r,s6i      ;

         `ifdef paramifft

         always @ (posedge CLK) begin                  //  S6-- result adder

                            if (ED) 

                                     case  (ct)

                                               5: begin s6r<=s3d3r +s3d1r ;    // --       D0

                                                        s6i<=s3d3i +s3d1i ;end       //--      D0

                                               6: begin 

                                                                           s6r<=q1r - s5r ;           

                                                                 s6i<=q1i - s5i ; end

                                               7:  begin          

                                                                           s6r<=s3d2r - sjr ;       

                                                                 s6i<=s3d2i - sji ;          end

                                               0:  begin

                                                                           s6r<=s5r + s5d1r ;     

                                                                 s6i<= s5i +s5d1i ;     end  

                                               1:begin     s6r<=s3d3r - s3d1r ;             //--   D4

                                                        s6i<=s3d3i - s3d1i ; end

                                               2: begin     

                                                                           s6r<= s5r - s5d1r ;          //        D5

                                                                 s6i<= s5i - s5d1i ;        end

                                               3: begin                                                                      //      D6

                                                                           s6r<=s3d3r + sjr ;       

                                                                           s6i<=s3d3i + sji ;      

                                                                 end            

                                               4:   begin                                                                                   //        D0

                                                                           s6r<= q1r + s5d2r ;    

                                                                           s6i<= q1i + s5d2i ;     

                                                                 end

                                     endcase

                   end 

                  

   `else

                            always @ (posedge CLK) begin                  //  S6-- result adder

                            if (ED) 

                                     case  (ct)

                                               5: begin s6r<=s3d3r +s3d1r ;    // --       D0

                                                        s6i<=s3d3i +s3d1i ;end       //--      D0

                                               6:  begin

                                                                           s6r<=q1r + s5r ;                     //-- D1

                                                                 s6i<=q1i + s5i ; end 

                                                        7:   begin

                                                                           s6r<=s3d2r +sjr ;               //-- D2

                                                                 s6i<=s3d2i +sji ;           end

                                               0:   begin

                                                                           s6r<=s5r - s5d1r ;                   // --     D3

                                                                 s6i<= s5i - s5d1i ;end          

                                                       

                                               1:begin     s6r<=s3d3r - s3d1r ;             //--   D4

                                                        s6i<=s3d3i - s3d1i ; end

                                               2:   begin

                                                                          s6r<=s5r + s5d1r ;                 //--        D5

                                                                 s6i<=s5i + s5d1i ; end         

                                                       

                                               3:  begin

                                                                           s6r<= s3d3r - sjr ;             //      D6

                                                                 s6i<=s3d3i - sji ;        end

                                              

                                               4:   begin

                                                                           s6r<= q1r - s5d2r ;            //    D0

                                                                 s6i<=  q1i - s5d2i ; end

                                                       

                                     endcase

                   end   

         `endif

                  

         assign #1 DOR=s6r[nb+2:0];

         assign #1 DOI= s6i[nb+2:0];

        

endmodule

 

乘以0.707的子程序——MPU707.v

/////////////////////////////////////////////////////////////////////

////                                                             ////

////  Multiplier by 0.7071                                       ////

////                                                             ////

////  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                                           ////

//// [email protected]                                     ////

////                                                             ////

//// 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.          ////

////                                                             ////

/////////////////////////////////////////////////////////////////////

// Design_Version       : 1.0

// File name            : MPU707.v

// File Revision        :

// Last modification    : Sun Sep 30 20:11:56 2007

/////////////////////////////////////////////////////////////////////

// FUNCTION: Constant multiplier

// PROPERTIES:1)Is based on shifts right and add

//                 2)for short input bit width 0.7071 is approximated as

//              10110101 then rounding is not used

//                 3)for long input bit width 0.7071 is approximated as

//              10110101000000101              

//                 4)hardware is 3 or 4 adders

/////////////////////////////////////////////////////////////////////

//`include "FFT64_CONFIG.inc"

 

module MPU707 ( CLK ,DO ,DI ,EI );

//`USFFT64paramnb

         parameter nb = 16;

         input CLK ;

         wire CLK ;

         input [nb+1:0] DI ;

         wire signed [nb+1:0] DI ;

         input EI ;

         wire EI ;

        

         output [nb+1:0] DO ;

         reg [nb+1:0] DO ;    

        

         reg signed [nb+5 :0] dx5;         

         reg signed        [nb+2 : 0] dt;               

         wire signed [nb+6 : 0]  dx5p;

         wire  signed  [nb+6 : 0] dot;        

        

         always @(posedge CLK)

                   begin

                            if (EI) begin

                                               dx5<=DI+(DI <<2);   //multiply by 5

                                               dt<=DI;               

                                               DO<=dot >>>4;        

                                     end

                   end           

                  

         //`ifdef USFFT64bitwidth_0707_high

         //assign   dot=      (dx5p+(dt>>>4)+(dx5>>>12));    // multiply by 10110101000000101       

         //`else                                     

         assign    dot=                 (dx5p+(dt>>>4) )      ;  // multiply by 10110101        

         //`endif           

                  

                   assign       dx5p=(dx5<<1)+(dx5>>>2);               // multiply by 101101                      

        

        

endmodule

 

step3:SRAM控制器——SRAM_controller.v

module SRAM_controller(

                                                        //Host Side

                                                        iCLK,

                                                        iRST_N,

                                                        iWR,

                                                        iRD,

                                                        iWR_ADDR,

                                                        iWR_MAX_ADDR,

                                                        iRD_ADDR,

                                                        iWR_DATA,

                                                        oRD_DATA,

                                                        //SRAM Side

                                                        SRAM_DQ,

                                                        SRAM_ADDR,

                                                        SRAM_CE_N,

                                                        SRAM_OE_N,

                                                        SRAM_WE_N,

                                                        SRAM_UB_N,

                                                        SRAM_LB_N

                                                        );

         //HOST Side

         input                 iCLK,iRST_N,iWR,iRD;

         input                 [19:0]iWR_ADDR,iWR_MAX_ADDR,iRD_ADDR;

         input                  [15:0]iWR_DATA;

         ///////////////////////////////////////

         output     reg   [15:0]oRD_DATA;

         ///////////////////////////////////////

         //SRAM Side

         inout                 [15:0]SRAM_DQ;

         output               SRAM_CE_N, SRAM_OE_N, SRAM_WE_N, SRAM_UB_N, SRAM_LB_N;

         output              [19:0] SRAM_ADDR;

        

         reg                      SRAM_WE_N;

         reg                   [15:0] SRAM_DQ;

         reg                      [19:0] SRAM_ADDR;

        

         assign SRAM_CE_N = 0;//SRAM is always worked

         assign SRAM_UB_N = 0;//upper byte is available

         assign SRAM_LB_N = 0;//lower byte is available

         assign SRAM_OE_N = 0;//output enable (not effect write)

        

         reg [19:0] rWR_ADDR;//,rWR_MAX_ADDR;

 

         always @(posedge iCLK or negedge iRST_N)

                   begin       

                            //system reset

                            if(!iRST_N)

                                     begin

                                               rWR_ADDR              <= iWR_ADDR;;

                                               //rWR_MAX_ADDR         <= iWR_MAX_ADDR;

                                               SRAM_WE_N                    <= 1;                  

                                     end

                            else

                                     begin

                                               //write process

                                               if (iWR==1)

                                                        begin

                                                                 if (rWR_ADDR<iWR_MAX_ADDR)

                                                                           begin

                                                                                    SRAM_WE_N           <= 0;

                                                                                    rWR_ADDR     <= rWR_ADDR+1'b1;

                                                                                    SRAM_DQ       <= iWR_DATA;

                                                                                    SRAM_ADDR <= rWR_ADDR;

                                                                           end

                                                                 else

                                                                           begin

                                                                                    SRAM_WE_N           <= 1;//write disable if reach the max address

                                                                           end

                                                        end

                                              

                                               //read process

                                              if (iRD==1)

                                                        begin

                                                                 SRAM_WE_N   <= 1;

                                                                 SRAM_DQ       <= 16'hzzzz;

                                                                 SRAM_ADDR <= iRD_ADDR;

                                                                 oRD_DATA      <= SRAM_DQ;

                                                        end

                                     end

                   end 

endmodule

 

step4:完成顶层文件。

 

//=======================================================

//  This code is generated by Terasic System Builder

//=======================================================

 

module SRAM_115(

 

         //////////// CLOCK //////////

         CLOCK_50,

         CLOCK2_50,

         CLOCK3_50,

 

         //////////// LED //////////

         LEDG,

         LEDR,

 

         //////////// KEY //////////

         KEY,

 

         //////////// SW //////////

         SW,

 

         //////////// SEG7 //////////

         HEX0,

         HEX1,

         HEX2,

         HEX3,

         HEX4,

         HEX5,

         HEX6,

         HEX7,

 

         //////////// SRAM //////////

         SRAM_ADDR,

         SRAM_CE_N,

         SRAM_DQ,

         SRAM_LB_N,

         SRAM_OE_N,

         SRAM_UB_N,

         SRAM_WE_N

);

 

//=======================================================

//  PARAMETER declarations

//=======================================================

 

 

//=======================================================

//  PORT declarations

//=======================================================

 

//////////// CLOCK //////////

input                                          CLOCK_50;

input                                          CLOCK2_50;

input                                          CLOCK3_50;

 

//////////// LED //////////

output                    [8:0]                 LEDG;

output                   [17:0]                 LEDR;

 

//////////// KEY //////////

input                       [3:0]                 KEY;

 

//////////// SW //////////

input                      [17:0]                 SW;

 

//////////// SEG7 //////////

output                    [6:0]                 HEX0;

output                    [6:0]                 HEX1;

output                    [6:0]                 HEX2;

output                    [6:0]                 HEX3;

output                    [6:0]                 HEX4;

output                    [6:0]                 HEX5;

output                    [6:0]                 HEX6;

output                    [6:0]                 HEX7;

 

//////////// SRAM //////////

output                   [19:0]                 SRAM_ADDR;

output                                       SRAM_CE_N;

inout                      [15:0]                 SRAM_DQ;

output                                       SRAM_LB_N;

output                                       SRAM_OE_N;

output                                       SRAM_UB_N;

output                                       SRAM_WE_N;

 

//=======================================================

//  REG/WIRE declarations

//=======================================================

wire         [15:0]hdata;//data saved in the assigned address

reg            [15:0]datar,datai;

wire [18:0]DOR,DOI;

wire RST_N;

//wire       START;

wire RDY;

reg            rWR;

 

//=======================================================

assign       RST_N=KEY[3];

 

//test t1(

//               .iCLK                   (CLOCK_50),

//               .iRST_N             (RST_N),

//               .iSTART              (!KEY[2]),

//               .oRDY                (RDY)

//               );

 

FFT8 f1(

                   .DOR       (DOR),

                   .DOI         (DOI),

                   .RDY         (RDY),               

                   .RST         (!RST_N),

                   .ED           (1'b1),

                   .CLK         (CLOCK_50),             

                   .START    (!KEY[2]),

                   .DIR         (datar),

                   .DII          (datai)               

                   );

 

always @(posedge CLOCK_50 or negedge RST_N)         begin

         if (!RST_N)        begin

                   datar        <= 0;

                   datai         <= 0;

         end

         else begin

                   if (!KEY[2]) begin//if (RDY) begin

                            datar        <= 0;

                            datai         <= 0;

                   end

                   else begin

                            datar        <= datar + 1'b1;

                            datai         <= 0;

                   end

         end

end

 

//assign iWR=(!KEY[1]) && READY;

always @(posedge CLOCK_50 or negedge RST_N)         begin

         if (!RST_N)        begin

                   rWR<=0;

         end

         else begin

                   if (RDY) begin

                            rWR<=1'b1;

                   end

         end

end

                  

         SRAM_controller sram0(

                            //Host Side

                            .iCLK                            (CLOCK_50),

                            .iRST_N                       (RST_N),//KEY[3]),

                            .iWR                            (rWR),//!KEY[1]),

                            .iRD                    (!KEY[1]),

                            .iWR_ADDR               (0),//0),

                            .iWR_MAX_ADDR   (8),//(100),//262100),//write from iWR_ADDR to iWR_MAX_ADDR-1

                            .iRD_ADDR                (SW),

                            .iWR_DATA                (DOR[18:3]),

                            .oRD_DATA                (hdata),

                            //SRAM Side

                            .SRAM_DQ              (SRAM_DQ),

                            .SRAM_ADDR           (SRAM_ADDR),

                            .SRAM_CE_N            (SRAM_CE_N),

                            .SRAM_OE_N            (SRAM_OE_N),

                            .SRAM_WE_N           (SRAM_WE_N),

                            .SRAM_UB_N           (SRAM_UB_N),

                            .SRAM_LB_N            (SRAM_LB_N)

                            );

        

        

         assign     LEDR= SW;//show which SW moved

         assign       LEDG={4'b000,rWR,!KEY[3],!KEY[2],!KEY[1],!KEY[0]};//show which key pressed

        

         //display the 16-bit data saved in the assigned address(SW)

         assign       HEX0= set_HEX({1'b0,hdata[3:0]});

         assign       HEX1= set_HEX({1'b0,hdata[7:4]});

         assign       HEX2= set_HEX({1'b0,hdata[11:8]});

         assign       HEX3= set_HEX({1'b0,hdata[15:12]});

         assign       HEX4= set_HEX({1'b0,hdata[3:0]});

         assign       HEX5= set_HEX({1'b0,hdata[7:4]});

         assign       HEX6= set_HEX({1'b0,hdata[11:8]});

         assign       HEX7= set_HEX({1'b0,hdata[15:12]});

 

         //table of HEX

         function [6:0] set_HEX;

                   input [4:0] num;

                   begin

                            case(num)

                                     5'b00000: set_HEX = 7'b100_0000; //0

                                     5'b00001: set_HEX = 7'b111_1001; //1

                                     5'b00010: set_HEX = 7'b010_0100; //2

                                     5'b00011: set_HEX = 7'b011_0000; //3

                                     5'b00100: set_HEX = 7'b001_1001; //4

                                     5'b00101: set_HEX = 7'b001_0010; //5

                                     5'b00110: set_HEX = 7'b000_0010; //6

                                     5'b00111: set_HEX = 7'b111_1000; //7

                                     5'b01000: set_HEX = 7'b000_0000; //8

                                     5'b01001: set_HEX = 7'b001_1000; //9

                                     5'b01010: set_HEX = 7'b000_1000; //A

                                     5'b01011: set_HEX = 7'b000_0011; //B

                                     5'b01100: set_HEX = 7'b100_0110; //C

                                     5'b01101: set_HEX = 7'b010_0001; //D

                                     5'b01110: set_HEX = 7'b000_0110; //E

                                     5'b01111: set_HEX = 7'b000_1110; //F

                                     default:  set_HEX = 7'b111_1111; //default

                            endcase

                   end

         endfunction

endmodule

你可能感兴趣的:(实现)