HDLBits答案(2)_Verilog向量基础
HDLBits_Verilog向量基礎知識
HDLBits鏈接
向量
在Verilog中,對向量維度的聲明在向量名之前,這點與C語言有所差異,但使用向量的時候維度信息仍在向量名后。
wire [99:0] my_vector; // Declare a 100-element vector assign out = my_vector[10]; // Part-select one bit out of the vector向量的更多知識
聲明向量
type [upper:lower] vector_name;
type 指定了向量的數據類型,通常為reg或wire類型。如果聲明的是輸入、輸出向量的話,類型前還可以加上input和output,如下所示:
wire [7:0] w; // 8-bit wire reg [4:1] x; // 4-bit reg output reg [0:0] y; // 1-bit reg that is also an output port (this is still a vector) input wire [3:-2] z; // 6-bit wire input (negative ranges are allowed) output [3:0] a; // 4-bit output wire. Type is 'wire' unless specified otherwise. wire [0:7] b; // 8-bit wire where b[0] is the most-significant bit.向量的大小端是指最不重要的位具有較低的索引([3:0])還是較高的索引([0:3]),一旦用特定的索引規則定義了向量,就要用相同的方式去使用它。
[David說]:向量聲明時數字的順序很重要,它決定了向量是以大端存儲或者小端存儲。舉例說明,若聲明wire [3:0] w,則w[0]為w的最低位,w[3]為w的最高位;若聲明為wire [0:3] w,則與上述結果相反。所以在向量的定義和使用時一定要保持大小端一致!
未定義的中間變量容易出錯
使用wire型變量前請先聲明,不要圖一時之便直接未定義就拿來做中間變量,這樣導致的錯誤會很難發現。
wire [2:0] a, c; // Two vectors assign a = 3'b101; // a = 101 assign b = a; // b = 1 implicitly-created wire assign c = b; // c = 001 <-- bug my_module i1 (d,e); // d and e are implicitly one-bit wide if not declared.// This could be a bug if the port was intended to be a vector.向量名前為維度,向量名后為數目,不寫統統視作1。(可類比C語言中的數組,向量名前為數組元素的數據類型,向量名后為數組長度;或者形象化的表述為:維度即為每個房子的大小,數目為房子的總數目)
reg [7:0] mem [255:0]; // 256 unpacked elements, each of which is a 8-bit packed vector of reg. reg mem2 [28:0]; // 29 unpacked elements, each of which is a 1-bit reg.獲取向量元素:部分選擇
訪問整個向量是使用向量名完成的,如:assign w = a;如果左右兩邊的長度不匹配,則根據情況對向量進行補零或截斷。
向量的部分選擇操作可以訪問向量的一部分。(向量聲明來自上面"聲明向量"部分)
w[3:0] // Only the lower 4 bits of w x[1] // The lowest bit of x x[1:1] // ...also the lowest bit of x z[-1:-2] // Two lowest bits of z b[3:0] // Illegal. Vector part-select must match the direction of the declaration. b[0:3] // The upper 4 bits of b. assign w[3:0] = b[0:3]; // Assign upper 4 bits of b to lower 4 bits of w. w[3]=b[0], w[2]=b[1], etc.[David說]:取用向量中特定維度的數時一定注意要與向量的定義一致,注意大小端匹配的問題。
題目描述:
構建一個電路將一個4byte的數中的字節順序調轉,常用于數據的大小端轉換。
AaaaaaaaBbbbbbbbCcccccccDddddddd => DdddddddCcccccccBbbbbbbbAaaaaaaa
Solution:
module top_module( input [31:0] in,output [31:0] out );assign out[31:24] = in[7:0];assign out[23:16] = in[15:8];assign out[15:8] = in[23:16];assign out[7:0] = in[31:24];endmodule[David說]:在向量賦值的左右兩端都可以選擇對部分數據進行操作。
對向量進行門操作
位操作運算符VS邏輯操作運算符
對兩個Nbit位寬的向量而言,按位操作輸出為Nbit位寬向量;而邏輯操作將整個向量視為布爾值(true =非零,false =零)并產生一個1bit的輸出。
**題目描述1:**對向量特定部分的數據進行按位操作和邏輯操作。
Solution1:
module top_module( input [2:0] a,input [2:0] b,output [2:0] out_or_bitwise,output out_or_logical,output [5:0] out_not );assign out_or_logical = a || b;assign out_or_bitwise = a | b;assign out_not[5:3] = ~b;assign out_not[2:0] = ~a; endmodule題目描述2:
對輸入向量進行按位的與、或和異或操作。
Solution2:
module top_module( input [3:0] in,output out_and,output out_or,output out_xor );assign out_and = ∈ // &in = in[3]&in[2]&in[1]&in[0]assign out_or = |in;assign out_xor = ^in; endmodule[David說]:合理利用縮位運算符精簡代碼,按位進行邏輯運算,結果為1bit數。
- 與縮位運算符:&
- 或縮位運算符:|
- 異或縮位運算符:^
- 與、或、異或運算符和非運算符組成的復合運算符:&,|, ~,^
向量拼接操作
向量拼接操作需要知道待拼接的各向量的位寬,否則你怎么知道結果的位寬?所以{1,2,3}是無效的,因為你未指定向量位寬。
向量的拼接操作在賦值的左右兩端均可使用。
input [15:0] in; output [23:0] out; assign {out[7:0], out[15:8]} = in; // Swap two bytes. Right side and left side are both 16-bit vectors. assign out[15:0] = {in[7:0], in[15:8]}; // This is the same thing. assign out = {in[7:0], in[15:8]}; // This is different. The 16-bit vector on the right is extended to// match the 24-bit vector on the left, so out[23:16] are zero.// In the first two examples, out[23:16] are not assigned.[David說]:1、位寬合并需知道各成分的確切位寬,否則結果位寬不定。2、位寬合并時在assign兩端均可實現,最好左右兩端位寬相同,否則未被指定的數據會被置零。
題目描述:
給定幾個輸入向量,將它們拼接在一起,然后將它們分割成幾個輸出向量。有6個5位輸入向量:a, b, c, d, e, f,總共30位輸入。對于32位的輸出,有4個8位的輸出向量:w、x、y和z。輸出應該是輸入向量與兩個“1”位的串聯:
Solution:
module top_module (input [4:0] a, b, c, d, e, f,output [7:0] w, x, y, z );wire [31:0] temp;assign temp = {a,b,c,d,e,f,2'b11};assign {w,x,y,z}=temp; endmodule向量翻轉
題目描述:
給定一個8位輸入向量[7:0],顛倒它的位順序。
Solution1:
module top_module( input [7:0] in,output [7:0] out );assign out={in[0],in[1],in[2],in[3],in[4],in[5],in[6],in[7]}; endmoduleSolution2:
module top_module( input [7:0] in,output [7:0] out );integer i;always@(*)beginfor(i = 0;i < 8;i = i + 1)beginout[i]=in[7-i];endend endmodule[David說]:建議使用Solution2實現,可擴展性強。
向量復制操作
向量復制操作允許重復一個向量并將它們連接在一起:{num{vector}}
例如:
{5{1'b1}} // 5'b11111 (or 5'd31 or 5'h1f) {2{a,b,c}} // The same as {a,b,c,a,b,c} {3'd5, {2{3'd6}}} // 9'b101_110_110. It's a concatenation of 101 with// the second vector, which is two copies of 3'b110.[David說]:復制向量有捷徑,花括外面帶數字。主要用于符號位的拓展。如4’b0101帶符號拓展為8bit的話為8’b00000101,4’b1101帶符號拓展為8bit數為8’b11111101。
**題目描述:**建立一個電路,將8位數字擴展到32位。這需要將符號位的24個副本(即將位[7]復制24次)與8位數字本身連接起來。
Solution:
module top_module (input [7:0] in,output [31:0] out );assign out = { {24{in[7]}} , in };endmodule**題目描述2:**給定5個1位信號(a、b、c、d和e),計算25位輸出向量中所有25個成對的1位比較。如果兩個被比較的位相等,輸出應該是1。
out[24] = ~a ^ a; // a == a, so out[24] is always 1. out[23] = ~a ^ b; out[22] = ~a ^ c; ... out[ 1] = ~e ^ d; out[ 0] = ~e ^ e;[David說]:該操作可以定位特定signal所在位置,兩向量重復數據有規律可循,可用復制的方式來產生,簡化代碼。
Solution:
module top_module (input a, b, c, d, e,output [24:0] out );assign out = ~{5{a,b,c,d,e}} ^ {{5{a}},{5{b}},{5{c}},{5ze8trgl8bvbq},{5{e}}};endmodule總結:
學習了向量操作的相關知識,包括聲明、選擇部分數據、合并、復制等操作。
總結
以上是生活随笔為你收集整理的HDLBits答案(2)_Verilog向量基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#发送电子邮件 (异步) z
- 下一篇: HDLBits答案(3)_Verilog