1. 程式人生 > >Systemverilog for design 筆記(六)

Systemverilog for design 筆記(六)

端口說明 ase style 決定 包括 轉換成 狀態 unique 第一章

第一章 有限狀態機建模(FSM,finite state machine)

1.1. 使用枚舉類型建立狀態機模型

l 三過程塊建模風格:三個過程塊分別實現:

a.狀態轉換(always_ff) b.產生下一狀態(always_comb) c.產生狀態輸出值(always_comb)

l 使用枚舉類型表示狀態編碼:通過定義enum類型決定狀態位數;可顯示指定label value

l 使用枚舉類型的反向case語句:對應ont-hot編碼模式,條件選項是狀態編碼的某一位

l 使用unique修飾case語句

l 對於未使用的狀態值(由狀態變量寬度遍歷產生):

n Verilog:使用X作為缺省賦值,case語句中default:state = n’bxxx; SV:用unique case

n 使用專用的綜合full_case附註

l 盡量使用enum list中的label,而不是具體value對枚舉變量賦值

l 對於enum變量的操作:1.直接將int賦值給enum變量是非法的,要在操作後(賦值前)進行強制轉換,將其轉換為枚舉類型。 2.可使用枚舉方法,見3.2.6

1.2. 在FSM模型中使用兩態數據類型

容易出現死鎖。解決方法:1.使用logic顯示聲明enum 2.使用always_comb

1.3. 總結

unique case + logic enum大法好

第二章 層次化設計

2.1. 模塊原型

SV允許用戶為被實例化的模塊指定一個原型。原型的定義使用關鍵詞extern

Extern之後是模塊及端口聲明。 該聲明只在其定義的範圍內可見。

若模塊有extern module聲明,則模塊定義時無需重復端口聲明,可用 .* 替代

Eg.extern module counter #(parameter N = 15)

(output logic [N:0] cnt,
input wire [N:0] d,
input wire clock,
load,
resetN);

module counter ( .* ); //$unit中已使用原型定義,所以無需重復端口聲明
… //模塊內容

endmodule

2.2. 命名的結束語句

l 命名的模塊結尾 eg. endmodule : <module_name>

l 命名的代碼塊結尾 見6.7,另外還有package...endpackage, interface...endinterface,
task...endtask, function...endfunction, and begin...end

2.3. 嵌套(局部)模塊的聲明

Eg. module ip_core (input clock);
sub1 u1 (...); // 嵌套模塊sub1實例化

module sub1 (...); // 嵌套模塊定義(註意是在ip_core模塊中嵌套定義,而非實例化)
sub2 u2 (); //在nested module sub1的定義中實例化sub2
...

endmodule: sub1

module sub2; //嵌套模塊定義。Sub2沒有端口,但可看到其父模塊源碼中的標識符

sub3 u3 (...); //在nested module sub2的定義中實例化sub3

endmodule: sub2
module sub3 (...); //嵌套模塊定義
...
endmodule: sub3

endmodule: ip_core

Verilog中的模塊名全部是全局的

SV為解決全局模塊帶來的可能模塊間沖突及安全問題,提出了:

嵌套(局部)模塊:Nested (local) module 在模塊內聲明(local)模塊

允許一個模塊的定義嵌套在另一個模塊的定義中,該模塊在聲明的層次域外不可見

2.4. 簡化的模塊實例網表

Verilog中兩種連接模塊實例的代碼風格:

l 使用端口順序連接模塊實例 eg. dff d1 (out, /*not used*/, in, clock, reset);

l 使用端口名稱連接模塊實例 eg. dff d1 (.q(out), .qb(/*not used*/),//.<端口名>(<線網
.d(in), .clk(clock), .rst(reset) );// 或變量名>)

SV中有三種端口連接方法:

l .name 端口連接

l .* 端口連接

l 接口(見第九章)

2.4.1. .name端口連接

當port_name = wire_name且寬度相同時,SV中可使用.name的方式連接模塊實例

相當於verilog中的.name(name)

Eg.

prom prom (
.dout(program_data),
.clk, //使用.name端口連接
.address(program_address)

);

2.4.2. .* 端口連接

用於表示模塊實例中所有名稱相同的端口和線網(或變量)是自動連接在一起的。

Eg.

prom prom (
.*, //使用.*端口連接
.dout(program_data),
.address(program_address)

);

2.5. 線網別名化(alias)

SV使用alias表示兩個不同名稱對同一個線網的引用。

Eg. wire clock,clk; alias clk = clock ;//clk和clock指的是同一個邏輯線網,不是賦值語句

Alias支持多重別名化:alias rst = reset = resetN = rstN ;//一個擁有4個別名的邏輯線網

Rule:

l 進行別名化的兩個線網類型及位數必須相同

l 只有線網類型可以別名化,變量不能別名化

(wire, uwire, wand, wor, tri, triand,trior, tri0, tri1, trireg.)

2.6. 在模塊端口間傳遞數值

Verilog對模塊端口的限制:

l 只有線網類型可以用在端口的輸入端

l 只有net , reg , integer ,或文本整數值可以用在模塊輸出端口

l 通過模塊端口傳遞real類型不合法,要先轉換成向量來傳遞

l 模塊端口間傳遞任何維數的非壓縮數組是不合法的

SV中解除了這些限制:

l 任何類型都可以在模塊的input/output端口,包括實數值

l 任何維數的壓縮或非壓縮數組都可以在端口間傳遞

l Struct和union也可以在模塊端口間傳遞

未解除一些限制:

u 變量只能從單個源接收數值

u 端口兩邊的非壓縮類型在結構上完全匹配(對於struct/union要求typedef相同)

(壓縮值作為向量在端口間傳遞)

2.7. 端口引用(ref)(不可綜合)

相對於verilog的input/ouput/inout,SV增加了ref端口。

Ref端口可以在端口間卻傳遞一個對變量的層次化引用,而不是傳遞該變量值。

對端口名稱的任何引用都會直接引用實際的原變量。

通過引用在端口間傳遞變量會生成共享變量,但在硬件行為卻不是如此。

2.8. 增強的端口聲明

SV相對於Verilog簡化了端口說明的步驟:

l SV制定了缺省的端口方向inout

l 若port list中下一個port定義了類型,但沒有指定方向,那麽默認端口的方向與前一端口一致

l SV增加了兩種可以帶port ,interface和program的層次塊,它們的端口聲明同模塊

l 如果第一個端口沒有指定方向和類型,則其他端口也不能聲明方向和類型

2.9. 參數化類型

通過parameter type聲明參數化的類型

Eg.

module adder #(parameter type ADDERTYPE = shortint) //缺省情況下,參數類型是shortint

(input ADDERTYPE a, b, //可重定義類型

output ADDERTYPE sum, //可重定義類型

output logic carry);

ADDERTYPE temp; // 使用可重定義類型的局部變量

... // 加法器功能

endmodule

module big_chip( ... );

shortint a, b, r1;

int c, d, r2;

int unsigned e, f, r3;

wire carry1, carry2, carry3;

adder i1 (a, b, r1, carry1);//16位無符號加法器

adder #(.ADDERTYPE(int)) i2 (c, d, r2, carry2); //重新定義參數類型,32位有符號加法器

adder #(.ADDERTYPE(int unsigned)) i3 (e, f, r3, carry3); //32位有符號加法器

endmodule

Systemverilog for design 筆記(六)