verilog 5

2023. 3. 13. 11:14Verilog

Task와 Function

반복되는 행위수준 모델링을 task와 함수라 정의하고, 이들을 호출해서 사용한다. Task와 fucntion은 소스코드의 가독성과 디버깅을 쉽게 한다. 

function은 하나의 값을 반환하는 c언어의 정수, 실수형 함수들과 유사하고, task는 void와 유사하다. 둘의 공통점은 모듈 내에서 선언되어야 하고, 선언된 모듈내에서만 호출 가능하다. 또 둘 다 내부에서 wire(net 자료형)은 가질 수 없고, wire를 사용할 수 없기 때문에 continuous assignment문을 사용할 수 없다. 

function

 

  • [size_or_type]에는 함수 결과값의 속성 및 범위를 지정하며, 별도의 지정이 없으면 1비트 reg형으로 선언된다. 
  • 함수가 정의되면 함수 이름과 동일한 이름의 변수가 내부에 선언되며, 따라서 함수의 이름을 사용할 수 없다. 

 

함수의 사용 예

function [7:0] GetByte; // 함수 정의
	input [63:0] word; // 선언 순서는 호출 모듈에서 인수 순서와 동일
	input [3:0] bytenum;
	integer bit;
	reg [7:0] temp;
	begin
	for (bit=0; bit<=7; bit=bit+1)
		temp[bit] = word[((bytenum-1)*8)+bit];
		GetByte = temp; // 함수 반환 값, 함수 이름과 동일
	end
endfunction
// 함수 호출 예
this_byte = GetByte(data, 4);

함수를 사용한 시프터

module fshift (data, direct, mode, result);
input [7:0] data;
input direct, mode;
output [7:0] result;
wire [7:0] result;
assign result = (mode) ? (rotate(data, direct)): (shift (data, direct));
function [7:0] shift;
	input [7:0] data;
	input direct;
	shift = (direct == 1) ? (data >> 1) : (data << 1); //자신의 이름으로 return
endfunction
function [7:0] rotate;
	input [7:0] data;
	input direct;
	rotate = (direct) ? {data[0], data[7:1]} : {data[6:0], data[7]}; //자신의 이름으로 return
endfunction
endmodule

task

 

  • 인수가 없거나 input, output, inout 모두 사용 가능하고, 정의에서 사용하느 순서로 인수 전달
  • 태스크 내부에 #, @, wait 등의 시간 제어 연산자 사용 가능

태스크를 사용한 1개수 카운트

module bit_count (clk, data, bnbr);
input clk;
input [15:0] data;
output [4:0] bnbr;
reg [4:0] bnbr;
always @ ( posedge clk)
count_ones( data, bnbr);
task count_ones;
	input [15:0] din;
	output [4:0] count;
	reg [4:0] count;
	reg [4:0] i; // loop index
	begin
		count = 0;
		for (i=0; i<16; i=i+1)
		if (din[i]) count = count + 1; // 1 count
	end
endtask

Test bench

  • HDL(Hardware Description language)로 설계한 회로의 동작을 확인하기 위한 HDL 프레임워크
  • DUT(Design Under Test) : 하드웨어를 합성하기 위한 회로로 입력 파형이 인가되면 설계된 회로의 동작에 따라 출력이 생성되는 모듈
  • Response monitor : DUT의 출력 파형을 연결
  • 테스트 벤치 모듈은 입력 및 출력 포트가 없다.

TB 구조

  • DUT : 하드웨어 모듈의 인스턴스
  • Stimulus Generator : 동작적 모델링으로 작성되는 파형 생성기
  • Response Monitor : 출력파형으로 동작 확인
  • 한개의 Verilog 모듈로 작성

TB 작성

TB 신호 선언

Stimulus 작성

주기적인 파형

  • 시간에 따라 일정한 주기로 반복되는 파형
  • always 문을 사용하고, 시간에 대한 진행사항 포함

비주기적인 파형

  • 시간에 따라 임의적으로 변하는 파형
  • initial문을 사용하고, 시간에 대한 진행사항 포함

Timescale 작성

타임스케일 설정

  • 컴파일러 지시어
  • 시뮬레이터의 시간간격과 시간분해능력 설정
  • time_unit / time_precision
  • 사용 가능한 단위 : s, ms, us, ns, ps, fs

Ring Counter 테스트하기

 

`timescale 1ns / 1ps


module Decoder_2X4(
        input[1:0] x,
        input en,
        output reg[3:0] y
    );

    always @(en, x) begin
        if(en)
            case(x)
                2'b00 : y = 4'b0001;
                2'b01 : y = 4'b0010;
                2'b10 : y = 4'b0100;
                2'b11 : y = 4'b1000;
                default : y = 4'b0;
            endcase
        else
            y = 4'b0;
    end

endmodule
`timescale 1ns / 1ps

module cnt8(
    input clk, rst,
    output reg [2:0] q
    );

    always @(posedge clk or negedge rst) begin
        if(~rst)
            q<= 3'b0;
        else 
            q <= q+1'b1;
    end
endmodule
`timescale 1ns / 1ps

module ring_counter(
        input clk, rst,
        output [7:0] seq
    );

    wire [2:0] CQ;
    wire enb;

    assign enb = ~CQ[2];
    Decoder_2X4 U1(.en(CQ[2]),.x(CQ[1:0]),.y(seq[7:4]));
    Decoder_2X4 U0(.en(enb), .x(CQ[1:0]), .y(seq[3:0]));
    cnt8 C0(.clk(clk), .rst(rst), .q(CQ));
endmodule
`timescale 1ns / 1ps

module tb;

reg clk = 1, rst = 1;
wire [7:0] cnt_out;

ring_counter R1(.clk(clk), .rst(rst), .seq(cnt_out));

initial begin
    rst = 0;
    #100 rst = 1;
end

always #50 clk = ~clk;

endmodule

링카운터 테스트벤치

클록 주기 100ns마다 1씩 쉬프트가 잘 되는 모습을 볼 수 있다. 

'Verilog' 카테고리의 다른 글

verilog 9 카운터 실습  (0) 2023.03.15
verilog7  (0) 2023.03.14
verilog 3  (0) 2023.03.10
Verilog-2  (0) 2023.03.09
Verilog  (0) 2023.03.08