ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 디지털 시스템: 베릴로그 문법정리 + Two's complement adder
    메모 및 기타 2020. 9. 17. 17:33

    베릴로그 프로그래밍 예시를 보면서 베릴로그 문법을 살펴보겠다.

     

     

    1. swap_bytes

     

     

    < swap_bytes > 

    module swap_bytes(in, out);
    input [31:0] in;
    output [31:0] out;
    
    assign out[31 -:8] = in[0 +:8],
    	out[23 -:8] = in[8 +:8],
    	out[15 -:8] = in[16 +:8],
    	out[7 -:8] = in[24 +:8];
    
    endmodule

     

    in이라는 input을 받고

    out이라는 ouput을 받는 swap_bytes 모듈을 만들었다. 

     

     

    in과 out을 32비트 변수로 저장해준다.

     

     

    assign문은 좌변에 변수, 우변에 수식을 넣어 산술 논리 조건 연산식을 

    사용할 수 있도록 한다.

     

     

    ex)

    a = 4'b0101;       b=4'b0011;

    assign x = a & b;      // x = 4'b0001

    assign y = a | b;       // y = 4'b0111

    assign z = ~^a;      // z = 1 

     

     

    out[31 - :8] = out[31:24]

    in[0 +:8] = in[7:0] 이므로

     

    out[31:24] = in[7:0] 이고 위 과정을 반복하면

     

    첫번째 부분을 네번째로

    두번째 부분을 세번째로

    세번째 부분을 두번째로

    네번째 부분을 첫번째로 옮겨진 32비트 값이 나온다. 

     

     

     

     

     

    < swap_bytes_tb >

    `timescale 1ns/100ps
    module swap_bytes_tb;
    reg [31:0] x;
    wire [31:0] y;
    
    swap_bytes U_swap(.in(x), .out(y));
    initial begin
    
    	x = 32'h1234_abcd;
    	#20 x = 32'habcd_1234;
    	#20 x = 32'h2222_1111;
    
    end
    endmodule

     

    swap_bytes의 테스트 벤치를 만들었다.

     

    가장 먼저 timescale을 정해준다. (timescale에 따라 앞으로의 시간딜레이가 결정된다)

     

    `timescale 1ns/1ps 라 한다면 

    시간 딜레이의 기준을 1ns, 1ps의 정확도로 측정하겠다는 뜻

     

    인풋은 reg로, 아웃풋은 wire로 정한다.

     

    swap_bytes 모듈을 가져다 쓸것이므로 

     

    swap_bytes 변수명(.in(x), .out(y)); 로 선언한다. (named association)

     

     

     initial문은 시뮬레이션을 위한 구문으로 순차적으로 신호를 인가할 때 사용한다.

     

    시뮬레이션이 시작하면 모든 initial 구문이 실행되어 파형을 만든다.

     

    여기서 #20은 20ns뒤에 실행하겠다는 의미(timescale에 의해 결정된다)

     

    실행하면 다음과 같은 결과를 얻을 수 있다.

     

     

    2. Two's complement adder

     

     

    덧셈 뺄셈이 가능한 Adder 

     

    sub가 0일때 덧셈, 1일때 뺄셈을 수행한다.

     

    sub가 0인 경우, x + y를 수행하고

    sub가 1인 경우, x - y이므로 

     

    2의 보수법을 사용하면 

    x + ~(y) + 1 이다  

     

     

     

    <two_adder>

    module twos_adder(x, y, c_in, sum, c_out);
    input [3:0] x,y;
    input c_in;
    output [3:0] sum;
    output c_out;
    wire [3:0] t;
    
    assign t = y^{4{c_in}};
    assign {c_out, sum} = x + t + c_in;
    endmodule

     

    c_in = 0 일때 t = y 이고

    c_in = 1 일때 t = ~ y이므로

    t = y^{4{cin}} 라 한다.

     

     

    여기서 {}는 결합연산자로 여러개의 피연산자를 묶어서 사용할 수 있다.

     

    ex)

     

    a = 2'b01, b = 2'b10, c = 4'b0101 일때

    x = {a, b[1], c[3:1]} 라하면

    x = 011010 이다  

     

    또한 x = {a, 4b[1], c} 라 하면

    b[1]을 4번 반복해서 쓸 수 있다는 의미로

    x = 0111110101 이다

     

     

     

    <two_adder_tb>

    `timescale 1ns/100ps
    module twos_adder_tb;
    parameter N = 4;
    reg[N-1:0]a,b;
    reg c_in;
    wire[N-1:0]sum;
    integer i;
    twos_adder U_TADD(.x(a), .y(b), .c_in(c_in),.sum(sum), .c_out(c_out));
    initial begin a = 0; b=0; c_in = 0; end
    always #20 a = a+1;
    initial for(i = 0;i<16;i=i+1)
    #20 b = 16-i;
    initial #320 c_in = 1;
    endmodule

     

    always #20 a = a+1

     

    20ns 마다 위 연산을 반복한다.

     

     

    begin end는 c언어에서 중괄호라고 생각하면 편하다.

     

    이건 다른 경우지만 참고하도록 하자. 

     

    반응형

    댓글

Designed by Tistory.