★ Negative level-sensitive 방식으로 동작하는 8비트 D래치회로를 설계하고, 테스트벤치를 작성하여 기능을 검증한다.
module dlatch8(clk,d,q);
input clk;
input [7:0] d;
output reg [7:0] q;
always@(*)begin
if(!clk) q=d;
end
endmodule
▣ TESTBENCH
// 설계과제 11.1 testbench
module tb_dlatch8;
reg clk;
reg [7:0] d;
wire [7:0] q;
dlatch8 uo(clk,d,q);
initial begin
clk = 1'b0;
d = 1'b0;
end
always begin
#15 d= 1'b1; #20 d=1'b0;
#10 d = 1'b1; #10 d= 1'b0;
end
always
#10 clk = ~clk;
endmodule
★ active-low 셋과 리셋을 갖는 negative level-sensitive 8bit D래치를 설계하고, 테스트벤치를 작성하여 기능을 검증한다.
// 설계과제 11.2
module d1latch8_set(clk,rst,d,q);
input clk, rst;
input [7:0] d;
output reg [7:0] q;
always@(*)begin
if(!rst) q=8'b0;
else if(!clk) q= d;
end
endmodule
▣ TESTBENCH
// 설계과제 11.2 testbench
module tb_dlatch8;
reg clk,rst;
reg [7:0] d;
wire [7:0] q;
d1latch8_set u0(clk,rst,d,q);
initial begin
clk = 1'b0;
rst = 1'b1;
d = 1'b0;
#20 rst = 1'b0;
#20 rst = 1'b1;
end
always begin
#15 d= 1'b1; #20 d=1'b0;
#10 d = 1'b1; #10 d= 1'b0;
end
always
#10 clk = ~clk;
endmodule
★ 다음 코드에서 blocking할당문의 순서를 바꾼경우이다. 바꾸기 전 회로와 동일한 회로인지, 만약 다른 회로라면 어떤 회로가 되는지 시뮬레이션과 합성을 통해 확인하고, 그 이유를 생각해본다.
▣ TESTBENCH
module tb_latch_blk2;
reg en,a,b,c;
wire y;
latch_blk2 u0(en,a,b,c,y);
always
#10 clk = ~clk;
initial begin
clk = 1'b0;
en = 1;
a = 0;
b = 0;
c = 1;
end
endmodule
위의 시뮬레이션 결과를 보면 80ns까지 X(unkonown) 값이 y로 출력되는데 이는 blocking의 특성을 잘 내타내는 시뮬레이션 입니다. DUT를 살펴보면 m값이 도출 되기전, y값에 m값이 필요합니다. (순서가 중요한 blocking) 즉, 출력 y를 나타내기 위해 m값이 필요한데 m값을 모르는 상태이니 출력 y값이 X(unkonwn)으로 출력되는 것 입니다.
★ 다음 코드는 nonblocking할당문의 순서를 바꾼 경우이다. 바꾸기 전 회로와 동일한 회로인지, 만약 다른 회로라면 어떤 회로가 되는지 시뮬레이션과 합성을 통해 확인하고, 그 이유를 생각해본다.
▣ TESTBENCH
module tb_latch_blk2;
reg en,a,b,c;
wire y;
latch_blk2 u0(en,a,b,c,y);
always
#80 en = ~en;
initial begin
en = 1;
a = 0;
b = 0;
c = 1;
#160 a = 1; b = 1; c =0;
end
endmodule
nonblocking 구문이 쓰인 두문장의 순서를 바꿔도 동일한 시뮬레이션 결과를 도출합니다. 위의 두 예제를 통해서 우리는 blocking할당문 nonblocking할당문의 차이를 알 수 있습니다.
★ q와 q_bar출력을 갖는 D플립플롭은 다음과 같이 모델링하면, 단순 D플립플롭이 아닌 다른 회로가 된다. 시뮬레이션과 합성을 통해 코드의 모델링이 어떤 회로로 동작하는지 확인하고, 그 이유를 생각해 본다.
q_bar에 nonblocking 할당문 ~q를 사용했다. 여기서 발생하는 문제점은 첫번째 nonblocking할당문에서 q에 d가 들어가기전 q의 값이 두번째 nonblocking할당문으로 들어가야하는데 이값은 아직 정해지지 않은 값이다. 그래서 q_bar가 q에 비해 더 긴 X(unkowun)값을 지늬고 있다. 또한 계속해서 그 이전의 q값이 q_bar에 들어가기때문에 q_bar가 q에 늦게 들어가는 형태의 시뮬레이션을 보이고 있다.
★ 일반적인 clock의 생성과 clock gating의 생성을 모델링하고, 시뮬레이션을 통해 동작을 확인한다.
module clk_gating(clk_i,clk_en,clk_o);
input clk_i, clk_en;
output clk_o;
assign clk_o = clk_i & clk_en;
endmodule
▣ TESTBENCH
module tb_clk_gating;
reg clk_i, clk_en;
wire clk_o;
clk_gating u0(clk_i,clk_en,clk_o);
always
#10 clk_i = ~clk_i;
initial begin
clk_i = 0;
clk_en = 1;
#100 clk_en = 0;
#100 clk_en = 1;
$finish;
end
endmodule
★ 다음의 D플립플롭을 Verilog HDL로 모델링하고, 시뮬레이션을 통해 동작을 확인한다.
① 동기식 active-high 리셋을 갖는 D 플립플롭
module dff_test1(
input clk,
input rst,
input d,
output reg q
);
always@(posedge clk)begin
if(rst) q <= 1'b0;
else q <= d;
end
endmodule
② 동기식 active-high 셋을 갖는 D 플립플롭
module dff_test2(
input clk,
input st,
input d,
output reg q
);
always@(posedge clk)begin
if(st) q <= 1'b1;
else q <= d;
end
endmodule
③ 동기식 active-low 셋과 리셋을 갖는 D플립플롭
module dff_test3(
input clk,
input rst,
input st,
input d,
output reg q
);
always@(posedge clk)begin
if(!rst) q <= 1'b0;
else if(!st) q<= 1'b1;
else q <= d;
end
endmodule
④ 비동기식 active-high 리셋을 갖는 D플립플롭
module dff_test4(
input clk,
input rst,
input d,
output reg q
);
always@(posedge clk or posedge rst)begin
if(rst) q <= 1'b0;
else q <= d;
end
endmodule
⑤ 비동기식 active-high 셋을 갖는 D플립플롭
module dff_test5(
input clk,
input st,
input d,
output reg q
);
always@(posedge clk or posedge st)begin
if(st) q <= 1'b1;
else q <= d;
end
endmodule
⑥ 비동기식 active-low 셋과 리셋을 갖는 D플립플롭
module dff_test6(
input clk,
input rst,
input st,
input d,
output reg q
);
always@(posedge clk or posedge rst or posedge st)begin
if(!rst) q <= 1'b0;
else if(!st) q<= 1'b1;
else q <= d;
end
endmodule
★ 다음의 D플립플롭을 모델링하고 시뮬레이션을 통해 동작을 확인한다.
module d_ff_test(
input clk,
input sync_reset,
input async_reset,
input async_reset_n,
input i_value,
output reg o_value_sync_reset,
output reg o_value_async_reset,
output reg o_value_async_reset_n,
output reg o_value_mixed_reset,
output reg o_vlaue_no_rest
);
// 1. sync reset
always@(posedge clk)begin
if(sync_reset) begin
o_value_async_reset <= 1'b0;
end
else begin
o_value_async_reset <= i_value;
end
end
// 2. async_reset
always@(posedge clk or posedge async_reset)begin
if(async_reset) o_value_async_reset <= 1'b0;
else o_value_async_reset <= i_value;
end
// 3. async_reset_n
always@(posedge clk or negedge async_reset_n)begin
if(!async_reset_n) o_value_async_reset_n <= 1'b0;
else o_value_async_reset_n <= i_value;
end
// 4. mixed
always@(posedge clk or posedge async_reset or posedge sync_reset)begin
if(async_reset) o_value_mixed_reset <= 1'b0;
else if(sync_reset) o_value_mixed_reset <= 1'b0;
else o_value_mixed_reset <= i_value;
end
// 5. no reset
always@(posedge clk)begin
o_vlaue_no_rest <= i_value;
end
endmodule
▣ TESTBENCH
module tb_d_ff_test;
reg clk;
reg clk_enable;
reg sync_reset;
reg async_reset;
reg async_reset_n;
reg i_value;
wire o_value_sync_reset;
wire o_value_async_reset;
wire o_value_async_reset_n;
wire o_value_mixed_reset;
wire o_vlaue_no_rest;
always begin
#10 clk = ~clk;
end
initial begin
clk = 0;
clk_enable = 0;
sync_reset = 0;
async_reset = 0;
async_reset_n = 1;
i_value = 1;
#50
sync_reset = 1;
async_reset = 1;
async_reset_n = 0;
#20
sync_reset = 1;
async_reset = 1;
async_reset_n = 0;
#20
clk_enable = 1;
#20
sync_reset = 1;
#20
sync_reset = 0;
end
wire clk_dut = clk && clk_enable;
d_ff_test u0(clk_dut,sync_reset,async_reset,async_reset_n,i_value,o_value_sync_reset,o_value_async_reset,o_value_async_reset_n,o_value_mixed_reset,o_vlaue_no_rest);
endmodule
'UVM & RTL > Verilog HDL' 카테고리의 다른 글
[27] Verilog HDL blocking할당문과 nonblocking할당문 설계과제 (2) | 2022.03.05 |
---|---|
[26] Verilog HDL 순차회로에서 blocking할당문과 nonblocking할당문 (0) | 2022.03.05 |
[24] Verilog HDL 순차회로 (LATCH, FILP FLOP) (0) | 2022.03.05 |
[23] Verilog HDL 순차회로 설계과제 (COMPARATOR, TRI-STATE) (0) | 2022.03.05 |
[22] Verilog HDL 조합회로 구현 (COMPARATOR, TRI-STATE) (0) | 2022.03.05 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!