首页 > Windows开发 > 详细

FPGA图像处理项目(四)--二维FFT RapidIO

时间:2014-02-18 16:12:44      阅读:868      评论:0      收藏:0      [点我收藏+]

    今天把RapidIO核已经加上,相应的target user代码也已经完成,最后把VxWorks上的代码也进行了相应的调整,整个项目算是大功告成了。最后写一个简要的文档把RapidIO与Vxworks中关键的地方进行下描述以便以后查找起来理解起来也比较方便。


1. 从FLASH中加载bit文件。xxx_fpga_update_v51(g_len, g_recv_buf);

2. 判断文件大小,超过8MB为全bit;小于8MB为部分bit,并要使能部分重配置。Loacl_bus_write32(CS2_BASE, 0x38, 0x3);//可重构部分加载设置

3.重置整个系统,使得系统在一个明确的状态。hwa_dbell_send(1, 0x8000); //可重构部分使能  cpu_reset_n<= treq_db_info[0];

    RapidIO--target user.v    

4.开始执行FFT运算,传入待处理数据,首先判断是多少点FFT运算。Loacl_bus_read32(RAPIDIO_BASE, 0x8004, &tempVal);

5.根据第4步的判断来传入相应数据。hwa_srio_dma_send(0, (UINT32) buf, (UINT32) destptr, NUM); 

   localparam LAD_LOW  = 24‘h00_0000 >> 3;
   localparam LAD_HIGH = 24‘h00_7FFC >> 3;
   localparam FFT_STATUS_ADDR  = 24‘h00_8000 >>3;

6.判断FFT运算是否完成。 Loacl_bus_read32(RAPIDIO_BASE, 0x8004, &tempVal); if ((tempVal & 0x2) == 0x2)  fpga_status             <= {fft_calculate_finish , 1‘b1};

7.将处理完的数据传回。hwa_srio_dma_send(0, (UINT32) destptr, (UINT32) buf,NUM);


target user.v

///////////////////////////////////////////////////////////////////////////////
//
// (c) Copyright 2005 - 2011 Xilinx, Inc. All rights reserved.
//
// This file contains confidential and proprietary information
// of Xilinx, Inc. and is protected under U.S. and
// international copyright and other intellectual property
// laws.
//     
// DISCLAIMER
// This disclaimer is not a license and does not grant any
// rights to the materials distributed herewith. Except as
// otherwise provided in a valid license issued to you by
// Xilinx, and to the maximum extent permitted by applicable
// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
// (2) Xilinx shall not be liable (whether in contract or tort,
// including negligence, or under any other theory of
// liability) for any loss or damage of any kind or nature
// related to, arising under or in connection with these
// materials, including for any direct, or any indirect,
// special, incidental, or consequential loss or damage
// (including loss of data, profits, goodwill, or any type of
// loss or damage suffered as a result of any action brought
// by a third party) even if such damage or loss was
// reasonably foreseeable or Xilinx had been advised of the
// possibility of the same.
// 
// CRITICAL APPLICATIONS
// Xilinx products are not designed or intended to be fail-
// safe, or for use in any application requiring fail-safe
// performance, such as life-support or safety devices or
// systems, Class III medical devices, nuclear facilities,
// applications related to the deployment of airbags, or any
// other applications that could lead to death, personal
// injury, or severe property or environmental damage
// (individually and collectively, "Critical
// Applications"). Customer assumes the sole risk and
// liability of any use of Xilinx products in Critical
// Applications, subject only to applicable laws and
// regulations governing limitations on product liability.
// 
// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
// PART OF THIS FILE AT ALL TIMES.

///////////////////////////////////////////////////////////////////////////////
//
// File name:     target_user.v
// Rev:           5.6
// Description:   Target User Engine
//
///////////////////////////////////////////////////////////////////////////////

