【python脚本】ICer的脚本入门训练——gen_tc

简介: 【python脚本】ICer的脚本入门训练——gen_tc

前言

【python脚本】ICer的脚本入门训练——svn_back

上一篇博客的目的,是通过处理固定流程的事物来体现脚本的必要性。而后这篇博客的目的,是熟悉脚本里的一些基本的处理思路。

gen_tc是一个芯片前端验证很常见的脚本,作用是:

1.根据已有的tc生成新的tc文件;

2.修改内部关键字;

3.输出文件;

在这个过程中,我们需要涉及到的处理包括:吃命令行,遍历输入文件,正则匹配与替换,文件输出等过程,作为我第一个学习的脚本,几十行的内容简直最合适作为入门训练。

要求

假定目前我们有一个case,文件名为:sanity_case.sv,内容就是个普普通通的case如下:

1. `ifndef SANITY_CASE_SV
2. `define SANITY_CASE_SV
3. 
4. class sanity_case_seq extends my_sequence;
5. 
6.  extern function new(string name = "sanity_case_seq");
7.  extern virtual task body();
8. 
9.  `uvm_object_utils(sanity_case_seq)
10. endclass: sanity_case_seq
11. 
12. function sanity_case_seq::new(string name = "sanity_case_seq");
13.   super.new(name);
14. endfunction: new
15. 
16. task sanity_case_seq::body();
17.   repeat(10000) begin
18.     `uvm_do_with(my_tr, {my_tr.par_err == 0;})
19.   end
20.   #100;
21. endtask: body
22. 
23. class sanity_case extends base_test;
24. 
25.   extern function new(string name = "base_test", uvm_component parent=null);
26.   extern virtual function void build_phase(uvm_phase phase);
27. 
28.   `uvm_component_utils(sanity_case)
29. endclass: sanity_case
30. 
31. function sanity_case::new(string name = "base_test", uvm_component parent=null);
32.     super.new(name, parent);
33. endfunction: new
34. 
35. function void sanity_case::build_phase(uvm_phase phase);
36.   super.build_phase(phase);
37.   uvm_config_db #(uvm_object_wrapper)::set(
38.     this,
39.     "env.i_agt0.sqr.main_phase",
40.     "default_sequence",
41.     sanity_case_seq::type_id::get()
42.   );
43.     uvm_config_db #(uvm_object_wrapper)::set(
44.     this,
45.     "env.i_agt1.sqr.main_phase",
46.     "default_sequence",
47.     sanity_case_seq::type_id::get()
48.   );
49. 
50. endfunction: build_phase
51. 
52. `endif

那么我们要做的就是,编写一个脚本 gen_tc,在当前目录执行gen_tc sanity_case.v new_case.v之后,在当前目录生成新的文件new_case.v。

实操

1.新建文件gen_tc

键入以下内容作为初始:

之后修改文件属性为可执行属性chmod a+x gen_tc,然后你就会发现你的脚本绿了:

敲一下,确认可执行,然后继续下一步:

2.读取命令参数

gen_tc脚本要吃两个参数,一般处理参数有两种常用的方式:sys.argv数组和argparse库。使用argparse的典型方式,如下面的代码,具体功能我们不做探究:

1. import argparse
2. def input_args_proc():
3.     parser = argparse.ArgumentParser(description="argparse info")
4.     parser.add_argument('-o', action='store_true', default=False, help='open this script')
5.     result = parser.parse_args()
6.     if result.o == True:
7.         os.system("gvim %s" % __file__)
8.         sys.exit(0)

gen_tc的输入参数情况比较简单,两个参数必须输入,因此不需要使用argparse,直接使用sys.argv数组即可。比如目前的输入获取方式:

1. def input_sys():
2.     if len(sys.argv) > 2:
3.         from_tc = sys.argv[1]
4.         to_tc = sys.argv[2]
5.     else:
6.         print("Input error")
7.         sys.exit(0)
8.     return from_tc, to_tc

sys.argv[0]不要使用,那是脚本自身名称。在main函数中接受该函数的返回值,读取输入参数的操作就完成了。

from_tc, to_tc = input_sys()

3.读取并修改参考tc

可以通过以下的形式形式来读取文件:

1. def modify_tc(file):
2.     with open(file, "r") as handle:
3.         hd = handle.readlines()
4.         for line in hd:
5.             line = line.strip("\n")
6.             print(line)

