FPGA图像处理项目(四)--二维FFT RapidIO
2014-02-18 14:20
274 查看
今天把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
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;
}
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
- FPGA图像处理项目(二)--FIFO FFT RAM
- FPGA图像处理项目(一)--FIFO与FFT
- FPGA设计——图像处理(阈值分割)
- ImageSharp一个专注于NetCore平台图像处理的开源项目
- ImageSharp一个专注于NetCore平台图像处理的开源项目
- 4K图像处理技术之FPGA处理流程(1)
- [项目实战派]图像处理项目硬件选型
- 深度学习FPGA实现基础知识16(图像处理中任意核卷积(matlab中conv2函数)的快速实现)
- FPGA之4K图像处理
- FPGA图像处理系列——直方图均衡
- iOS超全开源框架、项目和学习资料汇总--数据库、缓存处理、图像浏览、摄像照相视频音频篇
- 如何理解傅里叶变换和数字图像处理的二维傅里叶变换
- iOS超全开源框架、项目和学习资料汇总(4)数据库、缓存处理、图像浏览、摄像照相视频音频篇
- 图像处理项目-监控视频的行人追踪
- 基于FPGA的图像处理--基本概念导图
- 特征向量与特征值(做图像处理项目时所查)
- 一种FPGA图像处理算法的快速验证方式
- 本科写过的一些图像处理项目
- 二维小波分析对图像处理的应用(1)