1.為什么是RTL
在數(shù)字前端領(lǐng)域,RTL幾乎與“設(shè)計(jì)代碼”概念相同。RTL的英文全稱為Register Transfer Level,中文一般翻譯為寄存器傳輸級(jí),原本是HDL建模的一種層次。以Verilog HDL為例,其建模層次包括系統(tǒng)級(jí)、算法級(jí)、RTL級(jí)、門級(jí)和開關(guān)級(jí),其中:
*系統(tǒng)級(jí)和算法級(jí):描述層次較高,較多的忽略細(xì)節(jié)時(shí)序,設(shè)計(jì)精度低,但開發(fā)容易,設(shè)計(jì)難度低
*門級(jí)和開關(guān)級(jí):描述層次較低,設(shè)計(jì)難度很大,但設(shè)計(jì)精細(xì)度很高
*RTL級(jí):設(shè)計(jì)難度和設(shè)計(jì)精度的trade off,同時(shí)也是EDA工具能較好處理的最高層級(jí)
這里舉出一個(gè)乘加器的RTL例子,代碼如下所示:
reg [7:0] a_reg;
reg [7:0] b_reg;
reg [15:0] mul_reg;
reg [15:0] c_reg;
reg [16:0] result_reg;
always @ (posedge clk)
mul_reg <= a_reg * b_reg;
always @ (posedge clk)
result_reg <= c_reg + mul_reg;
這段代碼中涉及5個(gè)寄存器,以及寄存器之間的關(guān)系,例如mul_reg就等于a_reg和b_reg的乘積,RTL級(jí)的描述就是以寄存器為基點(diǎn)(例如a_reg
、b_reg
、mul_reg
),描述寄存器之間的關(guān)系(例如mul_reg=a_reg*b_reg
)的建模層次。
2.RTL拆解
2.1.R(Reg)
RTL首先為R,即寄存器,在RTL級(jí)中的寄存器為一種理想寄存器,其具有以下幾種特征:
*存儲(chǔ):寄存器具有存儲(chǔ)特性,在不復(fù)位和賦值的情況下會(huì)一直保持當(dāng)前的值
*延遲:由于寄存器是邊沿敏感器件,僅能在時(shí)鐘上升沿(一般不使用下降沿)可以被賦值,因此輸入的數(shù)據(jù)延遲一個(gè)cycle才能在輸出上體現(xiàn)
*時(shí)鐘:寄存器具有時(shí)鐘輸入端口,賦值的條件時(shí)時(shí)鐘邊沿+復(fù)位無效+有效信號(hào)(若有)
*復(fù)位:寄存器可以具有同步或異步復(fù)位端口,也可以沒有復(fù)位端口,復(fù)位是優(yōu)先級(jí)最高的賦值端口,會(huì)將寄存器輸出變?yōu)閺?fù)位值,且異步復(fù)位是立即有效的
對(duì)于Reg,可以分為以下幾種類型:
*存儲(chǔ):用于保存當(dāng)前的值供下次調(diào)用,使用了寄存器的存儲(chǔ)特性,為了滿足功能要求添加,在更上層的建模中可見
*打拍:用于打斷組合邏輯路徑,為了滿足時(shí)序要求添加,刪除后(匹配控制路徑)對(duì)功能無影響,在更上層的建模中不可見
*狀態(tài):用于保存狀態(tài),以自身狀態(tài)為下一狀態(tài)的輸入,常見為狀態(tài)機(jī)、隱式狀態(tài)機(jī)和計(jì)數(shù)器幾種,是一條控制路徑或子控制類路徑的起點(diǎn)
根據(jù)Reg處于數(shù)據(jù)路徑還是控制路徑,常見的形態(tài)如下表所示:
可以使用下面的例子展示,這里的例子是一個(gè)以累加器結(jié)尾的流水線,上方是控制路徑,下方是數(shù)據(jù)路徑。控制路徑的起點(diǎn)是分類為狀態(tài)的寄存器,形式為狀態(tài)機(jī),后續(xù)逐級(jí)對(duì)狀態(tài)信息打拍,這里的目的是為了匹配流水線的延遲,因此分類為打拍,最后將狀態(tài)存儲(chǔ)供后續(xù)使用,是為了功能添加,因此分類為存儲(chǔ)。數(shù)據(jù)路徑為流水線,添加流水線的目的是提高運(yùn)行速率,為了匹配時(shí)序目標(biāo),因此第一、第二、第三級(jí)流水線的分類均為打拍,而最后一級(jí)寄存器是累加寄存器,添加的目的是為了保持?jǐn)?shù)據(jù),滿足累加的功能要求,因此分類為存儲(chǔ):
最后,根據(jù)不同類型的寄存器,設(shè)計(jì)時(shí)需要考慮的問題都相對(duì)固定,首先分析寄存器是否有必要存在和基本的形式,分析的角度如下所示:
*狀態(tài)寄存器:當(dāng)前設(shè)計(jì)是集中式控制還是分布式控制,若為集中式控制,狀態(tài)寄存器是否需要移動(dòng)到控制模塊中;若為分布式控制,狀態(tài)寄存器的形態(tài)為計(jì)數(shù)器還是顯式狀態(tài)機(jī)。
*打拍寄存器:邏輯路徑是否過長(zhǎng),若過長(zhǎng),則添加在哪個(gè)點(diǎn)既能合理的分割邏輯路徑,又能使用較少bit的寄存器
*存儲(chǔ)寄存器:存儲(chǔ)的訪問方式,容量需求如何,是否需要靈活同時(shí)讀寫,是否可以用memory代替
隨后對(duì)于寄存器,有一些基本的設(shè)計(jì)要素,是每個(gè)寄存器都要考慮的,包括:
*工作在哪個(gè)時(shí)鐘域下,和輸入寄存器之間是否存在跨時(shí)鐘域的關(guān)系
*是否需要異步和同步復(fù)位信號(hào),若需要,位于哪個(gè)復(fù)位域(和其他哪些寄存器能一起復(fù)位)
*是否需要用前清零和用后清零
*什么是否需要對(duì)其進(jìn)行刷新,刷新是否需要有效信號(hào)(是否考慮自動(dòng)門控)
對(duì)其復(fù)位、自動(dòng)門控和復(fù)位的處理如下表所示,其中是否添加異步/同步復(fù)位和自動(dòng)門控優(yōu)先級(jí)主要與位置有關(guān),復(fù)位處理主要與分類有關(guān):
2.2.T(Transfer)
Transfer用于描述組合邏輯,即寄存器之間的連接關(guān)系,必須依附于寄存器(或端口)存在。Transfer可以用函數(shù)表示,描述其依附的Reg的值如何進(jìn)行更新。以一個(gè)累加器為例,其代碼如下所示:
input [7:0] din;
input din_vld;
reg [7:0] dout;
wire dout_transfer;
assign dout_transfer = dout + din;
always @ (posedge clk or negedge rst_b) begin
if(~rst_b) begin
dout <= 8'b0;
end else if(din_vld) begin
dout <= dout_transfer;
end
end
其中dout
是數(shù)據(jù)路徑上的存儲(chǔ)寄存器,對(duì)應(yīng)的transfer的函數(shù)表達(dá)式如下所示:
Transfer又可以分為兩類,分別是有狀態(tài)和無狀態(tài):
*有狀態(tài)Transfer:其依附的寄存器的值作為transfor的輸入,如上面的例子就是一個(gè)有狀態(tài)的Transfor,一般來說,有狀態(tài)的Transfor只會(huì)依附在狀態(tài)寄存器、存儲(chǔ)寄存器(累運(yùn)算)上
*無狀態(tài)Transfor:其依附的寄存器的值和transfor的輸入無關(guān),一般依附在打拍寄存器和一部分存儲(chǔ)寄存器(純存儲(chǔ))上
這兩種類型的Transfer的例子如下圖所示:
和Reg不同,Transfer的功能和基本實(shí)現(xiàn)模式由設(shè)計(jì)人員通過RTL代碼描述,而具體而細(xì)節(jié)的實(shí)現(xiàn)方式一般由綜合器確定(也可以由設(shè)計(jì)人員手工指定),綜合器主要會(huì)對(duì)Transfer進(jìn)行優(yōu)化,Transfer對(duì)應(yīng)的變量可能在綜合后被重命名,按原有名稱在網(wǎng)表中可能無法找到。
2.3.L(Level)
Level就是層級(jí),這里對(duì)R和T做一個(gè)總結(jié),以R(和Port)為節(jié)點(diǎn),以T為邊,可以構(gòu)建一個(gè)有向、有環(huán)、帶自環(huán)邊的圖,如下圖所示:
圖中的節(jié)點(diǎn)分為寄存器、端口和常數(shù)值(一般忽略),而邊分為控制線和數(shù)據(jù)線,控制線負(fù)責(zé)管理刷新時(shí)刻,而數(shù)據(jù)線負(fù)責(zé)生成刷新值。按另一種說法,如果將一個(gè)寄存器的功能用一個(gè)或多個(gè)不包括分支的函數(shù)表示,則函數(shù)中的輸入值就都是數(shù)據(jù)線,其他信號(hào)就是控制線,
RTL代碼實(shí)質(zhì)就是描述一張圖的關(guān)系,如下一段代碼:
input din_vld
reg cnt_en;
reg [7:0] cnt;
output dout_vld;
always @ (posedge clk or negedge rst_b) begin
if(~rst_b) begin
cnt_en <= 1'b0;
end else if(cnt == 8'd200) begin
cnt_en <= 1'b0; // 數(shù)據(jù)線f(x) = 0
end else if(din_vld) begin
cnt_en <= 1'b1; // 數(shù)據(jù)線f(x) = 1
end
always @ (posedge clk or negedge rst_b) begin
if(~rst_b) begin
cnt <= 8'b0;
end else if(din_vld) begin // 控制線
cnt <= 8'b0; // 數(shù)據(jù)線f(x) = 0
end else if(cnt_en) begin
cnt <= cnt + 1'b1; // 數(shù)據(jù)線f(x) = cnt + 1
end
assign dout_vld = (cnt > 8'd128); // 數(shù)據(jù)線f(x) = 0 和 f(x) = 1
這段代碼描述了一個(gè)計(jì)數(shù)器生成控制信號(hào)的過程,可以轉(zhuǎn)換為如下所示的圖。其中紅線為控制線,黑線為數(shù)據(jù)線,忽略了常數(shù)值:
3.RTL和Reg/Wire的關(guān)系
RTL中的Reg和Transfer與Verilog中常用的Reg和Wire的關(guān)系是一個(gè)老生常談的話題,這里直接給出結(jié)論:
*Verilog中的Reg類型可以建模RTL中的Reg(時(shí)序邏輯)和Transfer(組合邏輯),但RTL中的Reg只能用Verilog中的Reg類型建模
*Verilog中的Wire類型只能用來建模RTL中的Transfer(組合邏輯),但RTL中的Transfer(組合邏輯)既可以用Verilog中的Wire類型建模,也可以用Verilog中的Reg類型建模
-
寄存器
+關(guān)注
關(guān)注
31文章
5325瀏覽量
120052 -
EDA工具
+關(guān)注
關(guān)注
4文章
265瀏覽量
31717 -
RTL
+關(guān)注
關(guān)注
1文章
385瀏覽量
59710 -
狀態(tài)機(jī)
+關(guān)注
關(guān)注
2文章
492瀏覽量
27486 -
乘加器
+關(guān)注
關(guān)注
0文章
4瀏覽量
6006
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論