1. 조합회로
1-1 4x1 MUX
module mux4x1 (sel,d0,d1,d2,d3,m1,m2);
input [1:0] sel;
input d0, d1, d2, d3;
output m1, m2;
wire m1;
reg m2;
assign m1 = (sel[1]) ? ( (sel[0]) ? d3 : d2) ) : ( (sel[0]) ? d1 : d0 );
always @ (sel,d0,d1,d2,d3)
if (sel==2'b11) m2 = d3;
else if (sel==2'b11) m2 = d2;
else if (sel==2'b11) m2 = d1;
else if (sel==2'b11) m2 = d0;
endmodule
4x1 MUX를 위와 같이 작성했다. assign문으로도 만들 수 있고 always ~ if 문으로도 만들 수 있지만, 중요한 것은 if 문 혹은 case문 사용시 꼭 default / else 를 써줘야 한다는 점이다.
위와 같이 else를 써주지 않고 mux_output m2를 만든 결과 스키매틱을 보면 MUX가 아닌 래치가 발생한 것을 확인할 수 있다.
1-2 비교기 (A greater than B)
module gt (a, b, agtb);
parameter BW = 4;
input [BW-1:0] a, b;
output reg agtb;
//reg agtb;
always @ (a, b)
begin
agtb = 1'b0;
if (a[3]>b[3]) agtb=1'b1;
else if ((a[3]==b[3]) && (a[2]>b[2])) agtb=1'b1;
else if ((a[3:2]==b[3:2]) && (a[1]>b[1])) agtb=1'b1;
else if ((a[3:1]==b[3:1]) && (a[0]>b[0])) agtb=1'b1;
else agtb=1'b0;
end
endmodule
a와 b의 값을 비교하여 a의 값이 더 클 경우 1을 출력하는 비교기이다. 유의해야 할 점은 자리수를 비교할 때, 백의 자리를 비교한다면, 조건문에 - 천의자리는 같다는 전제 하에 백의 자리는 클 경우로 작성해주어야 한다.
<테스트벤치>
module tb_abgt;
reg [3:0] a, b;
wire agtb;
gt U1 (a,b,agtb);
initial begin
a = 4'b0000; b = 4'b0000;
#10 a = 4'b1000; b = 4'b0000;
#10 a = 4'b1000; b = 4'b1000;
#10 a = 4'b1100; b = 4'b1000;
#10 a = 4'b1100; b = 4'b1100;
#10 a = 4'b1110; b = 4'b1100;
#10 a = 4'b1110; b = 4'b1110;
#10 a = 4'b1111; b = 4'b1110;
#10 a = 4'b1111; b = 4'b1111;
#10 a = 4'b0111; b = 4'b1111;
#10 a = 4'b1110; b = 4'b1111;
#10;
end
endmodule
테스트벤치로 시뮬레이션 돌린 결과이다. 파형을 보면 A가 B보다 클 때만 출력이 1이 되는 것을 확인할 수 있다.
2. 순차회로
2-1. D-f/f (synch, preset)
module d_ff_sync_pr (clk,pr,d,q);
input clk, pr, d;
output q;
reg q;
always @ (posedge clk)
if (pr) q <= 1'b1;
else q <= d;
endmodule
2-2 D-f/f (asynch)
module d_ff_async (clk,rst,d,q,qb);
input clk, rst, d;
output q,qb;
reg q;
assign qb = ~q;
always @ (negedge rst or posedge clk)
if (~rst) q <= 1'b0;
else q <= d;
endmodule
module tb_d_ff_async;
reg clk, rst, d;
wire q, qb;
d_ff_async u1 (clk,rst,d,q,qb);
always #100 clk = ~clk;
initial
begin
d = 1'b0; clk = 1'b0; rst =0;
#325 d = 1'b1;
#100 rst = 1'b1;
#425 d = 1'b0;
#270 d = 1'b1;
#100 rst = 1'b0;
#200 d = 1'b0;
#270 d = 1'b1;
#200;
$stop;
end
endmodule
3-2 0~15 counter
module mod16_cnt (arst, clk, q, tco);
input arst, clk;
output [3:0] q;
output tco;
reg [3:0] q;
always @ (posedge arst or posedge clk)
if (arst) q <= 4'b0000;
else q <= q + 1'b1;
//순차회로 조합회로 분리하는 것이 더 좋음
assign tco = (q == 4'b1111) ? 1'b0 : 1'b1;
// assign tco = ~(&q) //q가 모두 1이면 0나감 위와 같다
endmodule
module tb_mod16_cnt;
reg arst, clk;
wire [3:0] q;
wire tco;
mod16_cnt u1 (arst, clk, q, tco);
always #100 clk = ~clk;
initial
begin
arst = 1'b1; clk = 1'b0;
#400 arst = 1'b0;
#3600;
$stop;
end
endmodule
'[Harman교육] 베릴로그' 카테고리의 다른 글
[23.03.22] CPU설계 - Shifter unit (0) | 2023.03.22 |
---|---|
[23.03.21] CPU 설계 - ALU unit (0) | 2023.03.21 |
[23.03.20] CPU 설계 기초 (0) | 2023.03.20 |
[23.03.17] 무어/ 밀리 모델 (0) | 2023.03.17 |
[23.03.13] 조합회로와 순차회로 -1 (0) | 2023.03.16 |