读取文件后,在没一行内匹配“sanity_case”或“SANITY_CASE”关键字,并将其替换为“new_case”和“NEW_CASE”,而后将字符串暂存于数组中,作为函数返回值:

1. def modify_tc(frm, to):
2.     frm_key = re.sub("\.sv","",frm) #得到sanity_case.sv里的sanity_case
3.     frm_uc = frm_key.upper() #纯小写
4.     frm_lc = frm_key.lower() #纯大写,执行的时候把这块注释删了
5. 
6.     to_key  = re.sub("\.sv","",to)
7.     to_uc = to_key.upper()
8.     to_lc = to_key.lower()
9. 
10.     out_file = []
11.     with open(frm, "r") as handle:
12.         hd = handle.readlines()
13.         for line in hd:
14.             line = line.strip("\n")
15.             line = re.sub(frm_uc, to_uc, line)
16.             line = re.sub(frm_lc, to_lc, line)
17.             out_file.append(line)
18.     return out_file

main函数中接收返回值:

out_file = modify_tc(from_tc, to_tc)

4.输出文件

输出文件的函数比较固定:

1. def write_list(lst, out):
2.     with open(out, "w") as handle:
3.         for line in lst:
4.             handle.write(line+"\n")

在main中把out_file和to_tc作为参数传给该函数即可:

write_list(out_file, to_tc)

5.执行脚本

代码编写完成后,执行脚本,打开文件new_case.sv:

1. `ifndef NEW_CASE_SV
2. `define NEW_CASE_SV
3. 
4. class new_case_seq extends my_sequence;
5. 
6.  extern function new(string name = "new_case_seq");
7.  extern virtual task body();
8. 
9.  `uvm_object_utils(new_case_seq)
10. endclass: new_case_seq
11. 
12. function new_case_seq::new(string name = "new_case_seq");
13.   super.new(name);
14. endfunction: new
15. 
16. task new_case_seq::body();
17.   repeat(10000) begin
18.     `uvm_do_with(my_tr, {my_tr.par_err == 0;})
19.   end
20.   #100;
21. endtask: body
22. 
23. class new_case extends base_test;
24. 
25.   extern function new(string name = "base_test", uvm_component parent=null);
26.   extern virtual function void build_phase(uvm_phase phase);
27. 
28.   `uvm_component_utils(new_case)
29. endclass: new_case
30. 
31. function new_case::new(string name = "base_test", uvm_component parent=null);
32.     super.new(name, parent);
33. endfunction: new
34. 
35. function void new_case::build_phase(uvm_phase phase);
36.   super.build_phase(phase);
37.   uvm_config_db #(uvm_object_wrapper)::set(
38.     this,
39.     "env.i_agt0.sqr.main_phase",
40.     "default_sequence",
41.     new_case_seq::type_id::get()
42.   );
43.     uvm_config_db #(uvm_object_wrapper)::set(
44.     this,
45.     "env.i_agt1.sqr.main_phase",
46.     "default_sequence",
47.     new_case_seq::type_id::get()
48.   );
49. 
50. endfunction: build_phase
51. 
52. `endif


相关文章
|
8月前
|
自然语言处理 数据挖掘 Linux
python脚本入门
python脚本入门
82 2
|
人工智能 Unix Linux
Python脚本入门|学习笔记
快速学习Python脚本入门
120 0
Python脚本入门|学习笔记
|
开发者 Python
Python脚本入门-3
Python脚本入门-3
60 0
Python脚本入门-3
|
Unix Linux iOS开发
Python脚本入门-2
Python脚本入门-2
89 0
Python脚本入门-2
|
人工智能 C语言 Python
Python脚本入门-1
Python脚本入门-1
93 0
Python脚本入门-1
|
数据采集 Python 数据库
如何开始写你的第一个python脚本——简单爬虫入门!
好多朋友在入门python的时候都是以爬虫入手,而网络爬虫是近几年比较流行的概念,特别是在大数据分析热门起来以后,学习网络爬虫的人越来越多,哦对,现在叫数据挖掘了! 其实,一般的爬虫具有2个功能:取数据和存数据!好像说了句废话。
1606 0
|
关系型数据库 MySQL Python

热门文章

最新文章