[TOC]
和verilog相比system verilog提供了很多數據改進的數據結構,一些數據對于創建者和測試者都有用。
># 內建數據類型
## 邏輯(logic)類型
system verilog對經典的reg數據類型進行了改進,使他除了作為變量以外,還能被**連續賦值、門單元、和驅動模塊所驅動**,這種改進的數據類型被稱為**logic**。</br>
它既可被過程賦值也能被連續賦值,編譯器可自動推斷**logic**是**reg**還是**wire**。唯一的限制是**logic**只允許一個輸入,不能被多重驅動,所以**inout**類型端口不能定義為**logic**。不過這個限制也帶來了一個好處,由于大部分電路結構本就是單驅動,如果誤接了多個驅動,使用**logic**在編譯時會報錯,幫助發現bug。*所以單驅動時用**logic**,多驅動時用**wire***。</br>
在[Jason的博客](https://link.zhihu.com/?target=http%3A//www.verilogpro.com/verilog-reg-verilog-wire-systemverilog-logic)評論中,Evan還提到一點**logic**和**wire**的區別。**wire**定義時賦值是連續賦值,而**logic**定義時賦值只是賦初值,并且賦初值是不能被綜合的。
```verilog
wire mysignal0 = A & B; // continuous assignment, AND gate
logic mysignal1 = A & B; // not synthesizable, initializes mysignal1 to the value of A & B at time 0 and then makes no further changes to it.
logic mysignal2;
assign mysignal2 = A & B; // Continuous assignment, AND gate
```
```
module tb ;
logic [7:0]i; //聲明logic結構數據
initial begin
i = 0;
repeat(10) begin //循環10次
$display("i=%d",i);
i = i + 1;
end
$display("test running!");
end
endmodule
```
仿真結果
```
Start run at Nov 2 19:42 2020
i= 0
i= 1
i= 2
i= 3
i= 4
i= 5
i= 6
i= 7
i= 8
i= 9
```
logic不僅能夠作為變量,而且可以被連續賦值,門單元和模塊所驅動。但是logic不能夠被多個結構體驅動。下面這段代碼展示了logic的使用方法。
```
module logic_test(input logic rst_h
);
parameter CYCLE = 20;
logic q,q_1,d,clk,rst_1;
initial
begin
clk = 0;
forever #(CYCLE/2) clk = ~clk; // 過程賦值
end
assign rst_1 = ~ rst_h; //連續賦值
not n1(q_1,q); //q_1被門驅動
my_dff d1(q,d,clk,rst_1); //q被模塊驅動
endmodule
```
**SystemVerilog logic的使用方法**
* 單驅動時**logic**可完全替代**reg**和**wire**,除了Evan提到的賦初值問題。
* 多驅動時,如**inout**類型端口,使用**wire**。
## 雙狀態數據類型
相比于verilog中的4狀態數據類型(1,0,x,z),SV引入雙狀態數據類型有利于提高仿真器的性能并減少內存的使用量。下面逐例解釋。
```
bit b; // 雙狀態 單bit
bit [31:0] b32; // 雙狀態,32bit,無符號
int unsigned ui; // 雙狀態,32bit,無符號
int i; // 雙狀態,32bit,有符號
byte b8; // 雙狀態,8bit ,有符號
shortint s; // 雙狀態,16bit,有符號
longint l; // 雙狀態,64bit,有符號
integer i4; // 四狀態,32bit,有符號
time t; // 四狀態,64bit,無符號
real r; // 雙狀態,雙精度浮點數。
```
雙狀態數據類型有利于提高仿真器的性能并減少內存。</br>
**對四態信號的檢查:**($isunknown)
這會讓任意位置出現X或者Z時返回1,使用實例如下:
```
if( $isunknown(iport) == 1)
$display("@%0t: 4-state velue detected on iport %b",$time,iport)
```
*****
部分仿真結果如下:
```
module tb ;
longint i; //聲明logic結構數據
byte b8;
initial begin
i = 0;
b8 = 2;
repeat(3) begin //循環
$display("i=%0d , b8=%0d",i,b8);
i = i - 1;
b8=b8*2;
end
end
endmodule
```
```
Start run at Nov 2 20:01 2020
i=0 , b8=2
i=-1 , b8=4
i=-2 , b8=8
```
># 定寬數組
verilog要求在聲明中必須給出數組的上下邊界,因為幾乎所有的數組都是用0作為索引下界,**所以sv允許只給出數組的寬度**,跟c語言類似。</br>
**例 :數組的聲明**
```
int arr[0:15]; //16個整數
int c_style[16]; //c風格,16個整數
```
可以通過**在變量后面指定維度的方式來聲明多維數組**;</br>
**例 : 聲明8行4列多維數據**
```
int arr2 [0:7][0:3]; //完整聲明
int arr2_cstyle[8][4];
```
**特別注意:**如果讀取的數據地址越界,那么sv會**返回數組元素的缺省值**
* logic類型:返回 X
* 雙狀態類型:返回 0
* 線網在沒有驅動時輸出為 Z
## 數組的遍歷
```
module tb ;
int md[2][3] = '{'{1,2,3},'{4,5,6}}; // 聲明2行3列數組并賦初值,這里使用常量數組來初始化md數組
initial begin
foreach(md[i,j]) //遍歷數組
$display("md[%0d][%0d]=%0d",i,j,md[i][j]);
end
endmodule
```
輸出結果
```
VCS Build Date = May 24 2016 20:38:43
Start run at Nov 2 20:26 2020
md[0][0]=1
md[0][1]=2
md[0][2]=3
md[1][0]=4
md[1][1]=5
md[1][2]=6
```
按維度遍歷
```
module tb ;
int md[2][3] = '{'{1,2,3},'{4,5,6}}; // 聲明2行3列數組并賦初值
initial begin
foreach( md[i] ) begin //遍歷第1維
$write("%2d:",i);
foreach( md[,j] ) //遍歷第2維
$write("%3d",md[i][j]);
$display;//顯示一個維度
end
end
endmodule
```
結果
```
0: 1 2 3
1: 4 5 6
```
## 數組的比較與復制
```
module tb ;
bit [31:0] src[5] = '{0,1,2,3,4},
dst[5] = '{5,4,3,2,1};
initial begin
//比較兩個數組
if( src == dst ) $display("src == dst");
else $display("src != dst");
//把src元素拷貝到dst
dst = src;
//只改變一個元素
dst[0] = 5;
//所有元素的值是否相等
$display("src %s dst",(src == dst)? "==" : "!=");
//使用數組片段對第 1-4 個元素進行比較
$display("src[1:4] %s dst[1:4]",(src[1:4] == dst[1:4]) ? "==" : "!=");
end
endmodule
```
輸出結果
```
Start run at Nov 2 20:41 2020
src != dst
src != dst
src[1:4] == dst[1:4]
```
## 使用數組位下標和數組下標
**例 : 位下標和數組下標**
```
module tb ;
bit [31:0] src[5] = '{5,1,2,3,4};
initial begin
$display(src[0],, // 5
src[0][0],, // 1
src[0][2:1]); // 2
end
endmodule
```
## 合并數組
對于一些數據你可能既希望作為**整體**訪問,也希望**拆分為更小單元**訪問,使用sv的合并數組可以實現這個功能。</br>
**例 : 合并數組例子**
```
module tb ;
bit [3:0][7:0] bytes ; //四個字節組裝而成的32 bit數據
initial begin
bytes = 32'hCafe_Dada;
$display(bytes,, //顯示所有32 bit
bytes[3],, //顯示最高字節 "CA"
bytes[3][7]); //顯示最高bit位 ”1“
end
endmodule
```
結果
```
3405699802 202 1
```
**擴展說明:**
已知一個多維混合數組的定義為:
```
bit [3:0][7:0][15:0] Array [3:0][7][6];
```
那么當我們寫下
```
Array[2][3][2][2] = xxxx;
```
的時候,到底是對哪個位置賦值了??
話不多說,直接看解答好啦~最后的答案其實很簡單,因為有一個簡單的圖示估計很多人知道,就是逆時針索引法:

**合并數組和非合并數組的選擇**
* 合并數組:和標量進行相互轉換,等待數組中的變化必須使用合并數組
> # 動態數組
sv提供動態數組,動態數組在聲明時使用空下標[ ]。**寬度將不會在編譯時給出,而是在程序運行時在指定**。數組開始時為空,因此你必須調用`new [ ] `操作來分配空間。</br>
**例 :動態數組實例**
```
module tb ;
int dyn[],d2[] ; //聲明動態數組
initial begin
dyn = new[5] ;//分配5個元素空間
foreach( dyn[i] ) dyn[i] = i; //對5個元素空間的值進行初始化
d2 = dyn ; //復制數組dyn到d2
d2[0] = 5 ; //修改d2[0]的值為5
$display(dyn[0],d2[0]); //顯示數值
dyn = new[20](dyn); //分配20個證書值并進行復制
dyn = new[100]; //分配 100 個新的整數值
dyn.delete(); //刪除所有元素
end
endmodule
```
**例 : 使用動態數組保存元素數量不定的列表**
```
bit [7:0] mask[] = '{ 8'h00,8'h01,
8'h03,8'h04,
8'h23,8'h36};
```
># 隊列
隊列與鏈表類似,可以**在一個隊列中的任何地方增加和刪除元素**,這類操作在性能上的損失比動態數組小的多!</br>
隊列的聲明使用`[$]`,隊列元素的編號從0到$。sv的隊列類似與STL的雙端隊列。可以通過增加元素來創建隊列。**你可以擴大和縮小隊列,但是不用向動態數組一樣付出很大的代價**。</br>
**例 : 隊列操作**
```
module tb ;
//注意,隊列常量不需要使用“’”
int q2[$] = {3,4};
int q[$]= {0,2,5};
initial begin
//在2之前插入1
q.insert(1,1); // 0 1 2 5
foreach(q[i])$write("%3d",q[i]); $display; //顯示結果
//在5之前插入隊列q2
q.insert(3,q2); // 0 1 2 3 4 5
foreach(q[i])$write( "%3d",q[i]); $display; //顯示結果
//刪除q下標為1的元素
q.delete(1); //0 2 3 4 5
foreach(q[i])$write( "%3d",q[i]); $display; //顯示結果
//以下操作速度很快
//在隊列最前面插入 8
q.push_front(8); //8 0 2 3 4 5
foreach(q[i])$write( "%3d",q[i]); $display; //打印整個鏈表
//在隊列最前后面插入 6
q.push_back(6); //8 0 2 3 4 5 6
foreach(q[i])$write( "%3d",q[i]); $display; //顯示結果
//讀出隊列最前面的元素并從隊列中移除該元素
$display(q.pop_front());
foreach(q[i])$write( "%3d",q[i]); $display; //顯示結果 0 2 3 4 5 6
//讀出隊列最后面的元素并從隊列中移除該元素
$display(q.pop_back());
foreach(q[i])$write( "%3d",q[i]); $display; //顯示結果 0 2 3 4 5
end
endmodule
```
結果
```
Start run at Nov 2 21:56 2020
0 1 2 5
0 1 2 3 4 5
0 2 3 4 5
8 0 2 3 4 5
8 0 2 3 4 5 6
8
0 2 3 4 5 6
6
0 2 3 4 5
```
>>**說明:** 可以使用字下標串聯來代替方法。對于隊列`q[$]={0,2,4}`,如果把`$`放在一個范圍表達式的左邊,那么`$`將代表最小值,例如`[$:2]`就代表`[0:2]`。如果把`$`放在一個范圍表達式的右邊,那么`$`將代表最大值,例如`[1:$]`就代表`[1:2]`。
使用上述方法的操作如下:</br>
**例 : 隊列串聯表達式**
```
module tb ;
//注意,隊列常量不需要使用“’”
int q2[$] = {3,4};
int q[$]= {0,2,5};
initial begin
//在2之前插入1
q={q[0:1],1,q[2:$]}; // 0 1 2 5
foreach(q[i])$write("%3d",q[i]); $display; //顯示結果
//在5之前插入隊列q2
q={q[0:2],q2,q[3:$]}; // 0 1 2 3 4 5
foreach(q[i])$write( "%3d",q[i]); $display; //顯示結果
//刪除q下標為1的元素
q.delete(1); //0 2 3 4 5
foreach(q[i])$write( "%3d",q[i]); $display; //顯示結果
//刪除整個隊列
q={};
end
endmodule
```
># 關聯數組
當你只需要偶爾創建一個大容量數組,那么動態數組已經足夠好用了,但是如果需要超大容量的呢?sv提供了關聯數組用來保存稀疏矩陣的元素。也就是說只為實際寫入的數據開辟存儲空間。**可以將其理解為哈希表**,雖然哈希表帶來了額外開銷,但是在這種情況下,這是可以也接受的。</br>
**例 : 關聯數組聲明,初始化和使用**
```
module tb ;
bit [63:0] assoc[ bit [63:0] ],idx = 1;
initial begin
//對稀疏分布的元素進行賦值
repeat (3) begin
assoc[idx] = idx;
idx = idx << 1;
end
//foreach遍歷數組
foreach(assoc[i])$display("assoc[%h]=%h",i,assoc[i]);
$display("+++++++++++++++++++++++");
//使用函數遍歷數組
if( assoc.first(idx) ) begin
do
$display("assoc[%h]=%h",idx,assoc[idx]);
while( assoc.next(idx) ); //得到下一個索引
end
//找到并刪除第一個元素
assoc.first(idx);
assoc.delete(idx);
$display("The array now has %0d elements",assoc.num);
end
endmodule
```
結果
```
Start run at Nov 2 22:22 2020
assoc[0000000000000001]=0000000000000001
assoc[0000000000000002]=0000000000000002
assoc[0000000000000004]=0000000000000004
+++++++++++++++++++++++
assoc[0000000000000001]=0000000000000001
assoc[0000000000000002]=0000000000000002
assoc[0000000000000004]=0000000000000004
The array now has 2 elements
```
**例 : 使用帶字符串索引的關聯數組**
```
//關聯數組也可以用字符串索引進行尋址,使用字符串索引讀取文件,并建立關聯數組switch,可以實現字符串到數字的映射。
/*
輸入文件內容如下:
42 min_address
1492 max_address
*/
int switch[string],min_address,max_address; //定義變量
initial begin //初始化
int i,r,file;
string s;//string 用來年保存長度可變的字符串常量
file = $fopen(“switch.txt”,r); //在當前目錄下以只讀的方式打開文件switch.txt,使用指針向量file指向該文件
while(! $feof(file) ) begin //未讀取到文件的結尾時
r=$fscanf (file, “%d %s”, i, s); //將文件中的數字以10進制的方式保存到i中,字符串保存到s中
switch[s] = i; //為數組中的字符串指定地址
end
$fclose(fire); //關閉文件
//獲取最小地址值,缺省為0
min_address=switch[“min_address”] //將min_address對應的地址(數字)賦值給min_address
//獲取最大地址值,缺省為1000
if(switch.exists(“max_address”)) //使用exists函數判斷switch數組中是否含有“max_address”
max_address = switch[“max_address”]//含有的話,將內容的地址賦值給 max_address
else
max_address =1000 //不存在指定內容,則默認地址為1000
//打印數組的所有元素
foreach(switch [s])
$display(“switch[ ‘ %s ’ ] = %0d ”, s ,switch[s] );//打印數組的內容和相應的地址
end
```
---
**例 : 字符關聯數組操作**
```
module tb ;
bit [63:0] assoc[ string ];
initial begin
//對稀疏分布的元素進行賦值
assoc["a"] = 1;
assoc["b"] = 2;
assoc["c"] = 3;
//foreach遍歷數組
foreach(assoc[i])$display("assoc[%s]=%h",i,assoc[i]);
end
endmodule
```
># 鏈表
sv提供了鏈表數據結構,類似于STL的列表容器,這個容器被定義為參數化的類,可以根據用戶所需存放各種類型的數據。</br>
雖然sv提供了鏈表,但是應該避免使用它。sv使用隊列更高效。
># 數組的方法
sv提供了很多數組的方法,可以用于任何一種非合并數組的類型,**包括定寬數組,動態數組,隊列和關聯數組**。
## sum方法:數組求和
**例 : 數組求和**
```module tb ;
bit on[5] = '{0,1,0,1,0};//單bit數組
initial begin
foreach( on [i])$write("%3d",on[i]);$display;
//單bit求和
$display("on.sum=%0d",on.sum);
end
endmodule
```
結果
```
Start run at Nov 2 22:49 2020
0 1 0 1 0
on.sum=0
```
>>sum方法的結果位寬和數組定義的位寬是一致的。
## product方法:數組求積
**例 :數組求積**
```
module tb ;
int on[3] = '{1,2,3};//單bit數組
initial begin
foreach( on [i])$write("%3d",on[i]);$display;
//單bit求和
$display("on.product=%0d",on.product);
end
endmodule
```
結果
```
Start run at Nov 2 22:57 2020
1 2 3
on.product=6
```
##and,or,xor方法:數組求與,或,異或
**例 :數組求與,或,異或**
```
module tb ;
int on[3] = '{1,3,3};//單bit數組
initial begin
foreach( on [i])$write("%3d",on[i]);$display;
$display("on.and=%0d",on.and);
$display("on.or=%0d",on.or);
$display("on.xor=%0d",on.xor);
end
endmodule
```
## min,max方法:最大值最小值方法
**注意返回值為一個隊列!**
**例 :最大值最小值方法**
```
module tb ;
int on[] = '{1,3,3,9};
int rt[$];
initial begin
foreach( on [i])$write("%3d",on[i]);$display;
rt=on.min();foreach(rt[i])$write("%3d",rt[i]);$display;
rt=on.max();foreach(rt[i])$write("%3d",rt[i]);$display;
end
endmodule
```
結果
```
Start run at Nov 2 23:11 2020
1 3 3 9
1
9
```
## unique方法:排除重復數值
**注意返回值為一個隊列!**
**例 :排除重復數值**
```
module tb ;
int on[] = '{1,3,3,9};
int rt[$];
initial begin
foreach( on [i])$write("%3d",on[i]);$display;
rt=on.unique();foreach(rt[i])$write("%3d",rt[i]);$display;
end
endmodule
```
結果
```
Start run at Nov 2 23:15 2020
1 3 3 9
1 3 9
```
## size方法:獲取數組大小
**例 :獲取數組大小**
```
module tb ;
int on[] = '{1,3,3,9};
int rt[$];
initial begin
foreach( on [i])$write("%3d",on[i]);$display;
//獲取動態數組的大小
$display("len=%0d",on.size());
//獲取各種數組大小的方法
$display("len=%0d",$size(on));
endmodule
```
結果
```
Start run at Nov 2 23:18 2020
1 3 3 9
len=4
len=4
```
## find方法:數組定位方法
**注意返回值為一個隊列!**
**例 :find數組定位方法**
```
module tb ;
int on[] = '{4,1,3,3,9};
int rt[$];
initial begin
foreach( on [i])$write("%3d",on[i]);$display;
//找出所有大于等于3的元素 4 3 3 9
rt=on.find with (item >= 3);
foreach(rt[i])$write("%3d",rt[i]);$display;
//找出值大于等于2的索引 0 2 3 4
rt=on.find_index with (item >= 2);
foreach(rt[i])$write("%3d",rt[i]);$display;
//找出第一個大于4的值 9
rt=on.find_first with (item >4);
foreach(rt[i])$write("%3d",rt[i]);$display;
//找出最后一個小于9的值 3
rt=on.find_last with (item < 9);
foreach(rt[i])$write("%3d",rt[i]);$display;
//找出第一個大于4的數據的索引值 4
rt=on.find_first_index with (item >4);
foreach(rt[i])$write("%3d",rt[i]);$display;
//找出最后一個==3的數據的索引值
rt=on.find_last_index with (item == 3);
foreach(rt[i])$write("%3d",rt[i]);$display;
end
endmodule
```
結果
```
Start run at Nov 2 23:31 2020
4 1 3 3 9
4 3 3 9
0 2 3 4
9
3
4
3
```
**例 : 等同的幾種描述**
```
rt=on.find_first with (item >= 3);
rt=on.find_first() with (item >= 3);
rt=on.find_first(item) with (item >= 3);
rt=on.find_first(x) with (x >= 3);
```
## 數組排序方法:reverse,sort,rsort,shuffle
**例:數組排序**
```
module tb ;
int on[] = '{4,1,3,3,9};
int rt[$],msum;
initial begin
foreach( on [i])$write("%3d",on[i]);$display;
//數組反序
on.reverse();
foreach( on [i])$write("%3d",on[i]);$display;
//數組 小->大
on.sort();
foreach( on [i])$write("%3d",on[i]);$display;
//數組 大->小
on.rsort();
foreach( on [i])$write("%3d",on[i]);$display;
//數組洗牌
on.shuffle();
foreach( on [i])$write("%3d",on[i]);$display;
end
endmodule
```
結果
```
Start run at Nov 3 00:12 2020
4 1 3 3 9
9 3 3 1 4
1 3 3 4 9
9 4 3 3 1
3 4 1 9 3
```
## 結構數組的使用和排序
**例 : 結構數組的使用和排序例子**
```
module tb ;
int rt[$],msum;
struct packed {byte red,green,blue;} c[]; //結構數組
initial begin
c=new[5];
foreach(c[i])c[i] = $urandom;//隨機賦值
foreach( c[i])$write("%10d",c[i].red);$display;
c.sort with (item.red); //up排序red
foreach( c[i])$write("%10d",c[i].red);$display;
end
endmodule
```
結果
```
Start run at Nov 3 00:17 2020
-30 -34 127 -86 121
-86 -34 -30 121 127
```
> # typedef創建新的數據類型
**例 :創建新數據類型**
```
parameter N = 8;
typedef reg [N - 1 : 0 ] opreg_t;
opreg_t c;
```
> # struct創建新的數據類型
**例 :struct創建新數據類型**
```
module tb ;
int rt[$];
typedef struct packed {byte red,green,blue;} pixel_s;//結構數組
typedef struct packed {int a;bit[2:0] b;} m_s;//結構數組
pixel_s c='{1,2,3};
m_s cc = '{
32'd23,
3'b101
};
initial begin
$display("%5d %5d %5d",c.red,c.green,c.blue);
$display("%5d %5d",cc.a,cc.b);
end
endmodule
```
結果
```
Start run at Nov 3 00:38 2020
1 2 3
23 5
```
># 靜態轉換
靜態轉換操作不對轉換值進行檢查。
**例 : 靜態轉換例子**
```
module tb ;
int rt[$];
int i ;
real r;
initial begin
i = int '(10.0 - 0.1); //非強制轉換
r = real '(42);
$display(i);
$display(r);
end
endmodule
```
> # 流操作
```
module tb ;
int rt[$];
byte h ;
bit [3:0] q[2] = '{4'h04,4'h01} ;
initial begin
$display("%6b %6b",q[0],q[1]);
//將q打包為byte
h = {>>{q}}; //0100_0001
$display("%b",h);
//位倒敘
h = {<<{h}}; //1000_0010
$display("%b",h);
end
endmodule
```
- 序
- 第1章 Linux下開發FPGA
- 1.1 Linux下安裝diamond
- 1.2 使用輕量級linux仿真工具iverilog
- 1.3 使用linux shell來讀寫串口
- 1.4 嵌入式上的linux
- 設備數教程
- linux C 標準庫文檔
- linux 網絡編程
- 開機啟動流程
- 1.5 linux上實現與樹莓派,FPGA等通信的串口腳本
- 第2章 Intel FPGA的使用
- 2.1 特別注意
- 2.2 高級應用開發流程
- 2.2.1 生成二進制bit流rbf
- 2.2.2 制作Preloader Image
- 2.2.2.1 生成BSP文件
- 2.2.2.2 編譯preloader和uboot
- 2.2.2.3 更新SD的preloader和uboot
- 2.3 HPS使用
- 2.3.1 通過JTAG下載代碼
- 2.3.2 HPS軟件部分開發
- 2.3 quartus中IP核的使用
- 2.3.1 Intel中RS232串口IP的使用
- 2.4 一些問題的解決方法
- 2.4.1 關于引腳的復用的綜合出錯
- 第3章 關于C/C++的一些語法
- 3.1 C中數組作為形參不傳長度
- 3.2 匯編中JUMP和CALL的區別
- 3.3 c++中map的使用
- 3.4 鏈表的一些應用
- 3.5 vector的使用
- 3.6 使用C實現一個簡單的FIFO
- 3.6.1 循環隊列
- 3.7 C語言不定長參數
- 3.8 AD采樣計算同頻信號的相位差
- 3.9 使用C實現棧
- 3.10 增量式PID
- 第4章 Xilinx的FPGA使用
- 4.1 Alinx使用中的一些問題及解決方法
- 4.1.1 在Genarate Bitstream時提示沒有name.tcl
- 4.1.2 利用verilog求位寬
- 4.1.3 vivado中AXI寫DDR說明
- 4.1.4 zynq中AXI GPIO中斷問題
- 4.1.5 關于時序約束
- 4.1.6 zynq的PS端利用串口接收電腦的數據
- 4.1.7 SDK啟動出錯的解決方法
- 4.1.8 讓工具綜合是不優化某一模塊的方法
- 4.1.9 固化程序(雙核)
- 4.1.10 分配引腳時的問題
- 4.1.11 vivado仿真時相對文件路徑的問題
- 4.2 GCC使用Attribute分配空間給變量
- 4.3 關于Zynq的DDR寫入byte和word的方法
- 4.4 常用模塊
- 4.4.1 I2S接收串轉并
- 4.5 時鐘約束
- 4.5.1 時鐘約束
- 4.6 VIVADO使用
- 4.6.1 使用vivado進行仿真
- 4.7 關于PicoBlaze軟核的使用
- 4.8 vivado一些IP的使用
- 4.8.1 float-point浮點單元的使用
- 4.10 zynq的雙核中斷
- 第5章 FPGA的那些好用的工具
- 5.1 iverilog
- 5.2 Arduino串口繪圖器工具
- 5.3 LabVIEW
- 5.4 FPGA開發實用小工具
- 5.5 Linux下繪制時序圖軟件
- 5.6 verilog和VHDL相互轉換工具
- 5.7 linux下搭建輕量易用的verilog仿真環境
- 5.8 VCS仿真verilog并查看波形
- 5.9 Verilog開源的綜合工具-Yosys
- 5.10 sublim text3編輯器配置verilog編輯環境
- 5.11 在線工具
- 真值表 -> 邏輯表達式
- 5.12 Modelsim使用命令仿真
- 5.13 使用TCL實現的個人仿真腳本
- 5.14 在cygwin下使用命令行下載arduino代碼到開發板
- 5.15 STM32開發
- 5.15.1 安裝Atollic TrueSTUDIO for STM32
- 5.15.2 LED閃爍吧
- 5.15.3 模擬U盤
- 第6章 底層實現
- 6.1 硬件實現加法的流程
- 6.2 硬件實現乘法器
- 6.3 UART實現
- 6.3.1 通用串口發送模塊
- 6.4 二進制數轉BCD碼
- 6.5 基本開源資源
- 6.5.1 深度資源
- 6.5.2 FreeCore資源集合
- 第7章 常用模塊
- 7.1 溫濕度傳感器DHT11的verilog驅動
- 7.2 DAC7631驅動(verilog)
- 7.3 按鍵消抖
- 7.4 小腳丫數碼管顯示
- 7.5 verilog實現任意人數表決器
- 7.6 基本模塊head.v
- 7.7 四相八拍步進電機驅動
- 7.8 單片機部分
- 7.8.1 I2C OLED驅動
- 第8章 verilog 掃盲區
- 8.1 時序電路中數據的讀寫
- 8.2 從RTL角度來看verilog中=和<=的區別
- 8.3 case和casez的區別
- 8.4 關于參數的傳遞與讀取(paramter)
- 8.5 關于符號優先級
- 第9章 verilog中的一些語法使用
- 9.1 可綜合的repeat
- 第10章 system verilog
- 10.1 簡介
- 10.2 推薦demo學習網址
- 10.3 VCS在linux上環境的搭建
- 10.4 deepin15.11(linux)下搭建system verilog的vcs仿真環境
- 10.5 linux上使用vcs寫的腳本仿真管理
- 10.6 system verilog基本語法
- 10.6.1 數據類型
- 10.6.2 枚舉與字符串
- 第11章 tcl/tk的使用
- 11.1 使用Tcl/Tk
- 11.2 tcl基本語法教程
- 11.3 Tk的基本語法
- 11.3.1 建立按鈕
- 11.3.2 復選框
- 11.3.3 單選框
- 11.3.4 標簽
- 11.3.5 建立信息
- 11.3.6 建立輸入框
- 11.3.7 旋轉框
- 11.3.8 框架
- 11.3.9 標簽框架
- 11.3.10 將窗口小部件分配到框架/標簽框架
- 11.3.11 建立新的上層窗口
- 11.3.12 建立菜單
- 11.3.13 上層窗口建立菜單
- 11.3.14 建立滾動條
- 11.4 窗口管理器
- 11.5 一些學習的腳本
- 11.6 一些常用的操作語法實現
- 11.6.1 刪除同一后綴的文件
- 11.7 在Lattice的Diamond中使用tcl
- 第12章 FPGA的重要知識
- 12.1 面積與速度的平衡與互換
- 12.2 硬件原則
- 12.3 系統原則
- 12.4 同步設計原則
- 12.5 乒乓操作
- 12.6 串并轉換設計技巧
- 12.7 流水線操作設計思想
- 12.8 數據接口的同步方法
- 第13章 小項目
- 13.1 數字濾波器
- 13.2 FIFO
- 13.3 一個精簡的CPU( mini-mcu )
- 13.3.1 基本功能實現
- 13.3.2 中斷添加
- 13.3.3 使用中斷實現流水燈(實際硬件驗證)
- 13.3.4 綜合一點的應用示例
- 13.4.5 使用flex開發匯編編譯器
- 13.4.5 linux--Flex and Bison
- 13.4 有符號數轉單精度浮點數
- 13.5 串口調試FPGA模板