1. 程式人生 > >LLVM在Windows下用opt呼叫自定義pass

LLVM在Windows下用opt呼叫自定義pass

步驟1 建立測試C程式碼

首先編寫一個測試用的C程式碼example.c,內容如下:

#include<stdio.h>

void test() {
    printf("hello\n");
}
int main(int argc, char ** argv) {
    int a = 2;
    int b = 1;
    int c = 0;

    test();
    c = a + b;
    printf("c is %d\n", c);
}

步驟2 使用clang編譯程式碼

clang -S -O0 -emit-llvm example.
c

編譯成功後會生成example.ll檔案,可以直接用文字編輯器開啟檢視。

步驟3 使用opt呼叫pass

網上的材料大多是linux下或是mac下的,Windows下略微不同,呼叫的命令如下:

opt -mypass example.ll

輸出資訊:

test
main

說明我們的pass被呼叫啦~

附:

步驟2的example.ll檔案內容:

; ModuleID = 'C:\Users\sing\Desktop\example.c'
source_filename = "C:\5CUsers\sing\5CDesktop\5Cexample.c"
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc19.12.25831" $"\01??_C@_06BGKFAKIK@hello?6?$AA@" = comdat any $"\01??_C@_08PFOKLJEB@c?5is?5?$CFd?6?$AA@" = comdat any @"\01??_C@_06BGKFAKIK@hello?6?$AA@" = linkonce_odr unnamed_addr constant [7 x i8] c"hello\0A\00"
, comdat, align 1 @"\01??_C@_08PFOKLJEB@c?5is?5?$CFd?6?$AA@" = linkonce_odr unnamed_addr constant [9 x i8] c"c is %d\0A\00", comdat, align 1 ; Function Attrs: noinline nounwind optnone uwtable define void @test() #0 { entry: %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01??_C@_06BGKFAKIK@hello?6?$AA@", i32 0, i32 0)) ret void } declare i32 @printf(i8*, ...) #1 ; Function Attrs: noinline nounwind optnone uwtable define i32 @main(i32 %argc, i8** %argv) #0 { entry: %argv.addr = alloca i8**, align 8 %argc.addr = alloca i32, align 4 %a = alloca i32, align 4 %b = alloca i32, align 4 %c = alloca i32, align 4 store i8** %argv, i8*** %argv.addr, align 8 store i32 %argc, i32* %argc.addr, align 4 store i32 2, i32* %a, align 4 store i32 1, i32* %b, align 4 store i32 0, i32* %c, align 4 call void @test() %0 = load i32, i32* %a, align 4 %1 = load i32, i32* %b, align 4 %add = add nsw i32 %0, %1 store i32 %add, i32* %c, align 4 %2 = load i32, i32* %c, align 4 %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"\01??_C@_08PFOKLJEB@c?5is?5?$CFd?6?$AA@", i32 0, i32 0), i32 %2) ret i32 0 } attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{!0, !1} !llvm.ident = !{!2} !0 = !{i32 1, !"wchar_size", i32 2} !1 = !{i32 7, !"PIC Level", i32 2} !2 = !{!"clang version 6.0.0 (tags/RELEASE_600/final)"}

是因為使用了-O0優化開關,如果不使用這個開關,使用:

clang -S -emit-llvm example.c

生成的example.ll檔案比較大:

; ModuleID = 'example.c'
source_filename = "example.c"
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc19.12.25831"

%struct.__crt_locale_pointers = type { %struct.__crt_locale_data*, %struct.__crt_multibyte_data* }
%struct.__crt_locale_data = type opaque
%struct.__crt_multibyte_data = type opaque
%struct._iobuf = type { i8* }

$sprintf = comdat any

$vsprintf = comdat any

$_snprintf = comdat any

$_vsnprintf = comdat any

$printf = comdat any

$_vsprintf_l = comdat any

$_vsnprintf_l = comdat any

$__local_stdio_printf_options = comdat any

$_vfprintf_l = comdat any

$"\01??_C@_07NNOMJDJG@hello2?6?$AA@" = comdat any

$"\01??_C@_08PFOKLJEB@c?5is?5?$CFd?6?$AA@" = comdat any

@"\01??_C@_07NNOMJDJG@hello2?6?$AA@" = linkonce_odr unnamed_addr constant [8 x i8] c"hello2\0A\00", comdat, align 1
@"\01??_C@_08PFOKLJEB@c?5is?5?$CFd?6?$AA@" = linkonce_odr unnamed_addr constant [9 x i8] c"c is %d\0A\00", comdat, align 1
@__local_stdio_printf_options._OptionsStorage = internal global i64 0, align 8

