HLS第二十七课(UG871,tcl与工程模式,typedefine, Csim)

打开vivado HLS command prompt,
首先是,切换盘符,直接键入
---->E:
切换到E盘,
然后,运行cd命令,
到需要打开工程的目录下,
---->cd E:\studyhls\lab3
然后显示目录已经更改成功,
E:\studyhls\lab3>
然后,运行
E:\studyhls\lab3>vivado_hls -f run_hls.tcl
建立工程。
然后dir命令,查看一下有哪些新建的文件夹。
可以看到,新建了一个fir_prj文件。
这时,运行
E:\studyhls\lab3>vivado_hls -p fir_prj
就可以启动这个工程的GUI了。

实际工作中,推荐使用TCL模式建工程,工程建好后,在GUI下运行工作任务。

使用tcl,总能找到对应的工程模式下的操作。

在每个solution中,都由一个script.tcl文件,这就是执行的命令的TCL记录文件。
而directives.tcl,则是保存了用于这个solution的directives的TCL记录命令。

下面分别说明各个命令:
+++++++++++++++++++++++++
open_project -reset fir_prj
在上级目录下,从.project文件,找到PRJ的对应信息,打开一个工程。

set_top fir
在工程中,project setting->synthesis->top function,点击browse,找到对应的函数,设置为TOP。

add_files fir_prj/src/fir.c
在工程中,添加source file。

add_files -tb fir_prj/tb/fir_test.c -cflags "-I ../src"
在工程中,添加TB文件,并指定source file的位置。
工程模式中,建议如果要添加path,不要加cflags,
而是在工程文件夹上,右键选择property,进入property for prj界面。
在C++ general->path and symbols中,
添加或者删除path。

add_files -tb fir_prj/tb/out.gold.dat
在工程中,添加TB文件,数据文件。

open_solution -reset "solution1"
在工程中,打开一个solution。

set_part
在工程中,solution setting中,设置part。

create_clock
在工程中,solution setting中,设置clock。

source “./fir_prj/solution3/directives.tcl”
在工程中,导入directives.tcl中的信息。

csim_design
在工程中,run csim.

csynth_design
在工程中,run synthesis。

cosim_design -tool xsim
在工程中,run cosim。

export_design -rtl verilog -format ip_catalog
在工程中,export RTL。

exit
退出

++++++++++++++++++++++++++++++++++++
在源文件编写时,需要一个头文件,这个头文件可以是和top模块同名的头文件,例如XXX.h,也可以定义为XXX_types.h。
在这里面,需要对所用到的类型进行统一的typedef。
例如fir,
首先是头文件保护宏。

#ifndef FIR_H_
#define FIR_H_
	...
#endif

然后再添加常数的实义化定义宏。

#define N	11

然后再添加类型的实义化定义。
后缀加上“_t”标识,用来表明这是一个自定义的类型。

typedef int	coef_t;
typedef int	data_t;
typedef int	acc_t;

然后是添加函数的原型定义。

void fir (
  data_t *y,
  coef_t c[N+1],
  data_t x
  );

+++++++++++++++++++++++++++++++++++
在源文件编写时,首先就是包含这个自有的头文件。

#include "fir.h"

在源文件中使用的数据类型,原则上,尽可能使用在H文件中typedef的那些数据类型。
如果希望HLS将变量实现为RAM或者ROM,应定义为数组,而且加上static关键字。

static data_t shift_reg[N];

++++++++++++++++++++++++++++++++++++
Csim时,首先是需要包含各个头文件。

#include <stdio.h>
#include <math.h>
#include "fir.h"

在Csim时,是由main作为TB来运行的。

main通常有两种写法,一种是

int main ()

无参数写法,表示TB并不需要从命令行提取参数。

另一种是

int main(int argc, char** argv)

带参数写法,表示TB需要从命令行中提取字符串参数。
例如:

in_gray = cv::imread(argv[1], 0);

使用了argv[1]这个字符串。
在工程模式下,project setting->simulation->input arguments中输入参数字符串。

++++++++++++++++++++++++++++++++++++++++
testbench中,推荐使用文件操作,
一方面用来从文件中读取数据,另一方面,写入文件后,与金样比对。

	int ret;
	FILE         *fp;
	...
	fp=fopen("out.dat","w");
	...
	for (i=0;i<=SAMPLES;i++) {
	  	if (ramp_up == 1) 
	  		signal = signal + 1;
	  	else 
	  		signal = signal - 1;

		// Execute the function with latest input
  	  	fir(&output,taps,signal);
    
	    if ((ramp_up == 1) && (signal >= 75))
	    	ramp_up = 0;
	    else if ((ramp_up == 0) && (signal <= -75))
	    	ramp_up = 1;
    	
		// Save the results.
	    fprintf(fp,"%i %d %d\n",i,signal,output);
 	}
	...
	fclose(fp);
	
	ret = system("diff -w out.dat out.gold.dat");
	if (ret) {
		fprintf(stdout, "FAIL: Output DOES NOT match the golden output\n");
     	return 1;
  	} else {
		fprintf(stdout, "PASS: The output matches the golden output!\n");
     	return 0;
  }

声明一个FP。然后打开文件,用fp作为句柄。
在一个for循环中,执行了多次test task。
每一次的test task的执行,就是一次for循环体的迭代执行。
在每一次的test task的执行体中,大致分为如下部分,
pre-process,为DUT准备所需的数据,
Call DUT,调用DUT的函数。
post-porcess,调整环境变量,为下一次迭代,发起test task做环境准备。
record result,记录下本次DUT的test task的结果。本例中,即写入输出文件。

在所有的迭代测试任务结束后,关闭文件。

然后进行result compare,判断测试结果。

这里,使用的是系统函数system,
这个函数调用系统CMD命令行,并返回CMD命令行的执行结果。
system系统函数接受一个string参数,并解析为一个CMD命令行。
返回结果如果不是0,则为ERROR,如果为0,则为SUCCESS。

++++++++++++++++++++++++++++++++++++
在源文件编写时,需要一个头文件,这个头文件可以是和top模块同名的头文件,例如XXX.h,也可以定义为XXX_types.h。
在这里面,需要对所用到的类型进行统一的typedef。
例如fir,
首先是头文件保护宏。

#ifndef FIR_H_
#define FIR_H_
	...
#endif

然后再添加常数的实义化定义宏。

#define N	11

然后再添加类型的实义化定义。
后缀加上“_t”标识,用来表明这是一个自定义的类型。

typedef int	coef_t;
typedef int	data_t;
typedef int	acc_t;

然后是添加函数的原型定义。

void fir (
  data_t *y,
  coef_t c[N+1],
  data_t x
  );

+++++++++++++++++++++++++++++++++++
在源文件编写时,首先就是包含这个自有的头文件。

#include “fir.h”
在源文件中使用的数据类型,原则上,尽可能使用在H文件中typedef的那些数据类型。
如果希望HLS将变量实现为RAM或者ROM,应定义为数组,而且加上static关键字。

static data_t shift_reg[N];

++++++++++++++++++++++++++++++++++++
Csim时,首先是需要包含各个头文件。

#include <stdio.h>
#include <math.h>
#include "fir.h"

在Csim时,是由main作为TB来运行的。

main通常有两种写法,一种是

int main ()

无参数写法,表示TB并不需要从命令行提取参数。

另一种是

int main(int argc, char** argv)

带参数写法,表示TB需要从命令行中提取字符串参数。
例如:

in_gray = cv::imread(argv[1], 0);

使用了argv[1]这个字符串。
在工程模式下,project setting->simulation->input arguments中输入参数字符串。

++++++++++++++++++++++++++++++++++++++++
testbench中,推荐使用文件操作,
一方面用来从文件中读取数据,另一方面,写入文件后,与金样比对。
例如下面的例子:
文件求差法,将输出结果迭代写入文件,最后再将文件与金样文件求差比对。

	int ret;
	FILE         *fp;
	...
	fp=fopen("out.dat","w");
	...
	for (i=0;i<=SAMPLES;i++) {
	  	if (ramp_up == 1) 
	  		signal = signal + 1;
	  	else 
	  		signal = signal - 1;

		// Execute the function with latest input
  	  	fir(&output,taps,signal);
    
	    if ((ramp_up == 1) && (signal >= 75))
	    	ramp_up = 0;
	    else if ((ramp_up == 0) && (signal <= -75))
	    	ramp_up = 1;
    	
		// Save the results.
	    fprintf(fp,"%i %d %d\n",i,signal,output);
 	}
	...
	fclose(fp);
	
	ret = system("diff -w out.dat out.gold.dat");
	if (ret) {
		fprintf(stdout, "FAIL: Output DOES NOT match the golden output\n");
     	return 1;
  	} else {
		fprintf(stdout, "PASS: The output matches the golden output!\n");
     	return 0;
  	}

