Updated at 25-04-11
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와 동일하다.
`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
벡터의 다양한 특징에 대해서 알려주는 문제이다.
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]이 되는데 왜 인덱스 반전시킬땐 안 되는지 모르겠다
성격이 이상해
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;는 에러를 일으킨다.
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가 배열이다. 위에서 잘못 이해했다.
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]과 같은 접근이 가능하다.
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 사이 변환을 구현하는 문제이다.
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비트로 나오는 것을 확인할 수 있다.
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입력 논리 게이트의 구현이다. 어려울 건 없다.
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과 같이 상수도 삽입할 수 있다.
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
module top_module (
input [7:0] in,
output [31:0] out );
assign out = {{24{in[7]}}, in};
endmodule
{n{vector}}와 같이 써서 복제가 가능하다. vector를 n번 이어 붙인 결과가 나온다. 바깥에도 { }를 감싸줘야 함을 주의한다.
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
이어붙인 상태로 복사하는 것과, 복사한 상태로 이어붙이는 것의 차이를 활용하는 문제다.