본문 바로가기
Circuit Design

[Verilog] Signed, unsigned

by jae_walker 2019. 12. 25.

Verilog에서 signed와 unsigned가 섞여서 연산되는 경우,

출력 bit-width와 sign bit 처리에 각별히 유의해야 한다.

-> 연산이 적용되는 signal에 type과 range를 주석으로 다는 습관을 들이자~~

 

1. unsigned = unsigned + unsigned

  - output bit-width만 주의하면 됨.

  ex) 아래에서 case 1처럼 a와 b의 범위가 bit-width로 표현 가능한 범위보다 작게 constraint가 걸려있다면 output도 worst case에 맞게 output을 4bit만 해도 문제가 없지만, case 2처럼 4bit로 표현가능한 전체 범위를 사용한다면 case 1으로는 overflow가 발생한다. 따라서, 변수에 특정 범위가 지정되어 있지 않다면, case 2처럼 worst case를 고려해 output bit-width를 지정해야 한다.

/////// case 1 //////
module unsigned_adder1 (
	input [3:0] a,			// 0 ~ 4
	input [3:0] b,			// 0 ~ 10
	output [3:0] result		// 0 ~ 14
);
	assign result = a + b;
endmodule

////// case 2 //////
module unsigned_adder2 (
	input [3:0] a,			// 0 ~ 15
	input [3:0] b,			// 0 ~ 15
	output [4:0] result		// 0 ~ 30
);
	assign result = a + b;
endmodule

 

2. signed = signed + singed

  - signed는 MSB가 부호임을 주의! -> MSB를 제외한 bit-width로 overflow가 나지 않는지 확인해야 함.

  ex) a와 b 모두 3, 7을 표현하는데 각각 2bit, 3bit만 필요하지만, 음수를 표현하기 위한 signed bit이 추가됨에 유의. result도 마찬가지.

module signed_adder (
	input signed [2:0] a,			// -3 ~ 3
	input signed [3:0] b,			// -7 ~ 7
	output signed [4:0] result		// -10 ~ 10
);
	assign result = a + b ;
endmodule

 

3. signed + unsigned ...?

  - signed 연산에 섞여 있는 unsigned의 MSB가 1일 경우 이를 signed bit로 오인하는 문제가 발생한다.

  - 따라서, 반드시 MSB에 sign bit로 인식할 수 있는 1'b0을 추가하고 signed로 변환해야 한다. ($signed{1'b0, ...})

  - 출력 bit-width : signed/unsigned를 모두 고려하여 output range를 계산하고, signed bit가 있음에 유의.

  ex) signed 4bit인 a는 range가 -3 ~ 3이고, unsigned 4bit인 b는 range가 0 ~ 7이다. 따라서, output range는 -3 ~ 10. -3은 signed bit 포함 3bit이면 가능하지만 10은 signed bit 포함 5bit가 필요하므로 output bittage는 [4:0]이다.

module mixed_adder (
	input signed  [3:0] a,		// -3 ~ 3
    input         [3:0] b,		// 0 ~ 7
	output signed [4:0] result  // -3 ~ 10
);
	assign result = a + $signed{1'b0, b};
endmodule

 

4. signed extension 하는 법

Q. case 1로 해도 ㄱㅊ??

////// case 1 //////
   wire signed [BW:0] a;
   wire signed [15:0] b;
   
   assign b = $signed(a);

////// case 2 //////
   wire signed [BW:0] a;
   wire signed [15:0] b;
   
   assign b = {{(15-BW){a[BW]}}, a[BW-1:0]}

 

 

5. signed/unsigned shift

   - Unsigned shift (= Logical shift) : 단순히 0을 채워 넣으면서 왼쪽 혹은 오른쪽으로 bit 이동.

Q. Arithmetic Left Shift할 때는 sign bit 유지 안되는 건가?

'Circuit Design' 카테고리의 다른 글

[RTL] Equivalence Checking  (0) 2021.08.26
[Verilog] 코드 최적화  (0) 2018.05.08
디지털집적회로 정리  (0) 2018.05.06
집적설 정리  (0) 2018.05.06
MOSFET - 기본 구조 및 동작, Threshold voltage  (3) 2018.05.04