오늘은 지난 포스팅에 이어 Flip-Flop 에 대한 모듈 정의와 testbench 를 통한 파형 분석까지 학습하도록 하겠다. Flip-Flop 의 종류는 다양하지만, 많이 사용되는 D-FF 과 SR-FF 의 동작을 확인해보자.
positive edge triggered D Flip-Flop 의 동작을 이행하는 모듈을 생성하는 것이 첫번째 단계이다. 모듈 이름은 D_FF 로 정의하고 if 문을 통해 transparent 한 특성을 가지는 D-FF 의 특성을 구현시켜준다.
module D_FF(q,qbar,clk,rst,d);
output reg q;
output qbar;
input clk, rst;
input d;
assign qbar = ~q;
always @(posedge clk)
begin
if (rst)
q <= 0;
else
q <= d;
end
endmodule
다음으로는 생성된 모듈을 포함한 testbench 파일에 타이밍 정보를 입력하여 생명을 불어넣어줘야한다. wire 는 Data 를 연결, reg 는 Data 를 저장하는 변수이며 always 문 내에서 사용되는 변수는 앞에서 'reg' 로 선언되어야한다. 해당 코드를 확인해보면 현재 변수 d, rst, clk 이 always 문에서 사용되고 있기 때문에 변수들이 reg 로 선언된 것을 확인할 수 있다.
`include "D_FF.v"
`timescale 1ns/1ps
module D_FF_TB;
wire q, qbar;
reg clk,rst;
reg d;
D_FF d_ff(q,qbar,clk,rst,d);
always #5 clk = ~clk;
initial
begin
clk = 1'b0;
rst = 1; # 10; rst = 0; #10;
$display("RSLT\td\tq\tqbar");
d = 0; # 10; // Another value
if ( q === 1'b0 ) // Test for inversion
$display ("PASS\t%d\t%d\t%d",d,q,qbar);
else
$display ("FAIL\t%d\t%d\t%d",d,q,qbar);
d = 1; # 10; // Another value
if ( q === 1'b1 ) // Test for inversion
$display ("PASS\t%d\t%d\t%d",d,q,qbar);
else
$display ("FAIL\t%d\t%d\t%d",d,q,qbar);
#10;
$finish;
end
//enabling the wave dump
initial begin
$dumpfile("D_FF_TB.vcd");
$dumpvars(0, D_FF_TB);
end
endmodule
생성된 testbench 파일을 터미널에서 컴파일링 한 후 gtkwave 로 파형을 확인하면 다음과 같이 rst 이 1 일 때, q = 1, rst = 0 일 때 d = q 로 정상적인 동작을 하는 것을 확인할 수 있다.
첫번째로 SR-FF 의 동작 방식을 참고하여 2-bit 로 정의된 sr(Set/Reset) 의 값에 따른 output 변화를 case 문을 통해 분류해준다.
module SR_FF(q, qbar, clk, rst, sr);
output q;
reg q;
output qbar;
input clk, rst;
input [1:0] sr;
assign qbar = ~q;
always @(posedge clk)
begin
if (rst)
q <= 0;
else
case(sr)
2'b00: q <= q;
2'b01: q <= 0;
2'b10: q <= 1;
2'b11: q <= 1'bx;
endcase
end
endmodule
`include "SR_FF.v"
`timescale 1ns/1ps
module SR_FF_TB;
reg clk, rst;
reg [1:0] sr;
wire q;
wire qbar;
SR_FF sr_ff(.clk(clk), .rst(rst), .sr(sr), .q(q), .qbar(qbar));
always #5 clk = ~clk;
initial begin
clk = 1'b0; rst = 1; #10;
rst = 0; sr = 0; #10;
sr = 0; #10;
sr = 1; #10;
sr = 2; #10;
sr = 3; #10;
end
initial begin
$dumpfile("SR_FF_TB.vcd");
$dumpvars(0, SR_FF_TB);
end
endmodule
오늘까지가 기본적인 logic circuit 에 관한 내용이었다. 앞으로 Adder, Counter, Multiplier, Comparator 가 남았고... 비록 소스코드가 돌아다니고 있고 복사 붙여넣기만 하면 되는 일이지만 코드 분석이라도 열심히 해서 래퍼런스 없이도 코드를 능숙하게 짤 수 있는 정도로 연습해보려고 한다. 느리지만 정확하게!
To be continued...🫠