이번 포스트에서는 Verilog에서의 연산자에 대해서 정리해보도록 할게요.
연산자 같은 경우는 설명할 부분이 많지 않아서 모아서 정리해놓고 간간히 필요할 때 찾아 사용해도 좋을 것 같습니다.
- 산술 연산자(Arithmetic Operator)
Operator | Description |
a + b | a plus b |
a - b | a minus b |
a * b | a muliplied by b |
a / b | a divided by b |
a % b | a modulo b |
a ** b | a to the power by b |
산술 연산자는 너무나 잘 알고 있는 부분이죠.
더하기, 빼기, 곱하기, 나누기 이외에 %는 나머지를 구하는 연산자, a**b는 a의 b제곱 연산을 의미합니다.
간단하게 코드를 짜서 결과를 확인해볼까요?
module operator(
input wire [31:0] a,
input wire [31:0] b,
output reg [63:0] result_add,
output reg [63:0] result_sub,
output reg [63:0] result_mul,
output reg [63:0] result_div,
output reg [63:0] result_mod,
output reg [63:0] result_pow
);
always @(*) begin
result_add = a + b;
result_sub = a - b;
result_mul = a * b;
result_div = a / b;
result_mod = a % b;
result_pow = a ** 32'd2;
end
endmodule
위와 같이 코드를 작성해서 Testbench에서 a = 10, b = 4를 넣고 결과를 확인해봅시다.
결과가 Hex로 표현되어 있는데 add의 결과를 보면 e(10+4 = 14), sub의 결과 6(10-4 = 6), mul의 결과 28(10*4 = 40),
div의 결과 2(10/4의 몫 = 2), mod의 결과 2(10/4의 나머지 2), pow의 결과 64(10^2 = 100)으로 잘 나타나네요.
- 관계연산자(Relational Operator)
Operator | Description |
a < b | a less than b |
a > b | a greater than b |
a <= b | a less than b or equal to b |
a >= b | a greater than b or equal to b |
관계연산자는 대소비교를 하는 연산자로 조건에서 많이 쓰이게 되는데요.
이 부분은 알던 이상, 이하, 초과, 미만과 동일하게 때문에 따로 Simulation은 없이 넘어가도록 합시다.
- 동일 연산자(Equality Operator)
Operator | Description |
a === b | a equal to b, including x and z |
a !== b | a not equal to b, including x and z |
a == b | a equal to b, result can be unknown |
a != b | a not equal to b, result can be unknown |
동일 연산자에는 연산자가 세개(===, !==)가 들어가는 것과 두개(==, !=)가 들어가는 것이 나눠져 있는데
연산자가 세개인 것들은 x, z 상태까지 고려해 동일성 검사를 하기 때문입니다.
여기서 x, z 상태란 x는 unknown으로 어떤 값인지 모르는 상태(확신할 수 없는 상태)이고
z는 High-Impedance로 선이 연결되어 있지 않은 상태 등을 의미합니다.
예를 들어 unknow값을 포함한 111x과 111x을 서로 비교할 때,
==은 unknown(x)이 존재하기에 unknown(x)으로 판단하지만 ===은 같다고 판단하게 되는데 정말 그런지 한번 확인해보고 넘어갑시다.
module operator(
input wire [31:0] a,
input wire [31:0] b,
output reg [63:0] result_equal,
output reg [63:0] result_equal_incxz
);
always @(*) begin
result_equal = (a == b);
result_equal_incxz = (a === b);
end
endmodule
result_equal은 ==의 결과, result_equal_incxz는 ===의 결과를 출력하도록 하였고 a와 b모두 111x을 넣어봅시다.
정말 ==은 a, b가 같은지에 대해서 x(unknown) 판정을 내렸고 ===는 같다고 판정했네요!
- 논리 연산자(Logical Opeartor)
Operator | Description |
a && b | evaluates to true if a and b are true |
a || b | evaluates to true if a or b are true |
!a | converts non-zero value to zero, and vice versa |
논리 연산자에서 &&는 AND 연산, ||는 OR 연산, !는 NOT 연산입니다.
이 부분은 따로 확인하지 않아도 당연한 것이니 넘어가겠습니다.
- 비트 연산자(Bitwise Operator)
Operator | Description |
a & b | evaluates to true if a and b are true with its corresponding bit |
a | b | evaluates to true if a or b are true with its corresponding bit |
a ^ b | evaluates to true if a xor b are true with its corresponding bit |
비트 연산자는 논리 연산자와 다르게 비트 단위로 검사를 합니다.
예를 들어 a = 1011, b = 1101이 있다고 했을 때,
Logical AND연산, a && b를 하게되면 a가 0이 아니고 b가 0이 아니니 단순히 1이 나오게 되지만
Bitwise AND연산, a & b를 하게 되면 비트별로 and연산을 진행해서 1001이라는 결과가 나오게 됩니다.
이것도 한번 확인해보고 넘어갈까요?
module operator(
input wire [31:0] a,
input wire [31:0] b,
output reg [63:0] result_and,
output reg [63:0] result_and_bit
);
always @(*) begin
result_and = (a && b);
result_and_bit = (a & b);
end
endmodule
이와 같이 코드를 구성하고 a=1011, b=1101을 넣어봅시다.
위에서 이야기했던 대로 Logical 연산과 Bitwise 연산의 차이를 확실히 알 수 있습니다.
- 이동 연산자(Shift Operator)
Operator | Description |
<< | Logical Shift Left |
>> | Logical Shift Right |
<<< | Arithmetic Shift Left |
>>> | Arithmetic Shift Right |
마지막으로 이동연산자입니다.
이동 연산자도 동일 연산자와 비슷하게 2개짜리가 있고 3개짜리가 있네요.
차이를 보자면 <<, >>, <<<같은 경우에는 Shift가 일어나고 빈자리에 0이 채워지는
반면 >>>의 경우, 빈자리가 MSB의 부호로 채워지게 됩니다.
예를 들어, 1011을 Logical Shift Right(>>2)를 하면 0010이 되는데
Arithmetic Shift Right(>>>2)를 하면빈자리가 여기서 MSB인 1로 채워지기 때문에 1110이 되겠네요.
이런 Arithmetic Shift는 보통 Signed Number를 Shift할 때 쓰인다고 합니다.
이것도 한번 확인해보고 이번 포스트는 마치도록 해볼게요!
module operator(
input wire signed [3:0] a,
output reg [3:0] result_log_shi,
output reg [3:0] result_ari_shi
);
always @(*) begin
result_log_shi = (a >> 2);
result_ari_shi = (a >>> 2);
end
endmodule
위와 같이 코드를 작성해서 1011을 오른쪽으로 2번 Logical Shift와 Arithmetic Shift를 해봅시다.
공부한 대로 Logical Shift 연산시에는 0010, Arithmetic Shift 연산시에는 1110으로 나타나는 것을 확인할 수 있습니다.
최근댓글