`timescale 1 ps / 1 ps

module target_user #( parameter TCQ = 100 )(
             // System Inputs
             sys_clk,
             lnk_reset_n,

             // Target Response
             tresp_prio_o,
             tresp_ftype_o,
             tresp_dest_id_o,
             tresp_ttype_o,
             tresp_status_o,
             tresp_tid_o,
             tresp_data_o,
             tresp_sof_n_o,
             tresp_eof_n_o,
             tresp_vld_n_o,
             tresp_dsc_n_o,
             tresp_rdy_n_i,
             tresp_stalls,
             tresp_msg_seg,
             tresp_mbox,
             tresp_letter,

             // Target Request
             treq_prio_i,
             treq_ftype_i,
             treq_dest_id_i,
             treq_src_id_i,
             treq_tid_i,
             treq_ttype_i,
             treq_addr_i,
             treq_byte_en_n_i,
             treq_byte_count_i,
             treq_data_i,
             treq_sof_n_i,
             treq_eof_n_i,
             treq_vld_n_i,
             treq_rdy_n_o,
             treq_db_info,
             treq_msg_len,
             treq_msg_seg,
             treq_mbox,
             treq_letter
	     srio_wr_en,
	     srio_rd_en,
	     
	     srio_wr_data,
	     srio_rd_data,
	     
	     fft2_calc_finish,
	     cpu_reset_n
             );

  // System Interface

   input sys_clk;
   input lnk_reset_n;

  // Target Request Interface
  // Data signals to application interface
   input [0:1]  treq_prio_i;
   input [0:3]  treq_ftype_i;
   input [0:7]  treq_dest_id_i;
   input [0:7]  treq_src_id_i;
   input [0:7]  treq_tid_i;
   input [0:3]  treq_ttype_i;
   input [0:33] treq_addr_i;   /**/
   input [0:7]  treq_byte_en_n_i;
   input [0:8]  treq_byte_count_i;
   input [0:63] treq_data_i;

  // Target Req control signals
   input        treq_sof_n_i;
   input        treq_eof_n_i;
   input        treq_vld_n_i;
   output       treq_rdy_n_o;

  // Target Response Interface
  // Data signals to application interface
   input [0:15] treq_db_info;
   input [0:3]  treq_msg_len;
   input [0:3]  treq_msg_seg;
   input [0:5]  treq_mbox;
   input [0:1]  treq_letter;

   output [0:1] tresp_prio_o;
   output [0:3] tresp_ftype_o;
   output [0:7] tresp_dest_id_o;
   output [0:3] tresp_ttype_o;
   output [0:3] tresp_status_o;
   output [0:7] tresp_tid_o;
   output [0:63] tresp_data_o;
   output [0:3] tresp_msg_seg;
   output [0:1] tresp_mbox;
   output [0:1] tresp_letter;

  // Target Response control signals
   output        tresp_sof_n_o;
   output        tresp_eof_n_o;
   output        tresp_vld_n_o;
   output        tresp_dsc_n_o;
   input         tresp_rdy_n_i;
   input  [0:1]  tresp_stalls;

     /*user*/
     output	   	srio_wr_en,
     output	   	srio_rd_en,
     output   [63:0]    srio_wr_data,
     output   [63:0]    srio_rd_data,
     input  		fft2_calc_finish,
     output             cpu_reset_n
   // Register and Wire declarations

   // Target Response

   reg [0:3]     tresp_ttype_o;
   reg [0:3]     tresp_status_o;
   reg           tresp_sof_n_o;
   reg           tresp_eof_n_o;
   wire          tresp_vld_n_o;
   reg           tresp_rdy_q_n;
   reg           tresp_sof_q_n;
   wire          tresp_dsc_n_o;
   wire [0:63]   tresp_data_o; /*发回数据到主控*/

   // Target Request

   reg [0:1]     treq_prio_q;
   reg [0:3]     treq_ftype_q;
   reg [0:7]     treq_src_id_q;
   reg [0:7]     treq_tid_q;
   reg [0:3]     treq_ttype_q;
   reg [0:63]    treq_data_q; /*接收主控发来的数据*/
   reg           treq_eof_q_n;
   wire          treq_rdy_n_o;

   reg [0:1]     treq_letter_q;
   reg [0:3]     treq_msg_seg_q;
   reg [0:1]     treq_mbox_q;

   // Additional Wire and Registers
   reg [0:63]    size;
   reg [0:21]    local_address;
   reg [0:5]     dword_count;
   reg [0:10]    state;
   reg [0:10]    next_state;
   reg [0:63]    shadow_do;
   reg [0:63]    next_do;
   reg           first_valid; 
   reg           init_addr_in_range, next_addr_in_range;

   wire          tu_error; //target user error
   wire          bram_select;
   wire          rd_en;
   wire          wr_en;
   wire          size_reg_sel;
   wire [0:63]   bram_do;

   reg   [0:1]   stall_cnt;
   wire          stall;
   reg           tresp_vld_n;
   reg           tresp_vld_q_n_o;

	reg	[31:0]	 fpga_status  ;
	reg		 cpu_rd_status;
	wire		 cpu_reset;
   // Supported address range
   // Get rid of the three MSBs
   localparam LAD_LOW  = 24‘h00_0000 >> 3;
   localparam LAD_HIGH = 24‘h00_7FFC >> 3;
   localparam FFT_STATUS_ADDR  = 24‘h00_8000 >>3;

   // State Machine States
   `define IDLE          11‘h100
   `define WRITE         11‘h080
   `define DB_MSG        11‘h200
   `define READ_DECODE   11‘h040
   `define READ_SOF      11‘h020
   `define READ_NORMAL   11‘h010
   `define READ_EOF      11‘h008
   `define READ_SINGLE   11‘h004
   `define READ_PAUSE    11‘h002
   `define WRITE_RESP    11‘h001
   `define DB_MSG_RESP   11‘h400

 // Misc

   assign        tu_error = 1‘b0;

   assign    srio_rd_en			=  bram_select & rd_en;
   assign    srio_wr_en			=  bram_select & wr_en;
   
   assign    srio_wr_data               =  treq_data_q;
   
   assign    bram_do 			=  cpu_rd_status  ? fpga_status : ram_rd_data;
   
   assign    cpu_reset  		= ~cpu_reset_n;
   
   always @(posedge sys_clk or negedge lnk_reset_n)
           if(~lnk_reset_n)
	        cpu_reset_n	<= 0;
	   else
	   
	        if(first_valid & ((treq_ftype_i==4‘hA) | (treq_ftype_i==4‘hB)))	
		             cpu_reset_n                <=  treq_db_info[0];  //向设备1写0x8000(16位),重置
	        else
		             cpu_reset_n                <=  cpu_reset_n;
 
   always @(posedge sys_clk)
           if(cpu_reset)
                fpga_status             <= 0;
	   else
	        fpga_status             <= {fft_calculate_finish , 1‘b1};
		
   always @(posedge sys_clk)
           if(first_valid & (local_address == FFT_STATUS_ADDR))
	                 cpu_rd_status        <= 1;
	   else
	                 cpu_rd_status        <= 0;
   //===========================================================================
   // SECTION:     BlockRAM  Implementation
   // OPERATION:   BlockRAM to store the incoming data or read data from
   //              for Read requests.
   //===========================================================================
