大家好,這里是程序員 杰克 。一名平平無(wú)奇的嵌入式軟件工程師。
FPGA相比MCU而言,在數(shù)據(jù)位操作上有很明顯的優(yōu)勢(shì)。FPGA支持任意位拼接以及數(shù)據(jù)截取操作。本篇主要是總結(jié)和分享一些對(duì)數(shù)據(jù)位操作的實(shí)用語(yǔ)法技巧。內(nèi)容不多,其中最最最重要的內(nèi)容是數(shù)據(jù)的動(dòng)態(tài)位截取操作。
下面正式進(jìn)入本章推送的內(nèi)容。
01 數(shù)據(jù)位操作技巧
數(shù)據(jù)移位(shift)
Verilog中的移位操作有兩種:邏輯移位操作(logical)、算數(shù)移位操作(arithmetic)。邏輯移位使用“<<”、和“>>”,而算術(shù)移位使用“<<<”、和“>>>”,描述以及代碼示例如下所示:
//本示例使用邏輯、算術(shù)右移為例:
//邏輯右移( >>), 初始值為4'b1000, 移位結(jié)果為4'b0010
module shift();
reg [3:0] value, rusult;
initial begin
value = 4'b1000;
result = (value > > 2);
end
endmodule
//算術(shù)右移( >> >), 初始值為4'b1000, 移位結(jié)果為4'b1110
module shift();
reg signed [3:0] value, rusult;
initial begin
value = 4'b1000;
result = (value > >> 2);
end
endmodule
數(shù)據(jù)位拼接(concatenations)
顧名思義,“數(shù)據(jù)位拼接”是由多個(gè)表達(dá)式產(chǎn)生的位拼接在一起的輸出結(jié)果。其使用大括號(hào)“{}”來(lái)表示,內(nèi)部表達(dá)式之間使用逗號(hào)“,”隔開(kāi)。
對(duì)于位拼接操作,不允許使用不確定大小的常量;位拼接中唯一可以使用的操作是復(fù)制(replication)。
數(shù)據(jù)位拼接操作示例如下:
//1. 簡(jiǎn)單位拼接操作
reg [1:0] a;
reg [3:0] b;
reg [9:0] result = {2'b10, a, b[2:0], 3'd7};
//2. 復(fù)制拼接操作
reg [1:0] c;
reg [2:0] d;
reg [9:0] result;
result = {2{c, d}};//=={ {c[1:0], d[2:0]}, {c[1:0], d[2:0]} }
//3. 參數(shù)化代碼示例
parameter PARA = 32; //PARA = [1,32]
wire [31:0] e;
assign e = { {(32-PARA){1'b1}}, f[(PARA-1):0] };
數(shù)據(jù)位截取(bit select)
數(shù)據(jù)位截取(bit select)可以從線(xiàn)網(wǎng)( net )、寄存器( reg )、整數(shù)( integer )、時(shí)間( time )、參數(shù)( parameter )等類(lèi)型進(jìn)行任意位截取。IEEE中Verilog標(biāo)準(zhǔn)中對(duì)位截取的語(yǔ)法表達(dá)式如下:
vect[msb_expr : lsb_expr];
/*
其中msb_expr 是整形/常量表達(dá)式, lsb_expr 是常量表達(dá)式;
當(dāng)msb_expr為常量表達(dá)式時(shí),數(shù)據(jù)位截取則為靜態(tài)截取;
當(dāng)msb_expr為整形表達(dá)式時(shí),數(shù)據(jù)位截取則為動(dòng)態(tài)截?。?*/
靜態(tài)截取示例代碼如下:
//從vect[31:0]截取低16位賦值給value[15:0]
module bit_select();
reg [31:0] vect;
reg [15:0] value;
initial begin
vect = 32'hAAAA_CCCC;
value = vect[23:8]; //value = 16'hAACC;
end
endmodule
IEEE標(biāo)準(zhǔn)Verilog中,對(duì)reg、integer、time變量/parameter參數(shù)動(dòng)態(tài)截取語(yǔ)法如下所示:
//動(dòng)態(tài)截取操作語(yǔ)法
reg [15:0] big_vect;
reg [0:15] little_vect;
big_vect [lsb_base_expr +: width_expr]
little_vect [msb_base_expr +: width_expr]
bit_vect [msb_base_expr -: width_expr]
little_vect [lsb_base_expr -: width_expr]
/*
width_expr為常量表達(dá)式, 在代碼運(yùn)行時(shí)不能改變;
lsb/msb_base_expr為整形表達(dá)式, 作為從在運(yùn)行時(shí)可以動(dòng)態(tài)改變;
width_expr作為截取的位寬值, 而msb/lsb_base_expr為截取的起始地址;
“+”為地址向上遞增操作, “-”為地址向下遞增操作;
上面代碼功能是:
從msb/lsb_base_expr地址開(kāi)始, 向上(+)/向下"-"截取width_expr位寬的數(shù)據(jù);
*/
在上面的代碼中,width_expr為常量表達(dá)式,代碼運(yùn)行時(shí)不能改變;lsb_base_expr/msb_base_expr 為整形表達(dá)式,在運(yùn)行時(shí)可以改變;代碼示例:
reg [31:0] big_vect;
reg [0:31] little_vect;
reg [63:0] dword;
integer sel;
big_vect[0 +:8] //==big_vect[7 :0], 從第0位向上截取8bit的數(shù)據(jù)
big_vect[15-:8] //==big_vect[15:8], 從第15位向下截取8bit的數(shù)據(jù)
little_vect[0 +:8] //==little_vect[0: 7]
little_vect[15-:8] //==little_vect[8:15]
dword[8*sel +: 8] //從第(8*sel)位截取8位寬
總結(jié)說(shuō)明:
在表達(dá)式vect[base_expr +:/-: width_expr]中,
width_expr為截取的固定位寬,是常量值;
base_expr為截取的 起始第bit位地址 ,可以 是整形變量值,動(dòng)態(tài)變更 ;
05 文章總結(jié)
對(duì)于一名優(yōu)秀的FPGA工程師而言,合理應(yīng)用數(shù)據(jù)位操作是一項(xiàng)非常重要的能力。對(duì)于一些特定的使用場(chǎng)合,合理使用數(shù)據(jù)位操作可以很大地節(jié)約邏輯資源。
-
FPGA
+關(guān)注
關(guān)注
1625文章
21628瀏覽量
601254 -
mcu
+關(guān)注
關(guān)注
146文章
16900瀏覽量
349948 -
Verilog
+關(guān)注
關(guān)注
28文章
1343瀏覽量
109927 -
語(yǔ)法
+關(guān)注
關(guān)注
0文章
44瀏覽量
9763
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論