声明一个FP。然后打开文件,用fp作为句柄。
在一个for循环中,执行了多次test task。
每一次的test task的执行,就是一次for循环体的迭代执行。
在每一次的test task的执行体中,大致分为如下部分,
pre-process,为DUT准备所需的数据,
Call DUT,调用DUT的函数。
post-porcess,调整环境变量,为下一次迭代,发起test task做环境准备。
record result,记录下本次DUT的test task的结果。本例中,即写入输出文件。在所有的迭代测试任务结束后,关闭文件。
result compare,判断测试结果。
这里,使用的是系统函数system,
这个函数调用系统CMD命令行,并返回CMD命令行的执行结果。
system系统函数接受一个string参数,并解析为一个CMD命令行。
返回结果如果不是0,则为ERROR,如果为0,则为SUCCESS。

+++++++++++++++++++++++++++++++++++++++++
另一种方式是,
直接变量比较。
如果不是放在一个for循环里调用DUT函数,而是只在main中调用一次DUT函数就结束,则只是进行了一次test task。
同样的,一次test task,也是分为几个部分:
pre-process,为DUT准备所需的数据,
Call DUT,调用DUT的函数。
post-porcess,调整环境变量,为下一次迭代,发起test task做环境准备。本例中,不需要这个环节。
record result,记录下本次DUT的test task的结果。本例中,即写入输出变量数组。
result compare,判断测试结果。并进行counter计数。
display score,打印显示比对结果的正确次数计分和错误次数计分。

先来看看pre-process。

for (i = 0; i < WINDOW_LEN; i++) {
      // Generate a test pattern for input to DUT
      test_data[i] = (in_data_t)((32767.0 * (double)((i % 16) - 8) / 8.0) + 0.5);
      // Calculate the coefficient value for this index
      in_data_t coeff_val = (in_data_t)(WIN_COEFF_SCALE * (0.54 -
         0.46 * cos(2.0 * M_PI * i / (double)(WINDOW_LEN - 1))));
      // Generate array of expected values -- n.b. explicit casts to avoid
      // integer promotion issues
      sw_result[i] = (out_data_t)test_data[i] * (out_data_t)coeff_val;
   }

由于测试数据时数组,所以使用了一个for循环体。
用for循环体,在每一次迭代中,生成了测试数据数组的一个元素,并生成了一个金样结果数组的一个元素。

再来看Call DUT。

	printf("Running DUT...");
	
   hamming_window(hw_result, test_data);
   
   printf("done.\n");

再来看record result。

	fp=fopen("result.dat","w");
   	printf("Testing DUT results");
  	 for (i = 0; i < WINDOW_LEN; i++) {
	  	fprintf(fp, "%d %d \n", hw_result[i],sw_result[i]);
	  
	  	printf("DUT results: Sample=%d, DUT=%d, Expected=%d\n", i, hw_result[i],sw_result[i]);
      	if (hw_result[i] != sw_result[i]) {
         	err_cnt++;
         	check_dots = 0;
         	printf("\n!!! ERROR at i = %4d - expected: %10d\tgot: %10d",
               i, sw_result[i], hw_result[i]);
      	} else { // indicate progress on console
         	if (check_dots == 0)
            	printf("\n");
         	
         	printf(".");
         	
         	if (++check_dots == 64)
            	check_dots = 0;
      }
      
   }
   fclose(fp);

由于输出结果是一个数组,所以用一个for循环来逐个处理结果数组中的每个元素。
这里,将结果记录和结果比对放在了一个for循环体中。

这里有一个常用的技巧,就是“计分板变量”。
可以设置多个不同的计分板变量,
例如err_cnt,用来对错误的比对结果进行计分,
correct_cnt,用来对正确的比对结果进行计分。

最后是display score,

	if (err_cnt) {
      	printf("!!! TEST FAILED - %d errors detected !!!\n", err_cnt);
   } 
   else
      	printf("*** Test Passed ***\n");

   // Only return 0 on success
   return err_cnt;

++++++++++++++++++++++++++++++++++++++++++++++++

猜你喜欢

转载自blog.csdn.net/weixin_42418557/article/details/120997246