/*
  RAMB36SDP ram (
    .DO        (bram_do[0:63]),
    .DOP       (),
    .WRADDR    (local_address[13:21]),
    .RDADDR    (local_address[13:21]),
    .WRCLK     (sys_clk),
    .RDCLK     (sys_clk),
    .DI        (treq_data_q[0:63]),
    .DIP       (8‘h0),
    .RDEN      (bram_select),
    .SSR       (!lnk_reset_n),
    .WE        (8‘hFF),
    .WREN      (wr_en),
    .DBITERR   (),
    .ECCPARITY (),
    .SBITERR   (),
    .REGCE     ()
  );

*/

   //==============================================================================
   // SECTION:     SIZE REGISTER Implementation
   // OPERATION:   Size Register that contains the size of the memory space.
   //              This is located at address 24‘h10_2008.
   //==============================================================================


   // This register contains the size of the memory space
   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
        if (!lnk_reset_n)
          size <= #TCQ 64‘h0000_0000_0010_0000;
        else if (size_reg_sel & wr_en)
          begin
             if (!treq_byte_en_n_i[4])
               size[32:39] <= #TCQ treq_data_q[32:39];
             if (!treq_byte_en_n_i[5])
               size[40:47] <= #TCQ treq_data_q[40:47];
             if (!treq_byte_en_n_i[6])
               size[48:55] <= #TCQ treq_data_q[48:55];
             if (!treq_byte_en_n_i[7])
               size[56:63] <= #TCQ treq_data_q[56:63];
          end
     end

   // Determine if read or write is to the Size Register
   assign   size_reg_sel = (local_address == (24‘h10_2008 >> 3));

   //==============================================================================
   // SECTION:     TARGET REQUEST PORT Interface
   // OPERATION:   Interface to the Target Request port when incoming
   //              Read and Write packets.
   //==============================================================================

   // Register signals for easier timing
   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
        if (!lnk_reset_n)
          begin
             treq_prio_q   <= #TCQ 2‘b0;
             treq_ftype_q  <= #TCQ 4‘b0;
             treq_ttype_q  <= #TCQ 4‘h0;
             treq_src_id_q  <= #TCQ 8‘h0;
             treq_tid_q     <= #TCQ 8‘h0;
             treq_data_q    <= #TCQ 64‘h0;
             treq_letter_q  <= #TCQ 2‘h0;
             treq_msg_seg_q <= #TCQ 4‘h0;
             treq_mbox_q    <= #TCQ 2‘b00;

             treq_eof_q_n  <= #TCQ 1‘b1;
          end
        else if (!treq_vld_n_i & !treq_rdy_n_o)
          begin
             if (!treq_sof_n_i)
               begin
                  treq_prio_q    <= #TCQ treq_prio_i  ;
                  treq_ftype_q   <= #TCQ treq_ftype_i ;
                  treq_ttype_q   <= #TCQ treq_ttype_i ;
                  treq_src_id_q  <= #TCQ treq_src_id_i;
                  treq_tid_q     <= #TCQ treq_tid_i   ;
                  treq_letter_q  <= #TCQ treq_letter;
                  treq_msg_seg_q <= #TCQ treq_msg_seg;
                  treq_mbox_q    <= #TCQ treq_mbox[4:5];
               end
             treq_data_q   <= #TCQ treq_data_i;
             treq_eof_q_n  <= #TCQ treq_eof_n_i;
          end
     end

   // Packets may be received when in the idle state or when they are writes
   // Only accept data transfers in the WRITE or MSG states while in the middle of a
   // packet transfer
   assign treq_rdy_n_o = ~(state[2] | ((state[3] | state[1]) & treq_eof_q_n));

   // Capture the Dword size to be used in the state machine
   // This register contains the number of dwords to read or write
   // from the read or write command
   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
        if (!lnk_reset_n)
          dword_count <= #TCQ 6‘h0;
        // Load the number of dwords to be transferred
        else if (rd_en & dword_count == 0)
          dword_count <= #TCQ 6‘h0;
        else if (!treq_sof_n_i & !treq_vld_n_i & !treq_rdy_n_o)
          dword_count <= #TCQ treq_byte_count_i[0:5];
        // One less everytime a dword is transferred
        else if (wr_en | rd_en)
          dword_count <= #TCQ dword_count - 1‘b1;
     end
   
   // stall on the tresp interface when given some number of cycles to stall
   // from the vio interface
   always@(posedge sys_clk or negedge lnk_reset_n)
    if (~lnk_reset_n)
      stall_cnt <= #TCQ 2‘b0;
    else if (stall_cnt == 0)
      stall_cnt <= #TCQ tresp_stalls;
    else if (~tresp_vld_n)
      stall_cnt <= #TCQ stall_cnt - 1‘b1;

   assign stall = |stall_cnt;

   assign tresp_vld_n_o = tresp_vld_n | stall; 
   
   //==============================================================================
   // SECTION:     TREQ/TRESP State Machine
   // OPERATION:   The following state machine controls the acceptance of
   //              packets on the TREQ port and intiates RESPONSE packets on
   //              the Target Response Port.
   //==============================================================================
   always @(state or treq_sof_n_i or treq_vld_n_i or treq_rdy_n_o
            or treq_ftype_i or treq_eof_q_n or dword_count or treq_ttype_q
            or tresp_rdy_n_i or treq_ftype_q or tresp_vld_n_o)
     begin
        case (state)

          // State:       IDLE
          // Purpose:     Decode incoming transfers on TREQ port as
          //              read or write.
          `IDLE:
           begin
               if (!treq_sof_n_i & !treq_vld_n_i & !treq_rdy_n_o &
                   ((treq_ftype_i == 4‘h5) | (treq_ftype_i == 4‘h6)))
                 next_state = `WRITE;
               else if (!treq_sof_n_i & !treq_vld_n_i & !treq_rdy_n_o &
                        ((treq_ftype_i == 4‘hA) | (treq_ftype_i == 4‘hB)))
                 next_state = `DB_MSG;
               else if (!treq_sof_n_i & !treq_vld_n_i & !treq_rdy_n_o &
                        (treq_ftype_i == 4‘h2))
                 next_state = `READ_DECODE;
               else
                 next_state = `IDLE;
            end

          // State:       WRITE
          // Purpose:     Determine if packet ending or middle of packet.
          `WRITE:
            begin
               if ((!treq_eof_q_n) & (treq_ftype_q == 4‘h5) & (treq_ttype_q == 4‘h5))
                 next_state = `WRITE_RESP;
               else if (!treq_eof_q_n)
                 next_state = `IDLE;
               else
                 next_state = `WRITE;
            end

          //State:        DB_MSG
          // Purpose:     Determine if pkt ending or middle of packet.
          `DB_MSG:
            begin
               if ((!treq_eof_q_n) & ((treq_ftype_q == 4‘hA) | (treq_ftype_q == 4‘hB)))
                 next_state = `DB_MSG_RESP;
               else if (!treq_eof_q_n)
                 next_state = `IDLE;
               else
                 next_state = `DB_MSG;
            end

          // State:       READ_DECODE
          // Purpose:     Verify Ttype indicates a Read
          `READ_DECODE:
            begin
                if (treq_ttype_q != 4‘h4)
                  next_state = `READ_SINGLE;
                else if (dword_count == 6‘h1)
                  next_state = `READ_SINGLE;
                else
                  next_state = `READ_SOF;
            end

          // State:       READ_SOF
          // Purpose:     Determine length of Read and transition to
          //              correct space based on length.
          `READ_SOF:
            begin
               if ((!tresp_rdy_n_i & !tresp_vld_n_o) & (dword_count == 6‘h1))
                 next_state = `READ_EOF;
               else if (!tresp_rdy_n_i & !tresp_vld_n_o)
                 next_state = `READ_NORMAL;
               else
                 next_state = `READ_SOF;
            end

          // State:       READ_NORMAL
          // Purpose:     Read Data from Buffer, if tresp pause or one dword remaining,
          //              transition to next state.
          `READ_NORMAL:
            begin
               if (tresp_rdy_n_i)
                 next_state = `READ_PAUSE;
               else if ((dword_count == 6‘h1))
                 next_state = `READ_EOF;
               else
                 next_state = `READ_NORMAL;
            end

          // State:       READ_PAUSE
          // Purpose:     Pause reading data. If reading resumes transition to next
          //              state depending on if there is one dword or multiple dwords
          //              remaining left to read.
          //              transition to next state.
          `READ_PAUSE:
            begin
               if ((!tresp_rdy_n_i & !tresp_vld_n_o) & (dword_count == 1))
                 next_state = `READ_EOF;
               else if (!tresp_rdy_n_i & !tresp_vld_n_o)
                 next_state = `READ_NORMAL;
               else
                 next_state = `READ_PAUSE;
            end


          // State:       READ_EOF
          // Purpose:     Complete transmission of data on tresp port.
          //              Transition to next state based on new packets being
          //              received or tresp pause.
          `READ_EOF:
            begin
               if (!tresp_rdy_n_i & !tresp_vld_n_o)
                 next_state = `IDLE;
               else
                 next_state = `READ_EOF;
            end

          // State:       READ_SINGLE
          // Purpose:     Complete transmission of single dword read and
          //              transition back to IDLE or READ_SINGLE_P
          `READ_SINGLE:
            begin
               if (!tresp_rdy_n_i & !tresp_vld_n_o)
                 next_state = `IDLE;
               else
                 next_state = `READ_SINGLE;
            end

          // State:       WRITE_RESP
          // Purpose:     Generate Response packet on TRESP port for
          //              completed write transactions
         `WRITE_RESP:
            begin
               if (!tresp_rdy_n_i & !tresp_vld_n_o)
                 next_state = `IDLE;
               else
                 next_state = `WRITE_RESP;
            end

          // State:      DB_MSG_RESP
          // Purpose:    Generate Response packet on TRESP port for
          //             completed write transactions
          `DB_MSG_RESP:
            begin
               if (!tresp_rdy_n_i & !tresp_vld_n_o)
                 next_state = `IDLE;
               else
                 next_state = `DB_MSG_RESP;
              end
           default: 
            next_state = `IDLE;
        endcase
     end

   // State machine register
   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
        if (!lnk_reset_n)
          state <= #TCQ `IDLE;
        else
          state <= #TCQ next_state;
     end

   //==============================================================================
   // SECTION:     BLOCK RAM DATA READ and WRITE LOGIC
   // OPERATION:   The following logic enables reads and writes from/to the
   //              BlockRam based on the TREQ/TRESP state machine.
   //==============================================================================

   // Read enable logic
   assign   rd_en =  ((state == `READ_DECODE) |
                      ((!tresp_rdy_n_i & !tresp_vld_n_o) & ((state == `READ_SOF) |
                                         (state == `READ_NORMAL) |
                                         (state == `READ_PAUSE))));

   // Write enable logic
   assign   wr_en = (state == `WRITE);

   // This register captures the local address during
   // Any request transaction on the TREQ port.
   // The address is incremented for multi dword writes
   // or reads transactions.
   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
        if (!lnk_reset_n)
          local_address <= #TCQ 21‘h0;
        else if (!treq_sof_n_i & !treq_vld_n_i & !treq_rdy_n_o)
          local_address <= #TCQ treq_addr_i[9:30];
        else if (rd_en | wr_en)
          local_address <= #TCQ local_address + 1‘b1;
     end

   // BlockRAM enable logic.  Select the appropriate
   // BlockRAM based on the value of the local address.
   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
       if (!lnk_reset_n) begin
          init_addr_in_range <= #TCQ 1‘b0;
          next_addr_in_range <= #TCQ 1‘b0;
       end else begin
          init_addr_in_range <= #TCQ (treq_addr_i[9:30] >= LAD_LOW) &
                                     (treq_addr_i[9:30] <= LAD_HIGH);
          next_addr_in_range <= #TCQ ((local_address+1‘b1) >= LAD_LOW) &
                                     ((local_address+1‘b1) <= LAD_HIGH);
       end
     end

   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
        if (!lnk_reset_n)
          first_valid <= #TCQ 1‘b0;
        else
          first_valid <= #TCQ !treq_sof_n_i & !treq_vld_n_i & !treq_rdy_n_o;
     end

   assign bram_select = first_valid ? init_addr_in_range :
                        ((rd_en | wr_en)  & next_addr_in_range);

 // Registered version for rising/falling edge
  always @(posedge sys_clk or negedge lnk_reset_n)
    begin
      if (!lnk_reset_n)
        tresp_rdy_q_n <= #TCQ 1‘b1;
      else
        tresp_rdy_q_n <= #TCQ tresp_rdy_n_i;
    end


 // Registered version for rising/falling edge
  always @(posedge sys_clk or negedge lnk_reset_n)
    begin
      if (!lnk_reset_n)
        tresp_sof_q_n <= #TCQ 1‘b1;
      else
        tresp_sof_q_n <= #TCQ tresp_sof_n_o;
    end


 // Registered version for rising/falling edge
  always @(posedge sys_clk or negedge lnk_reset_n)
    begin
      if (!lnk_reset_n)
        tresp_vld_q_n_o <= #TCQ 1‘b1;
      else
        tresp_vld_q_n_o <= #TCQ tresp_vld_n_o;
    end

   // Create a shadow register to capture data
   // during pause states.
     always @(posedge sys_clk or negedge lnk_reset_n)
    begin
      if (!lnk_reset_n)
        shadow_do <= #TCQ 64‘h0;
      else if ((!tresp_rdy_q_n & tresp_rdy_n_i) |
               (tresp_sof_q_n & !tresp_sof_n_o) |
               (!tresp_vld_q_n_o & tresp_vld_n_o & state != `READ_PAUSE))
        shadow_do <= #TCQ bram_do;
    end

   // Select the next data to be sent on the TRESP_PATH
   // If the block Ram is selected determine if the data
   // should be sent from the shadow register or from
   // directly from the BlockRAM.
   // Shadow register will be selected when there is:
   // a. a wait state inserted in the SOF cycle
   //     (detection of this is harder than the other
   //      two conditions because the falling edge of
   //      tresp_rdy_n_i can be occur with the falling
   //      edge of SOF, which is not a true wait state
   //     condition.  Wait state would only be found
   //     if there was a falling edge of tresp_rdy_n_i
   //     and the previous cycle SOF was asserted.)
   // b. a wait state during intermediate data transfer
   // c. a wait state during an EOF cycle
   always@(*) 
     begin
        if (bram_select)
          begin
             if (((state == `READ_PAUSE) & !tresp_rdy_n_i) |
                 (state == `READ_EOF & (!tresp_rdy_n_i & tresp_rdy_q_n | 
                    (tresp_vld_q_n_o & !tresp_vld_n_o & tresp_stalls != 0))) |
                 (state == `READ_SOF & ((!tresp_rdy_n_i & tresp_rdy_q_n &
                     !tresp_sof_q_n) | (tresp_vld_q_n_o & !tresp_vld_n_o & tresp_stalls != 0))) |
                 (state == `READ_SINGLE & !tresp_rdy_n_i & tresp_rdy_q_n &
                     !tresp_sof_q_n) | 
                 (state == `READ_NORMAL & tresp_vld_q_n_o & !tresp_vld_n_o)) 
               next_do = shadow_do;
             else
               next_do = bram_do;
          end
        else if (state == `READ_EOF & !tresp_rdy_n_i & tresp_rdy_q_n)
          next_do = shadow_do;
        else if (state == `READ_EOF)
          next_do = bram_do;
        else
          next_do = bram_do;
     end

   //==============================================================================
   // SECTION:     TARGET RESPONSE SIGNAL GENERATION
   // OPERATION:   The following logic intiatiates a Response transfer on the
   //              TRESP port of the Logical Layer based on the incoming
   //              Request packet on the input TREQ port.
   //              Only NWRITE_R, NREAD and ATOMIC packets require RESPONSE packet
   //              generation. ATOMIC is currently not implmented.
   //==============================================================================

   // Response Packets have Request Priority + 1 by RapidIO Protocol Rules.
   assign tresp_prio_o = treq_prio_q + 1‘b1;
   // Response packets are FType 13
   assign tresp_ftype_o = 4‘hD;
   // Responses are returned to source of request
   assign tresp_dest_id_o = treq_src_id_q;

   // Responses must contain the correct transaction ID of the request packet
   assign tresp_tid_o = treq_tid_q;

   // Response Packets for Doorbell and Messaging should return the data from 
   // the inputed Request
   assign tresp_msg_seg = treq_msg_seg_q;
   assign tresp_mbox    = treq_mbox_q;
   assign tresp_letter  = treq_letter_q;


   // Response without Data bit
   // Set when packet response does not request
   // data such as a NWRITE_R request

   // TRESP SOF
   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
        if (!lnk_reset_n)
          tresp_sof_n_o <= #TCQ 1‘b1;
        else
             case(state)
                  `READ_DECODE: tresp_sof_n_o <= #TCQ 1‘b0;
                  `READ_SOF   : if (!tresp_rdy_n_i & !tresp_vld_n_o) tresp_sof_n_o <= #TCQ 1‘b1;
                  `READ_SINGLE: if (!tresp_rdy_n_i & !tresp_vld_n_o) tresp_sof_n_o <= #TCQ 1‘b1;
                  `WRITE      : if (!treq_eof_q_n & (treq_ftype_q == 4‘h5)
                                    & (treq_ttype_q == 4‘h5)) tresp_sof_n_o <= #TCQ 1‘b0;
                  `DB_MSG     : if (!treq_eof_q_n & ((treq_ftype_q == 4‘hA) | (treq_ftype_q == 4‘hB))) 
                                    tresp_sof_n_o <= #TCQ 1‘b0;
                  `WRITE_RESP : if (!tresp_rdy_n_i & !tresp_vld_n_o) tresp_sof_n_o <= #TCQ 1‘b1;
                  `DB_MSG_RESP: if (!tresp_rdy_n_i & !tresp_vld_n_o) tresp_sof_n_o <= #TCQ 1‘b1;
                  default:      tresp_sof_n_o <= #TCQ 1‘b1;
               endcase
     end


   // TRESP EOF
   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
        if (!lnk_reset_n)
          tresp_eof_n_o <= #TCQ 1‘b1;
        else
          case(state)
            `READ_DECODE : if ((dword_count == 6‘h1) |
                               (treq_ttype_q != 4‘h4))
                               tresp_eof_n_o <= #TCQ 1‘b0;
            `READ_SOF,
            `READ_NORMAL,
            `READ_PAUSE  : if ((!tresp_rdy_n_i) & (dword_count == 6‘h1))
                               tresp_eof_n_o <= #TCQ 1‘b0;
            `READ_EOF,
            `READ_SINGLE : if (!tresp_rdy_n_i & !tresp_vld_n_o) tresp_eof_n_o <= #TCQ 1‘b1;
            `WRITE       : if (!treq_eof_q_n & (treq_ftype_q == 4‘h5)
                               & (treq_ttype_q == 4‘h5)) tresp_eof_n_o <= #TCQ 1‘b0;
            `DB_MSG      : if (!treq_eof_q_n & ((treq_ftype_q == 4‘hA) | (treq_ftype_q == 4‘hB)))
                              tresp_eof_n_o <= #TCQ 1‘b0;
            `WRITE_RESP  : if (!tresp_rdy_n_i & !tresp_vld_n_o) tresp_eof_n_o <= #TCQ 1‘b1;
            `DB_MSG_RESP : if (!tresp_rdy_n_i & !tresp_vld_n_o) tresp_eof_n_o <= #TCQ 1‘b1;
             default     : tresp_eof_n_o <= #TCQ 1‘b1;
          endcase
     end


   // TRESP VLD
   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
        if (!lnk_reset_n)
          tresp_vld_n <= #TCQ 1‘b1;
        else
          case(state)
            `IDLE        : tresp_vld_n <= #TCQ 1‘b1;
            `READ_DECODE : tresp_vld_n <= #TCQ 1‘b0;
            `WRITE       : if (!treq_eof_q_n & (treq_ftype_q == 4‘h5)
                               & (treq_ttype_q == 4‘h5)) 
                             tresp_vld_n <= #TCQ 1‘b0;
            `DB_MSG      : if (!treq_eof_q_n & ((treq_ftype_q == 4‘hA) | (treq_ftype_q == 4‘hB)))
                              tresp_vld_n <= #TCQ 1‘b0;
            default      : tresp_vld_n <= #TCQ 1‘b0;
          endcase
     end


   // TRESP TTYPE
   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
        if (!lnk_reset_n)
          tresp_ttype_o <= #TCQ 4‘h0;
        else
          case(state)
            `READ_DECODE :
              begin
                tresp_ttype_o <= #TCQ 4‘h8;
              end
            `WRITE       : if (!treq_eof_q_n & (treq_ftype_q == 4‘h5)
                               & (treq_ttype_q == 4‘h5)) tresp_ttype_o <= #TCQ 4‘h0;
            `DB_MSG      : 
              begin
               if (!treq_eof_q_n & (treq_ftype_q == 4‘hB)) begin
                 tresp_ttype_o <= #TCQ 4‘h1;
               end
               else if (!treq_eof_q_n & (treq_ftype_q == 4‘hA)) begin
                 tresp_ttype_o <= #TCQ 4‘h0;
               end
              end
            default      : tresp_ttype_o <= #TCQ tresp_ttype_o;
          endcase
     end


   // TRESP STATUS
   always @(posedge sys_clk or negedge lnk_reset_n)
     begin
        if (!lnk_reset_n)
          tresp_status_o <= #TCQ 4‘h0;
        else
          case (state)
            `READ_DECODE :
              begin
                 if (tu_error) tresp_status_o <= #TCQ 4‘h7;
                 else tresp_status_o <= #TCQ 4‘h0;
              end
            `WRITE       : if (!treq_eof_q_n & (treq_ftype_q == 4‘h5)
                               & (treq_ttype_q == 4‘h5)) tresp_status_o <= #TCQ 4‘b0;
            `DB_MSG      : if (!treq_eof_q_n & ((treq_ftype_q == 4‘hA) | (treq_ftype_q == 4‘hB))) 
                              tresp_status_o <= #TCQ 4‘b0;
            default      : tresp_status_o <= #TCQ tresp_status_o;
          endcase
     end

   // TRESP DATA

   assign tresp_data_o = next_do;

   // TRESP DISCONNECT

   assign tresp_dsc_n_o = 1‘b1;


endmodule


Vxworks:

/*
 * device = 0 v51;
 * device = 1 v52;
 * 
 * flag = 0, 512 full
 * flag = 1  512 part
 * flag = 2  1024 full
 * flag = 3  1024 part
 * 
 * */
int HWA_main_test(int device, int flag)
{
	FILE *fp = NULL;
	char file_flag = 0;

	switch (flag)
	{
	case 0:
		fp = fopen("/tffs0/pr_test_512p.bit", "rb");
		if (fp == NULL)
		{
			printf("open /tffs0/pr_test_512p.bit file errror !\n");
			return ERROR;
		}
		else
		{
			printf("oepn /tffs0/pr_test_512p.bit file ok !\n");
		}
		break;
	case 1:
		fp
				= fopen("/tffs0/pr_test_512p_m_pr_user_m_pr_512p_partial.bit",
						"rb");
		if (fp == NULL)
		{
			printf(
					"open /tffs0/pr_test_512p_m_pr_user_m_pr_512p_partial.bit file errror !\n");
			return ERROR;
		}
		else
		{
			printf(
					"oepn /tffs0/pr_test_512p_m_pr_user_m_pr_512p_partial.bit file ok !\n");
		}
		break;
	case 2:
		fp = fopen("/tffs0/pr_test_1024p.bit", "rb");
		if (fp == NULL)
		{
			printf("open /tffs0/pr_test_1024p.bit file errror !\n");
			return ERROR;
		}
		else
		{
			printf("oepn /tffs0/pr_test_1024p.bit file ok !\n");
		}
		break;
	case 3:
		fp = fopen("/tffs0/pr_test_1024p_m_pr_user_m_pr_1024p_partial.bit", "rb");
		if (fp == NULL)
		{
			printf(
					"open /tffs0/pr_test_1024p_m_pr_user_m_pr_1024p_partial.bit file errror !\n");
			return ERROR;
		}
		else
		{
			printf(
					"oepn /tffs0/pr_test_1024p_m_pr_user_m_pr_1024p_partial.bit file ok !\n");
		}
		break;
	default:
		fp = fopen("/tffs0/pr_test_512p.bit", "rb");
		if (fp == NULL)
		{
			printf("open /tffs0/pr_test_512p.bit file errror !\n");
			return ERROR;
		}
		else
		{
			printf("oepn /tffs0/pr_test_512p.bit file ok !\n");
		}
		break;

	};

	fseek(fp, 0, SEEK_END);
	g_len = ftell(fp);

	g_recv_buf = malloc(g_len);
	if (g_recv_buf == NULL)
	{
		printf("malloc %d bytes sapce for recv data from PC error !\n", g_len);
		return ERROR;
	}
	else
	{
		printf("malloc address = 0x%x\n", g_recv_buf);
	}

	fseek(fp, 0, SEEK_SET);

	fread(g_recv_buf, 1, g_len, fp);

	if (device == 0) /* v51 */
	{
		if (g_len < g_all_file_len)
		{
			Loacl_bus_write32(CS2_BASE, 0x38, 0x3);//可重构部分加载设置
			delay(5);
			printf("part 0 \n");
		}

		hwa_fpga_update_v51(g_len, g_recv_buf);
	}
	else /* v52 */
	{
		if (g_len < g_all_file_len)
		{
			printf("part 2 \n");
			hwa_dbell_send(1, 0x0);
			delay(5);
			Loacl_bus_write32(CS2_BASE, 0x38, 0x3);//可重构部分加载设置
			delay(5);

		}

		hwa_fpga_update_v52(g_len, g_recv_buf);
	}

					
	if (flag1 == FALSE)
	{
		flag1 = TRUE;
		hwa_main();
	}

	if (g_all_file_len <= g_len)
	{
		hwa_dbell_send(1, 0x8000); //可重构部分使能
		taskDelay(1);
		fft_test7(); //fft运算
		taskDelay(1);
		//Loacl_bus_write32(CS2_BASE, 0x38, 0x1);//可重构部分加载设置
		//taskDelay(10);
	}
	else
	{
		printf("part 1 \n");
		//Loacl_bus_write32(CS2_BASE, 0x38, 0x1); //全bit加载
		//taskDelay(5);
		//hwa_dbell_send(1, 0x0); //可重构部分使能
		//taskDelay(5);
		hwa_dbell_send(1, 0x8000); //可重构部分使能
		taskDelay(5);
		fft_test7(); //fft运算
	}

	
	return OK;
}

int fft_test7(void) //ok
{
	FILE *fpI = NULL;
	FILE *fpQ = NULL;
	FILE *fp = NULL;
	FILE *fp1 = NULL;
	int temp = 0;
	int bufferI[1024];
	int bufferQ[1024];
	char tempbuf[16];
	unsigned int *destptr = (unsigned int *) (0xc6400000);
	int i = 0;
	char buf[8192];
	int tempVal = 0;
	int tempI = 0, tempQ = 0;
	int tempIVal = 0;
	int tempQVal = 0;
	int flag = 0;

	Loacl_bus_read32(RAPIDIO_BASE, 0x8004, &tempVal);
	printf("addr = 0x8004, val = %x\n", tempVal);
	if ((tempVal & 0x1) == 1) //1k
	{
		flag = 1024;
		printf("1024 point test \n");
	}
	else
	{
		if ((tempVal & 0x1) == 0) //512
		{
			flag = 512;
			printf("512 point test \n");
		}
		else
		{
			printf("FPGA status error !\n");
			return ERROR;
		}
	}

	if (flag == 1024)
	{
		fpI = fopen("/tffs0/ysi.txt", "r");
		if (fpI == NULL)
		{
			printf("open file /tffs0/ysi.txt error !\n");
			return ERROR;
		}
		else
		{
			printf("open file /tffs0/ysi.txt OK !\n");
		}

		fpQ = fopen("/tffs0/ysq.txt", "r+b");
		if (fpQ == NULL)
		{
			printf("open file ysq.txt error !\n");
			return ERROR;
		}
		else
		{
			printf("open file /tffs0/ysq.txt OK !\n");
		}

		for (i = 0; i < 1024; i++)
		{
			fgets(tempbuf, sizeof(tempbuf), fpI);
			tempIVal = convert(tempbuf);
			bufferI[i] = tempIVal;
			fgets(tempbuf, sizeof(tempbuf), fpQ);
			tempQVal = convert(tempbuf);
			bufferQ[i] = tempQVal;
		}

	}
	else
	{
		if (flag == 512)
		{
			fpI = fopen("/tffs0/ysi512.txt", "r");
			if (fpI == NULL)
			{
				printf("open file /tffs0/ysi512.txt error !\n");
				return ERROR;
			}
			else
			{
				printf("open file /tffs0/ysi512.txt OK !\n");
			}

			fpQ = fopen("/tffs0/ysq512.txt", "r+b");
			if (fpQ == NULL)
			{
				printf("open file /tffs0/ysq512.txt error !\n");
				return ERROR;
			}
			else
			{
				printf("open file /tffs0/ysq512.txt OK !\n");
			}

			for (i = 0; i < 512; i++)
			{
				fgets(tempbuf, sizeof(tempbuf), fpI);
				tempIVal = convert(tempbuf);
				bufferI[i] = tempIVal;
				fgets(tempbuf, sizeof(tempbuf), fpQ);
				tempQVal = convert(tempbuf);
				bufferQ[i] = tempQVal;
			}
		}
		else
		{
			printf("data point error !\n");
			return ERROR;
		}
	}

	fclose(fpI);
	fpI = NULL;

	fclose(fpQ);
	fpQ = NULL;

	if (flag == 1024)
	{
		for (i = 0; i < 8192; i += 8)
		{
			memcpy(&(buf[i]), &(bufferI[i / 8]), 4);
			memcpy(&(buf[i + 4]), &(bufferQ[i / 8]), 4);
		}
	}
	else
	{
		for (i = 0; i < 4096; i += 8)
		{
			memcpy(&(buf[i]), &(bufferI[i / 8]), 4);
			memcpy(&(buf[i + 4]), &(bufferQ[i / 8]), 4);
		}
	}

	Loacl_bus_read32(RAPIDIO_BASE, 0x8004, &tempVal);
	printf("addr = 0x8004, val = %x\n", tempVal);
	if ((tempVal & 0x1) == 1) //1k
	{
		hwa_srio_dma_send(0, (UINT32) buf, (UINT32) destptr, 8192);
	}
	else
	{
		if ((tempVal & 0x1) == 0) //512
		{
			hwa_srio_dma_send(0, (UINT32) buf, (UINT32) destptr, 4096);
		}
		else
		{
			printf("FPGA status error !\n");
			return ERROR;
		}
	}

	taskDelay(120);
	//semTake(rioDmaTxSem[0], WAIT_FOREVER);

	memset(buf, 0, sizeof(buf));

	taskDelay(10);

	for (;;)
	{
		Loacl_bus_read32(RAPIDIO_BASE, 0x8004, &tempVal);
		if ((tempVal & 0x2) == 0x2)
		{
			printf("fft finish tempVal = 0x%x!\n", tempVal);
			break;
		}
		else
		{
			printf(".");
			taskDelay(10);
		}
	}

	if (flag == 1024)
	{
		hwa_srio_dma_send(0, (UINT32) destptr, (UINT32) buf, 8192);
	}
	else
	{
		hwa_srio_dma_send(0, (UINT32) destptr, (UINT32) buf, 4096);
	}

	taskDelay(180);
	//semTake(rioDmaTxSem[0], WAIT_FOREVER);


	if (flag == 1024)
	{
		fp1 = fopen("temp_1024.txt", "w+");
	}
	else
	{
		fp1 = fopen("temp_512.txt", "w+");
	}

	if (flag == 1024)
	{
		for (i = 0; i < 8192; i += 8)
		{
			memset(tempbuf, 0, sizeof(tempbuf));
			memcpy(&tempVal, &(buf[i]), 4);
			sprintf(tempbuf, "%s%8.8x%s", "0x", tempVal, ",");
			fwrite(tempbuf, 1, 11, fp1);
			memset(tempbuf, 0, sizeof(tempbuf));
			memcpy(&tempVal, &(buf[i + 4]), 4);
			sprintf(tempbuf, "%s%8.8x", "0x", tempVal);
			fwrite(tempbuf, 1, 10, fp1);
			fwrite("\n", 1, 1, fp1);
		}
	}
	else
	{
		for (i = 0; i < 4096; i += 8)
		{
			memset(tempbuf, 0, sizeof(tempbuf));
			memcpy(&tempVal, &(buf[i]), 4);
			sprintf(tempbuf, "%s%8.8x%s", "0x", tempVal, ",");
			fwrite(tempbuf, 1, 11, fp1);
			memset(tempbuf, 0, sizeof(tempbuf));
			memcpy(&tempVal, &(buf[i + 4]), 4);
			sprintf(tempbuf, "%s%8.8x", "0x", tempVal);
			fwrite(tempbuf, 1, 10, fp1);
			fwrite("\n", 1, 1, fp1);
		}
	}

	fclose(fp1);
	fp1 = NULL;

	return OK;
}




FPGA图像处理项目(四)--二维FFT RapidIO

原文:http://blog.csdn.net/xz_rabbit/article/details/19407315

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!