이번 장에서 배울 것
- task
- barrel shifter
앞장에서 배운 function과 비슷한 기능을 하는 것이 task이다. function과 마찬가지로 여러개의 code를 묶어서 함수 호출하듯이 불러 쓸 수 있다. 그러나 task문에서는 delay문을 기술할 수 있다.
우선 이번 장에서 설계할 shiter에 대해서 알아보자.
shifter는 여러 bit로 구성 된 입력을 원하는 bit 수 만큼 좌/우로 이동 시키는 것을 말한다.
예를 들어 4'b0100을 입력으로 받아 오른 쪽으로 2bit 이동 시키면 4'b0001이 된다. 또는 왼쪽으로 2bit 이동 시키면 4'b0000이 된다. bit 수를 넘어가면 그 값은 사라지게 된다. verilog에서 이런 기능을 하는 shift 연산자가 있는데 오른 쪽 shift는 '>>' , 왼쪽 shift는 '<<' 기호를 사용한다. 예를 들어 A변수를 오른 쪽으로 2bit이동 시키는 것은 A >> 2; 라는 문장으로 표현할 수 있고 왼쪽으로 2bit shift하는 것은 A << 2; 라고 표현 할 수 있다. 그리고 이렇게 한번에 여러 bit를 shift할 수 있는 shifter를 barrael shifter라고 한다.
이런 기능을 task로 표현하면 아래와 같다.
task shifter (input [7:0] a, input [2:0] num, input left_right, output [7:0] y);
begin
if (left_right == 0) // shift right
y = #1 a >> num;
else
y = #1 a << num;
end
endtask
'task' keyword 다음에는 task 이름이 오고 뒤에 오는 괄호안에 입력과 출력 파라메터를 정의한다.
여기서 'a'는 shift할 값 즉 오퍼랜드(operand)이고 num은 shift할 bit 수, 그리고 left_right는 좌/우 shift를 명시하는 파라메터로 여기서 '0'은 right shift, '1'은 left shift를 의미하는 것으로 약속한다. 그리고 출력 변수는 y로 정의한다. 또한 task문에서 delay 문을 기술할 수 있는 것을 보여 주기 위해 'y'변수 대입 문에 #1 과 같은 delay문을 사용하였다. 이는 a를 shift한 값을 1ns 이후에 y에 대입한다는 의미이다.
이 task를 이용한 barrel shifter는 아래와 같이 코딩할 수 있다.
module barrel_shifter (
input clock,
input resetn,
input [7:0] a,
input [2:0] num,
input left_right,
output reg [7:0] y
);
reg [7:0] result;
task shifter (input [7:0] a, input [2:0] num, input left_right, output [7:0] y);
begin
if (left_right == 0) // shift right
y = #1 a >> num;
else
y = #1 a << num;
end
endtask
always @(posedge clock or negedge resetn)
begin
if (~resetn)
y <= 0;
else
begin
shifter(a, num, left_right, result);
y <= result;
end
end
endmodule
시뮬레이션을 수행하기 위한 테스트 벤치는 아래와 같다. 앞장의 테스트 벤치와 형태는 거의 동일하다.
입력 변수들은 모두 non-blocking assignment로 값을 대입해 주었다.
`timescale 1ns/1ns
module test;
// delare variables
reg clock;
reg resetn;
reg [7:0] a;
reg [2:0] num;
reg left_right;
wire [7:0] y;
// clock generation
always #10 clock = ~clock;
// shifter instantiation
barrel_shifter u_shifter (
.clock (clock),
.resetn (resetn),
.a (a),
.num (num),
.left_right (left_right),
.y (y)
);
// create wave dump file
initial
begin
$dumpfile("shifter.vcd");
$dumpvars(0, test);
end
// input stimulus
initial
begin
a <= 0;
num <= 0;
left_right <= 0;
clock <= 0;
resetn <= 0;
#100;
resetn <= 1;
a <= 2;
num <= 1;
@(posedge clock);
left_right <= 1;
a <= 4;
num <= 2;
@(posedge clock);
#100;
$finish();
end
endmodule
아래와 같이 컴파일하고 시뮬레이션 및 wave form 확인 할 수 있다.
>>iverilog test.v shifter.v
>>./a.out
>>gtkwave shifter.vcd&
아래는 결과 wave form이다.
clock의 positive edge 부분을 확대해서 보면 아래 그림과 같이 출력 y가 1ns 지연되어 출력되는 것을 알 수 있다.
'실전! Verilog HDL RTL Design' 카테고리의 다른 글
[Verilog HDL] 12. IP, Bus, SoC (0) | 2022.08.01 |
---|---|
[Verilog HDL] 11. ALU (Arithmetic Logic Unit) 설계 (2) | 2022.06.03 |
[Verilog HDL] 9. Function 을 사용한 뺄샘기(Subtractor) 설계 (0) | 2022.05.11 |
[Verilog HDL] 8. 순차논리 (Sequential Logic) Adder 설계 (0) | 2022.05.04 |
[Verilog HDL] 7. 순차논리 (Sequential Logic) 회로 설계 (D F/F) (0) | 2022.04.10 |