; Function Attrs: noinline nounwind optnone uwtable
define linkonce_odr i32 @sprintf(i8*, i8*, ...) #0 comdat {
  %3 = alloca i8*, align 8
  %4 = alloca i8*, align 8
  %5 = alloca i32, align 4
  %6 = alloca i8*, align 8
  store i8* %1, i8** %3, align 8
  store i8* %0, i8** %4, align 8
  %7 = bitcast i8** %6 to i8*
  call void @llvm.va_start(i8* %7)
  %8 = load i8*, i8** %6, align 8
  %9 = load i8*, i8** %3, align 8
  %10 = load i8*, i8** %4, align 8
  %11 = call i32 @_vsprintf_l(i8* %10, i8* %9, %struct.__crt_locale_pointers* null, i8* %8)
  store i32 %11, i32* %5, align 4
  %12 = bitcast i8** %6 to i8*
  call void @llvm.va_end(i8* %12)
  %13 = load i32, i32* %5, align 4
  ret i32 %13
}

; Function Attrs: noinline nounwind optnone uwtable
define linkonce_odr i32 @vsprintf(i8*, i8*, i8*) #0 comdat {
  %4 = alloca i8*, align 8
  %5 = alloca i8*, align 8
  %6 = alloca i8*, align 8
  store i8* %2, i8** %4, align 8
  store i8* %1, i8** %5, align 8
  store i8* %0, i8** %6, align 8
  %7 = load i8*, i8** %4, align 8
  %8 = load i8*, i8** %5, align 8
  %9 = load i8*, i8** %6, align 8
  %10 = call i32 @_vsnprintf_l(i8* %9, i64 -1, i8* %8, %struct.__crt_locale_pointers* null, i8* %7)
  ret i32 %10
}

; Function Attrs: noinline nounwind optnone uwtable
define linkonce_odr i32 @_snprintf(i8*, i64, i8*, ...) #0 comdat {
  %4 = alloca i8*, align 8
  %5 = alloca i64, align 8
  %6 = alloca i8*, align 8
  %7 = alloca i32, align 4
  %8 = alloca i8*, align 8
  store i8* %2, i8** %4, align 8
  store i64 %1, i64* %5, align 8
  store i8* %0, i8** %6, align 8
  %9 = bitcast i8** %8 to i8*
  call void @llvm.va_start(i8* %9)
  %10 = load i8*, i8** %8, align 8
  %11 = load i8*, i8** %4, align 8
  %12 = load i64, i64* %5, align 8
  %13 = load i8*, i8** %6, align 8
  %14 = call i32 @_vsnprintf(i8* %13, i64 %12, i8* %11, i8* %10)
  store i32 %14, i32* %7, align 4
  %15 = bitcast i8** %8 to i8*
  call void @llvm.va_end(i8* %15)
  %16 = load i32, i32* %7, align 4
  ret i32 %16
}

; Function Attrs: noinline nounwind optnone uwtable
define linkonce_odr i32 @_vsnprintf(i8*, i64, i8*, i8*) #0 comdat {
  %5 = alloca i8*, align 8
  %6 = alloca i8*, align 8
  %7 = alloca i64, align 8
  %8 = alloca i8*, align 8
  store i8* %3, i8** %5, align 8
  store i8* %2, i8** %6, align 8
  store i64 %1, i64* %7, align 8
  store i8* %0, i8** %8, align 8
  %9 = load i8*, i8** %5, align 8
  %10 = load i8*, i8** %6, align 8
  %11 = load i64, i64* %7, align 8
  %12 = load i8*, i8** %8, align 8
  %13 = call i32 @_vsnprintf_l(i8* %12, i64 %11, i8* %10, %struct.__crt_locale_pointers* null, i8* %9)
  ret i32 %13
}

; Function Attrs: noinline nounwind optnone uwtable
define void @test() #0 {
  %1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @"\01??_C@_07NNOMJDJG@hello2?6?$AA@", i32 0, i32 0))
  ret void
}

; Function Attrs: noinline nounwind optnone uwtable
define linkonce_odr i32 @printf(i8*, ...) #0 comdat {
  %2 = alloca i8*, align 8
  %3 = alloca i32, align 4
  %4 = alloca i8*, align 8
  store i8* %0, i8** %2, align 8
  %5 = bitcast i8** %4 to i8*
  call void @llvm.va_start(i8* %5)
  %6 = load i8*, i8** %4, align 8
  %7 = load i8*, i8** %2, align 8
  %8 = call %struct._iobuf* @__acrt_iob_func(i32 1)
  %9 = call i32 @_vfprintf_l(%struct._iobuf* %8, i8* %7, %struct.__crt_locale_pointers* null, i8* %6)
  store i32 %9, i32* %3, align 4
  %10 = bitcast i8** %4 to i8*
  call void @llvm.va_end(i8* %10)
  %11 = load i32, i32* %3, align 4
  ret i32 %11
}

