新發基金的好處和壞處是什么?新基金的封閉期一般是多久?
新發基金的好處和壞處是什么?新發基金的優點:1、認購費率低:一般
2023/07/06
上節說到pyverilog有很多示例腳本,本節開始逐個分析。
(相關資料圖)
1示例腳本下載及說明
可以在github下載,這里提供百度網盤下載
解壓后可以看到如下示例腳本
unzip Pyverilog-develop.zipcd Pyverilog-develop/exampleslltotal 80-rw-r--r--. 1 3153 Jul 31 18:25 example_active_analyzer.py-rw-r--r--. 1 2996 Jul 31 18:25 example_active_range.py-rw-r--r--. 1 2227 Jul 31 18:25 example_ast_code.py-rw-r--r--. 1 1749 Jul 31 18:25 example_codegen.py-rw-r--r--. 1 3648 Jul 31 18:25 example_controlflow_analyzer.py-rw-r--r--. 1 3176 Jul 31 18:25 example_dataflow_analyzer.py-rw-r--r--. 1 3952 Jul 31 18:25 example_dataflow_codegen.py-rw-r--r--. 1 4555 Jul 31 18:25 example_graphgen.py-rw-r--r--. 1 560 Jul 31 18:25 example_identifierreplace.py-rw-r--r--. 1 508 Jul 31 18:25 example_identifiervisitor.py-rw-r--r--. 1 1549 Jul 31 18:25 example_lexer.py-rw-r--r--. 1 3199 Jul 31 18:25 example_merge.py-rw-r--r--. 1 2230 Jul 31 18:25 example_optimizer.py-rw-r--r--. 1 1599 Jul 31 18:25 example_parser.py-rw-r--r--. 1 1441 Jul 31 18:25 example_preprocessor.py-rw-r--r--. 1 4210 Jul 31 18:25 example_subset.py-rw-r--r--. 1 3138 Jul 31 18:25 example_walker.py-rw-r--r--. 1 2130 Jul 31 18:25 Makefile
2 example_preprocessor.py分析
該腳本的主要作用是預處理verilog文件,預處理verilog中的宏定義和include文件,然后輸出一個純粹的verilog文件,不再受define和include的制約,方便后續處理。
每行腳本分析如下所示:
# 這行代碼是使用絕對導入的未來語法。在Python2.x 版本中,導入模塊時,如果模塊與當前腳本的名稱沖突,Python會優先導入當前腳本。使用from __future__ import absolute_import可以確保導入模塊時,不會優先導入當前腳本。from __future__ import absolute_import#這行代碼是使用print()函數的未來語法。在Python 2.x 版本中,print是一個關鍵字而不是函數,不需要使用括號。使用from __future__ import print_function可以讓Python 2.x 版本中的print行為與Python 3.x 版本中的print()函數一致。from __future__ import print_function# 這行代碼導入了Python標準庫中的sys模塊,用于訪問與Python解釋器相關的變量和函數。import sys# 這行代碼導入了Python標準庫中的os模塊,用于與操作系統進行交互,例如文件和目錄操作。import os# 這行代碼導入了Python標準庫中的optparse模塊中的OptionParser類,用于解析命令行選項和參數。fromoptparseimportOptionParser#thenextlinecanberemovedafterinstallationsys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))# 這行代碼的作用是將腳本所在文件的父目錄添加到Python模塊搜索路徑中# os.path.abspath(__file__):__file__是Python中一個內置變量,表示當前腳本的文件名。os.path.abspath()函數用于獲取當前腳本的絕對路徑。例如,如果腳本文件位于/home/user/example.py,那么os.path.abspath(__file__)將返回/home/user/example.py# os.path.dirname():os.path.dirname()函數用于獲取路徑中的目錄部分。將上一步得到的絕對路徑傳遞給os.path.dirname()函數,將返回/home/user,即父目錄的路徑# os.path.dirname(os.path.dirname(os.path.abspath(__file__)))):通過多次調用os.path.dirname()函數,可以獲取到腳本所在文件的父目錄的父目錄# sys.path.insert(0, ...):sys.path是Python中的一個列表,包含了Python模塊搜索路徑。sys.path.insert(0, ...)將指定的路徑插入到列表的第一個位置,即將腳本所在文件的父目錄添加到Python模塊搜索路徑的最前面# 這行代碼導入了Pyverilog庫,它是一個用于解析和處理Verilog代碼的Python庫。import pyverilog# 這行代碼從Pyverilog庫的vparser.preprocessor模塊中導入了preprocess函數。preprocess函數用于對Verilog代碼進行預處理,包括宏展開、頭文件包含等操作from pyverilog.vparser.preprocessor import preprocessdef main(): INFO = "Verilog Preprocessor" # pyverilog.__version__是Pyverilog庫的版本號 VERSION = pyverilog.__version__ USAGE = "Usage: python example_preprocessor.py file ..." # 定義showVersion子函數,打印信息 def showVersion(): print(INFO) print(VERSION) print(USAGE) sys.exit() # optparser.add_option()方法用于添加選項。每個選項都是一個參數的配置,包括名稱、選項類型、目標變量、默認值和幫助信息等。具體參數解釋如下: # -v 或--version:短選項和長選項,用來顯示版本號。 # action="store_true":當選項被指定時,將目標變量設為True。 # dest="showversion":將選項的值存儲到showversion變量中。 # default=False:如果選項未被指定,則將showversion變量的默認值設為False。 # help="Show the version":選項的幫助信息。 # -I 或--include:短選項和長選項,用來指定包含路徑。 # dest="include":將選項的值存儲到include變量中。 # action="append":當選項被指定時,將選項的值追加到include變量中。 # default=[]:如果選項未被指定,則將include變量的默認值設為一個空列表。 # help="Include path":選項的幫助信息。 # -D:短選項,用來指定宏定義。 # dest="define":將選項的值存儲到define變量中。 # action="append":當選項被指定時,將選項的值追加到define變量中。# default=[]:如果選項未被指定,則將define變量的默認值設為一個空列表。# help="Macro Definition":選項的幫助信息。 optparser = OptionParser() optparser.add_option("-v", "--version", action="store_true", dest="showversion", default=False, help="Show the version") optparser.add_option("-I", "--include", dest="include", action="append", default=[], help="Include path") optparser.add_option("-D", dest="define", action="append", default=[], help="Macro Definition")# optparser.parse_args()方法用于解析命令行參數,并將解析結果賦值給options和args變量。options是一個對象,包含了解析后的選項和參數的值;args是一個列表,包含了解析后的位置參數的值。 (options, args) = optparser.parse_args() filelist = args if options.showversion: showVersion() for f in filelist: if not os.path.exists(f):# os.path.exists()函數判斷文件是否存在。如果文件不存在,則拋出一個IOError異常,并將異常消息設為"file not found: " + f,其中f是文件路徑 raise IOError("file not found: " + f)#如果filist為空,則輸出自定義子函數 if len(filelist) == 0: showVersion() # preprocess()函數是在pyverilog.vparser.preprocessor模塊中定義的,用于對Verilog文件進行預處理。它接受三個參數:# filelist:一個包含文件路徑的列表,表示需要進行預處理的文件。 # include:一個包含包含路徑的列表,用于指定預處理時的包含路徑。 # define:一個包含宏定義的列表,用于指定預處理時的宏定義。 # 該函數返回預處理后的文本,將其存儲在text變量中。 text = preprocess(filelist, include=options.include, define=options.define) print(text)# __name__是一個特殊的內置變量,表示當前模塊的名稱。當一個Python腳本直接被運行時,__name__的值為"__main__";當一個Python模塊被導入時,__name__的值為模塊的名稱。# 因此,if __name__=="__main__":這個條件判斷語句的作用是,只有當當前腳本直接被運行時,才會執行main()函數。#這樣做的好處是,可以在腳本中定義一些測試代碼或者執行一些初始化操作,而這些代碼在腳本被導入時不會執行。只有當腳本直接被運行時,才會執行這些代碼。if __name__ == "__main__": main()
該腳本的應用示例如下所示:
3 example_parser.py分析
該模塊用于分析verilog代碼,生成抽象語法樹(ATS)和指令列表(directives)。
from __future__ import absolute_importfrom __future__ import print_functionimport sysimport osfromoptparseimportOptionParser# the next line can be removed after installationsys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))import pyverilogfrom pyverilog.vparser.parser import parsedef main(): INFO = "Verilog code parser" VERSION = pyverilog.__version__ USAGE = "Usage: python example_parser.py file ..." def showVersion(): print(INFO) print(VERSION) print(USAGE) sys.exit() optparser = OptionParser() optparser.add_option("-v", "--version", action="store_true", dest="showversion", default=False, help="Show the version") optparser.add_option("-I", "--include", dest="include", action="append", default=[], help="Include path") optparser.add_option("-D", dest="define", action="append", default=[], help="Macro Definition") (options, args) = optparser.parse_args() # parse()函數是在pyverilog.vparser.parser模塊中定義的,用于解析Verilog文件。它接受三個參數: # filelist:一個包含文件路徑的列表,表示需要進行解析的文件。 # preprocess_include:一個包含包含路徑的列表,用于指定預處理時的包含路徑。 # preprocess_define:一個包含宏定義的列表,用于指定預處理時的宏定義。 # 該函數返回解析后的抽象語法樹(AST)和指令(directives),將其分別存儲在ast和directives變量中。 filelist = args if options.showversion: showVersion() for f in filelist: if not os.path.exists(f): raise IOError("file not found: " + f) if len(filelist) == 0: showVersion() # ast.show()是AST對象的一個方法,用于以可讀的形式打印出整個抽象語法樹的結構。調用ast.show()后,會將抽象語法樹的結構輸出到控制臺。 # directives是一個包含行號和指令的元組列表。通過循環遍歷directives,可以逐行打印出每個指令的行號和內容。 # 這段代碼的作用是先展示解析后的抽象語法樹的結構,然后逐行打印出每個指令的行號和內容。這樣可以更好地了解解析后的結果,并進行后續的處理或分析。 ast, directives = parse(filelist, preprocess_include=options.include, preprocess_define=options.define) ast.show() for lineno, directive in directives: print("Line %d : %s" % (lineno, directive))if __name__ == "__main__": main()
4 example_ast_code.py分析
該腳本用于構建ATS抽象樹,進而生成rtl代碼
# from __future__ import absolute_importfrom __future__ import print_functionimport sysimport os# the next line can be removed after installationsys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))# vast模塊是pyverilog庫中定義的抽象語法樹(AST)的模塊。它包含了用于構建和操作Verilog抽象語法樹的各種類和函數。# ASTCodeGenerator類是pyverilog庫中的一個代碼生成器類。它提供了將抽象語法樹(AST)轉換成為Verilog代碼的功能。#通過導入這兩個模塊和類,我們可以使用vast模塊中的類來構建Verilog抽象語法樹(AST),然后使用ASTCodeGenerator類來將AST轉換成為Verilog代碼。import pyverilog.vparser.ast as vastfrom pyverilog.ast_code_generator.codegen import ASTCodeGeneratordef main(): datawid = vast.Parameter("DATAWID", vast.Rvalue(vast.IntConst("32"))) params = vast.Paramlist([datawid]) clk = vast.Ioport(vast.Input("CLK")) rst = vast.Ioport(vast.Input("RST")) width = vast.Width(vast.IntConst("7"), vast.IntConst("0")) led= vast.Ioport(vast.Output("led", width=width)) ports = vast.Portlist([clk, rst, led]) width = vast.Width(vast.Minus(vast.Identifier("DATAWID"), vast.IntConst("1")), vast.IntConst("0")) count = vast.Reg("count", width=width) assign = vast.Assign( vast.Lvalue(vast.Identifier("led")), vast.Rvalue( vast.Partselect( vast.Identifier("count"), vast.Minus(vast.Identifier("DATAWID"), vast.IntConst("1")), vast.Minus(vast.Identifier("DATAWID"), vast.IntConst("8"))))) sens = vast.Sens(vast.Identifier("CLK"), type="posedge") senslist = vast.SensList([sens]) assign_count_true = vast.NonblockingSubstitution( vast.Lvalue(vast.Identifier("count")), vast.Rvalue(vast.IntConst("0"))) if0_true = vast.Block([assign_count_true]) # count + 1 count_plus_1 = vast.Plus(vast.Identifier("count"), vast.IntConst("1")) assign_count_false = vast.NonblockingSubstitution( vast.Lvalue(vast.Identifier("count")), vast.Rvalue(count_plus_1)) if0_false = vast.Block([assign_count_false]) if0 = vast.IfStatement(vast.Identifier("RST"), if0_true, if0_false) statement = vast.Block([if0]) always = vast.Always(senslist, statement) items = [] items.append(count) items.append(assign) items.append(always) ast = vast.ModuleDef("top", params, ports, items) codegen = ASTCodeGenerator() rslt = codegen.visit(ast) print(rslt)if __name__ == "__main__": main()
生成的verilog代碼如下所示:
module top #( parameter DATAWID = 32)( input CLK, input RST, output [7:0] led); reg [DATAWID-1:0] count; assign led = count[DATAWID-1:DATAWID-8]; always @(posedge CLK) begin if(RST) begin count <= 0; end else begin count <= count + 1; end endendmodule
話說通過ATS生成verilog確實很繁瑣,還不如直接上手寫個veirlog。
本節介紹結束。
審核編輯:湯梓紅
標簽: