2.2 Verilog Language - Vectors

Kiwoong Nam·2025년 4월 11일

HDLBits

목록 보기
2/11

Updated at 25-04-11

Vectors

Vector0

module top_module ( 
    input wire [2:0] vec,
    output wire [2:0] outv,
    output wire o2,
    output wire o1,
    output wire o0  ); // Module body starts after module declaration
    assign outv = vec;
    assign o2 = vec[2];
    assign o1 = vec[1];
    assign o0 = vec[0];

endmodule

벡터의 사용법을 알려주는 문제이다. C언어의 배열과 대충 비슷한데, 선언시 wire [2:0] w와 같이 길이가 이름 앞에 온다는 특징이 있으며, 길이가 그대로 오는게 아닌 MSB와 LSB 번호가 온다. 인덱스 접근은 C와 동일하다.

Vectors in more detail

Vector1

`default_nettype none     // Disable implicit nets. Reduces some types of bugs.
module top_module( 
    input wire [15:0] in,
    output wire [7:0] out_hi,
    output wire [7:0] out_lo );
    assign out_hi = in[15:8];
    assign out_lo = in[7:0];

endmodule

벡터의 다양한 특징에 대해서 알려주는 문제이다.

Declaring Vectors

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.

벡터의 선언의 다양한 방법들이다. 범위에 음의 정수를 넣을 수도 있고, output이라고 써도 wire가 생략된 것으로 간주되어 문제없이 선언된다.
선언할 때는 [0:7]이 되는데 왜 인덱스 반전시킬땐 안 되는지 모르겠다
성격이 이상해

Implicit nets

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.

assign 구문을 통해 암시적으로 wire의 선언이 가능한데, 이 경우 반드시 1-bit wire로 선언된다. 따라서 중간의 assign c = b;는 에러를 일으킨다.

Packed Arrays

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.

벡터가 구조체이고 packed가 배열이다. 위에서 잘못 이해했다.

Part-Select

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.

다양한 방법으로 벡터의 요소에 접근할 수 있다. 인덱스는 처음에 선언한 범위를 따라가기 때문에, x[0]이 아닌 x[1]이 LSB를 가리키고, b[0:3]과 같은 접근이 가능하다.

Vector part select

Vector2

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

Little-endian과 Big-endian 사이 변환을 구현하는 문제이다.

Bitwise operators

Vectorgates

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_bitwise = a|b;
    assign out_or_logical = a||b;
    assign out_not[5:3] = ~b;
    assign out_not[2:0] = ~a;

endmodule

그림에 주어진 회로를 적절히 구현하면 되는 문제이다. bitwise or은 결과값이 같은 길이의 벡터로 나오지만, logical or은 1비트로 나오는 것을 확인할 수 있다.

Four-input gates

Gates4

module top_module( 
    input [3:0] in,
    output out_and,
    output out_or,
    output out_xor
);
    assign out_and = in[0]&in[1]&in[2]&in[3];
    assign out_or = in[0]|in[1]|in[2]|in[3];
    assign out_xor = in[0]^in[1]^in[2]^in[3];

endmodule

4입력 논리 게이트의 구현이다. 어려울 건 없다.

Vector concatenation operator

Vector3

module top_module (
    input [4:0] a, b, c, d, e, f,
    output [7:0] w, x, y, z );
    assign {w, x, y, z} = {a, b, c, d, e, f, 2'b11};

endmodule

{ } 연산자를 이용해 벡터를 이어붙여서 사용할 수 있음을 알려주는 문제이다. assign 구문의 우변에는 2b'11과 같이 상수도 삽입할 수 있다.

Vector reversal 1

Vectorr

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]};

endmodule

처음에 assign out[7:0] = in[0:7];로 썼는데 안 돼서 당황했다. 이딴 식의 reversal은 지원하지 않는다고 한다.
always문과 for문을 이용하는 방법도 있다.

	always @(*) begin	
		for (int i=0; i<8; i++)	// int is a SystemVerilog type. Use integer for pure Verilog.
			out[i] = in[8-i-1];
	end

Replication operator

Vector4

module top_module (
    input [7:0] in,
    output [31:0] out );
    assign out = {{24{in[7]}}, in};

endmodule

{n{vector}}와 같이 써서 복제가 가능하다. vector를 n번 이어 붙인 결과가 나온다. 바깥에도 { }를 감싸줘야 함을 주의한다.

More replication

Vector5

module top_module (
    input a, b, c, d, e,
    output [24:0] out );//
    wire[24:0] op1;
    wire[24:0] op2;
    assign op1 = {5{a, b, c, d, e}};
    assign op2 = {{5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}}};
    assign out = ~(op1 ^ op2);

endmodule

이어붙인 상태로 복사하는 것과, 복사한 상태로 이어붙이는 것의 차이를 활용하는 문제다.

0개의 댓글