; Function Attrs: noinline nounwind optnone uwtable
define i32 @main(i32, i8**) #0 {
  %3 = alloca i8**, align 8
  %4 = alloca i32, align 4
  %5 = alloca i32, align 4
  %6 = alloca i32, align 4
  %7 = alloca i32, align 4
  store i8** %1, i8*** %3, align 8
  store i32 %0, i32* %4, align 4
  store i32 2, i32* %5, align 4
  store i32 1, i32* %6, align 4
  store i32 0, i32* %7, align 4
  call void @test()
  %8 = load i32, i32* %5, align 4
  %9 = load i32, i32* %6, align 4
  %10 = add nsw i32 %8, %9
  store i32 %10, i32* %7, align 4
  %11 = load i32, i32* %7, align 4
  %12 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"\01??_C@_08PFOKLJEB@c?5is?5?$CFd?6?$AA@", i32 0, i32 0), i32 %11)
  ret i32 0
}

; Function Attrs: nounwind
declare void @llvm.va_start(i8*) #1

; Function Attrs: noinline nounwind optnone uwtable
define linkonce_odr i32 @_vsprintf_l(i8*, i8*, %struct.__crt_locale_pointers*, i8*) #0 comdat {
  %5 = alloca i8*, align 8
  %6 = alloca %struct.__crt_locale_pointers*, align 8
  %7 = alloca i8*, align 8
  %8 = alloca i8*, align 8
  store i8* %3, i8** %5, align 8
  store %struct.__crt_locale_pointers* %2, %struct.__crt_locale_pointers** %6, align 8
  store i8* %1, i8** %7, align 8
  store i8* %0, i8** %8, align 8
  %9 = load i8*, i8** %5, align 8
  %10 = load %struct.__crt_locale_pointers*, %struct.__crt_locale_pointers** %6, align 8
  %11 = load i8*, i8** %7, align 8
  %12 = load i8*, i8** %8, align 8
  %13 = call i32 @_vsnprintf_l(i8* %12, i64 -1, i8* %11, %struct.__crt_locale_pointers* %10, i8* %9)
  ret i32 %13
}

; Function Attrs: nounwind
declare void @llvm.va_end(i8*) #1

; Function Attrs: noinline nounwind optnone uwtable
define linkonce_odr i32 @_vsnprintf_l(i8*, i64, i8*, %struct.__crt_locale_pointers*, i8*) #0 comdat {
  %6 = alloca i8*, align 8
  %7 = alloca %struct.__crt_locale_pointers*, align 8
  %8 = alloca i8*, align 8
  %9 = alloca i64, align 8
  %10 = alloca i8*, align 8
  %11 = alloca i32, align 4
  store i8* %4, i8** %6, align 8
  store %struct.__crt_locale_pointers* %3, %struct.__crt_locale_pointers** %7, align 8
  store i8* %2, i8** %8, align 8
  store i64 %1, i64* %9, align 8
  store i8* %0, i8** %10, align 8
  %12 = load i8*, i8** %6, align 8
  %13 = load %struct.__crt_locale_pointers*, %struct.__crt_locale_pointers** %7, align 8
  %14 = load i8*, i8** %8, align 8
  %15 = load i64, i64* %9, align 8
  %16 = load i8*, i8** %10, align 8
  %17 = call i64* @__local_stdio_printf_options()
  %18 = load i64, i64* %17, align 8
  %19 = or i64 %18, 1
  %20 = call i32 @__stdio_common_vsprintf(i64 %19, i8* %16, i64 %15, i8* %14, %struct.__crt_locale_pointers* %13, i8* %12)
  store i32 %20, i32* %11, align 4
  %21 = load i32, i32* %11, align 4
  %22 = icmp slt i32 %21, 0
  br i1 %22, label %23, label %24

; <label>:23:                                     ; preds = %5
  br label %26

; <label>:24:                                     ; preds = %5
  %25 = load i32, i32* %11, align 4
  br label %26

; <label>:26:                                     ; preds = %24, %23
  %27 = phi i32 [ -1, %23 ], [ %25, %24 ]
  ret i32 %27
}

declare i32 @__stdio_common_vsprintf(i64, i8*, i64, i8*, %struct.__crt_locale_pointers*, i8*) #2

; Function Attrs: noinline nounwind optnone uwtable
define linkonce_odr i64* @__local_stdio_printf_options() #0 comdat {
  ret i64* @__local_stdio_printf_options._OptionsStorage
}

; Function Attrs: noinline nounwind optnone uwtable
define linkonce_odr i32 @_vfprintf_l(%struct._iobuf*, i8*, %struct.__crt_locale_pointers*, i8*) #0 comdat {
  %5 = alloca i8*, align 8
  %6 = alloca %struct.__crt_locale_pointers*, align 8
  %7 = alloca i8*, align 8
  %8 = alloca %struct._iobuf*, align 8
  store i8* %3, i8** %5, align 8
  store %struct.__crt_locale_pointers* %2, %struct.__crt_locale_pointers** %6, align 8
  store i8* %1, i8** %7, align 8
  store %struct._iobuf* %0, %struct._iobuf** %8, align 8
  %9 = load i8*, i8** %5, align 8
  %10 = load %struct.__crt_locale_pointers*, %struct.__crt_locale_pointers** %6, align 8
  %11 = load i8*, i8** %7, align 8
  %12 = load %struct._iobuf*, %struct._iobuf** %8, align 8
  %13 = call i64* @__local_stdio_printf_options()
  %14 = load i64, i64* %13, align 8
  %15 = call i32 @__stdio_common_vfprintf(i64 %14, %struct._iobuf* %12, i8* %11, %struct.__crt_locale_pointers* %10, i8* %9)
  ret i32 %15
}

declare %struct._iobuf* @__acrt_iob_func(i32) #2

declare i32 @__stdio_common_vfprintf(i64, %struct._iobuf*, i8*, %struct.__crt_locale_pointers*, i8*) #2

attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}

!0 = !{i32 1, !"wchar_size", i32 2}
!1 = !{i32 7, !"PIC Level", i32 2}
!2 = !{!"clang version 6.0.0 (tags/RELEASE_600/final)"}

使用opt -mypass example.ll輸出:

sprintf
vsprintf
_snprintf
_vsnprintf
test
printf
main
_vsprintf_l
_vsnprintf_l
__local_stdio_printf_options
_vfprintf_l

使用clang時開啟該pass:

clang.exe -mllvm -mypass example.c -o example.exe

相關推薦

LLVM在Windowsopt呼叫定義pass

步驟1 建立測試C程式碼 首先編寫一個測試用的C程式碼example.c,內容如下: #include<stdio.h> void test() { printf("hello\n"); } int main(int argc, c

LLVM在Windows使用VisualStudio2017新增編譯定義pass

該方法仍然有效,只不過還需要一些修改,遇到的錯誤需要解決。 錯誤1 CMake Error at CMakeLists.txt:658 (message): Unexpected failure executing llvm-build: l

Linux環境 lua 呼叫定義so動態庫(skynet)

最近看的 skynet 使用的 c+lua 的架構,框架提供的是基礎的api,所以業務邏輯還得自己去寫,如果某些業務邏輯比較耗效能,那可能就需要把某些業務邏輯丟到 c/c++ 去做,提供個介面供

儲存過程中呼叫定義函式(不在同一使用者)提示無許可權或識別符號無效

 問題描述:           在A使用者下自定了一個函式 : getName(); 然後在B使用者下建立儲存過程,呼叫了A使用者下的自定義函式getName;在編譯儲存過程時提示函式 getName無效。 解決方法:           將A使用者下自定義函式getNa

linuxSNMP的extend--定義監控

linux snmp extend snmp除了具有系統默認的監控項,還提供了一個強大的功能,可自定義監控項。在snmpd.conf配置文件中的exec選項(高版本的snmp中,extend替代了exec)提供了自定義的監控功能,可以將命令或者腳本的執行結果添加到snmp的查詢中。格式為:extend

Unity NGUI UIPanel對粒子或定義Mesh的剪裁

ngui unity uipanel 裁切 剪裁 粒子 寫在開篇: 越來越煩那些無腦轉發自己不做驗證的博主論壇樓主,網上好不容易找到一些資料,結果代碼搞下來卻是錯的,有些確實是因為版本問題太老不兼容,但是有些明顯是有問題的,轉發前自己試試就知道肯定是不能用的。結果。。。哎。。。真

如何在Windows Server 2008R2上面批量添加AD戶及定義OU批量添加

開始 disable png spl 跳過 size 不能 關閉 shadow 首先這裏我們需要找HR要到員工的信息表,越詳細越好 註:密碼不能太過於簡單,一定要符合密碼的復雜性的要求,不然會提示報錯信息 然後把修改號的表保存到C盤的根目錄下面 下面添加這些信息for /f

織夢新增超過兩百個定義欄位後在使用addfields呼叫定義欄位出錯的解決方法

dedecsm 自定義模型  新增自定義欄位(個數一百多個),使用addfields  方法呼叫,出現呼叫不出來的情況【addfields  裡面就能新增145個欄位,多了直接亂碼或者無法顯示】 解決方法 分別開啟 include/dedehtml2.class.

Hadoop完全分散式MapReduce實現定義排序、分割槽和分組

    經過前面一段時間的學習,簡單的單詞統計已經不能實現更多的需求,就連自帶的一些函式方法等也是跟不上節奏了;加上前面一篇MapReduce的底層執行步驟的瞭解,今天學習自定義的排序、分組、分割槽相對也特別容易。 認為不好理解,先參考一下前面的一篇:https://bl

在NetSuite Sublist,增加/刪除定義記錄行

NetSuite 產品群:779253701 在實施過程中,遇到一個客戶的需求:在聯絡人介面增加從業經歷,記錄其之前所在公司、起止時間、部門和職務。這要求在NetSuite的標準聯絡人記錄中,增加一個“從業經歷”的sublist,並可以增加/刪除和修改行資訊,即從業經歷條目。 在Goog

layui呼叫定義方法提示未定義的解決辦法

呼叫test()時提示未定義 layui.use(['layer', 'form', 'element'], function(){ var layer = layui.layer ,form = layui.form ,element = layui.element  &

Problem B: 指標:呼叫定義交換函式,完成5個浮點數從小到大排列

#include<stdio.h> int swap(float *p1,float *p2) { float flag; if(*p1>*p2) { flag=*p1; *p1=*p2; *p2=flag;

Problem D: 指標:呼叫定義排序函式sort,對輸入的n個數進行從小到大輸出。

#include<stdio.h> int sort(int *p,int n) { int i,j,temp; for(i=0;i<n-1;i++) for(j=i;j<n;j++) if(p[i]>p[j]) {

PHPCMS推薦位呼叫定義欄位

  第1步:成功登入到phpcms後臺。   第2步:開啟內容>>內容相關設定>>模型管理>>找到自己相對應的模型。   第3步:開啟模型找到並開啟“欄位管理”,在自己需要顯示的欄位上點選“修改”。   第4步:在最後倒數第三個”在推薦位標籤中呼叫“上選擇是並確定儲存

python呼叫定義模組方法

Python模組是一個Python檔案,以.py結尾,包括了Python物件定義和Python語句,能讓Python程式碼段更有邏輯性、更好用、更易懂,既然Python模組有這麼多好處,那麼該如何引用Python模組呢? import語句 自定義模組可以採用import語

關於nagios系統使用shell指令碼定義監控外掛的編寫以及沒有實時監控圖的問題

關於nagios系統下shell自定義監控外掛的編寫、指令碼規範以及沒有實時監控圖的問題的解決辦法 在自已編寫監控外掛之前我們首先需要對nagios監控原理有一定的瞭解 Nagios的功能是監控服務和主機,但是他自身並不包括這部分功能,所有的監控、檢測功能都是通過各種外掛來完成的。 啟動Nagios後,

sort函式呼叫定義的 swap 時的問題

自定義swap函式時,加上了測試語句 : cout<<"test swap!"<<endl; 但是在測試的時候sort似乎並沒有呼叫我寫的swap函式,cout << “test swap!” << endl; 沒有輸出出來. 原因是 當元素數目過

AOP攔截定義註解並獲取註解屬性與上下文引數(基於Springboot框架)

目錄 AOP可以用於日誌的設計,這樣話就少不了要獲取上下文的資訊,博主在設計日誌模組時考慮了一下此法,整理了一下如何用AOP來攔截你自定義的註解。 自定義註解 首先先自定義一個註解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNT

shell呼叫定義函式及傳參

1 單個引數 #!/bin/bash function LoopPrint() { count=0; while [ $count -lt $1 ] ; do echo $count; let +

vivado學習之定義IP和呼叫定義IP和的步驟

一、自定義IP核 1、開啟 VIVADO 軟體,新建一個工程。 2、Flow Navigater下,單擊 Add Source,選擇 Add or Creat design Sources,然後單擊 Next。 3、單擊 Create File,輸入檔名,單擊 OK。 4、