4bit Full Adder
: 4비트의 두 이진수를 더하는 디지털 회로이다.
아래의 코드를 보다보면 always 문이 나온다.
Always 문
: block 내부에 있는 코드가 계속 실행됨. @ () 내부에 있는 port의 값에 변화가 생길 때마다 코드가 실행 됨.
- level sensitive :
@()
port의 값에 따라 코드가 실행됨. - edge sensitive :
@()
port의 edge[rising, falling]에 따라 코드가 실행됨.- rising = posedge, falling = negedge
- ex)
always @(posedge a) begin
→ a가 0에서 1로 변하는 그 순간, edge에서 코드가 실행됨. - 보통 edge sensitive가 많이 사용됨.
Adder_Fnd.v
`timescale 1ns / 1ps
module Adder_Fnd ( // top
input [7:0] a,
input [7:0] b,
input [1:0] fndSel,
output [3:0] fndCom,
output [7:0] fndFont,
output carry
);
wire [7:0] w_sum;
wire [3:0] w_digit_1, w_digit_10, w_digit_100, w_digit_1000;
wire [3:0] w_digit;
Decoder U_Decoder_2x4 (
.x(fndSel),
.y(fndCom)
);
Adder U_8bitAdder (
.a (a),
.b (b),
.cin(1'b0),
.sum(w_sum),
.co (carry)
);
digitSplitter U_DigitSplitter(
.i_digit({5'b00000, carry, w_sum}),
.o_digit_1(w_digit_1),
.o_digit_10(w_digit_10),
.o_digit_100(w_digit_100),
.o_digit_1000(w_digit_1000)
);
Mux U_Mux_4x1(
.sel(fndSel),
.x0(w_digit_1),
.x1(w_digit_10),
.x2(w_digit_100),
.x3(w_digit_1000),
.y(w_digit)
);
BCDtoSEG U_BcdToSeg (
.bcd(w_digit),
.seg(fndFont)
);
endmodule
: 8bitAdder에서 나온 sum 값을 DigitSplitter에서 1, 10, 100, 1000의 자리로 나누고, 4x1Mux를 거쳐 차례대로 빠르게 나타낸다.
Adder.v
`timescale 1ns / 1ps
module Adder (
input [7:0] a,
input [7:0] b,
input cin,
output [7:0] sum,
output co
);
wire [6:0] w_carry;
fullAdder U_FA0 (
.a (a[0]),
.b (b[0]),
.cin(cin),
.sum(sum[0]),
.co (w_carry[0])
);
fullAdder U_FA1 (
.a (a[1]),
.b (b[1]),
.cin(w_carry[0]),
.sum(sum[1]),
.co (w_carry[1])
);
fullAdder U_FA2 (
.a (a[2]),
.b (b[2]),
.cin(w_carry[1]),
.sum(sum[2]),
.co (w_carry[2])
);
fullAdder U_FA3 (
.a (a[3]),
.b (b[3]),
.cin(w_carry[2]),
.sum(sum[3]),
.co (w_carry[3])
);
fullAdder U_FA4 (
.a (a[4]),
.b (b[4]),
.cin(w_carry[3]),
.sum(sum[4]),
.co (w_carry[4])
);
fullAdder U_FA5 (
.a (a[5]),
.b (b[5]),
.cin(w_carry[4]),
.sum(sum[5]),
.co (w_carry[5])
);
fullAdder U_FA6 (
.a (a[6]),
.b (b[6]),
.cin(w_carry[5]),
.sum(sum[6]),
.co (w_carry[6])
);
fullAdder U_FA7 (
.a (a[7]),
.b (b[7]),
.cin(w_carry[6]),
.sum(sum[7]),
.co (co)
);
endmodule
module halfAdder (
input a,
input b,
output sum,
output carry
);
assign sum = a ^ b;
assign carry = a & b;
endmodule
module fullAdder (
input a,
input b,
input cin,
output sum,
output co
);
wire w_sum1, w_carry1, w_carry2;
halfAdder U_HA1 (
.a(a),
.b(b),
.sum(w_sum1),
.carry(w_carry1)
);
halfAdder U_HA2 (
.a(w_sum1),
.b(cin),
.sum(sum),
.carry(w_carry2)
);
assign co = w_carry1 | w_carry2;
endmodule
Mux.v
`timescale 1ns / 1ps
module Mux (
input [1:0] sel,
input [3:0] x0,
input [3:0] x1,
input [3:0] x2,
input [3:0] x3,
output reg [3:0] y
);
always @(sel, x0, x1, x2, x3) begin
case (sel)
2'b00: y = x0;
2'b01: y = x1;
2'b10: y = x2;
2'b11: y = x3;
default: y = x0;
endcase
end
endmodule
※ output reg를 쓰는 이유 : assign 문에서 변경된 값을 저장해야하기 때문.
output reg를 안쓸 경우:
- 밑에 reg를 선언해줘야 함.
- assign
(연속할당문)
사용하기. output은 기본적인 wire 타입이기 대문에 별도의 wire를 선언하지 않아도 가능.
digitSplitter.v
`timescale 1ns / 1ps
module digitSplitter (
input [13:0] i_digit,
output [ 3:0] o_digit_1,
output [ 3:0] o_digit_10,
output [ 3:0] o_digit_100,
output [ 3:0] o_digit_1000
);
assign o_digit_1 = i_digit % 10;
assign o_digit_10 = i_digit / 10 % 10;
assign o_digit_100 = i_digit / 100 % 10;
assign o_digit_1000 = i_digit / 1000 % 10;
endmodule
Decoder.v
`timescale 1ns / 1ps
module Decoder (
input [1:0] x,
output reg [3:0] y
);
always @(x) begin
case (x)
2'h0: y = 4'b1110;
2'h1: y = 4'b1101;
2'h2: y = 4'b1011;
2'h3: y = 4'b0111;
default: y = 4'b1110;
endcase
end
endmodule
BCDtoSEG.v
`timescale 1ns / 1ps
module BCDtoSEG (
input [3:0] bcd,
output reg [7:0] seg
);
always @(bcd) begin// bcd 변화가 감지되면 실행
case (bcd)
4'h0: seg = 8'hc0;
4'h1: seg = 8'hf9;
4'h2: seg = 8'ha4;
4'h3: seg = 8'hb0;
4'h4: seg = 8'h99;
4'h5: seg = 8'h92;
4'h6: seg = 8'h82;
4'h7: seg = 8'hf8;
4'h8: seg = 8'h80;
4'h9: seg = 8'h90;
4'ha: seg = 8'h88;
4'hb: seg = 8'h83;
4'hc: seg = 8'hc6;
4'hd: seg = 8'ha1;
4'he: seg = 8'h86;
4'hf: seg = 8'h8e;
default: seg = 8'hff;
endcase
end
endmodule
schemaitc
tb_Adder._sv
`timescale 1ns / 1ps
class transaction;
rand bit [3:0] a;
rand bit [3:0] b;
endclass
module tb_Adder_sv ();
reg [3:0] a;
reg [3:0] b;
wire [3:0] sum;
wire co;
transaction trans;
Adder dut ( // dut (design under test)
.a (a),
.b (b),
.cin(1'b0),
.sum(sum),
.co (co)
);
initial begin
trans = new();
for (int i = 0; i < 100; i++) begin
trans.randomize();
a = trans.a;
b = trans.b;
#10 $display("a:%d + b:%d = %d", trans.a, trans.b, sum);
if ((a+b) == sum) begin
$display("passed!");
end
else begin
$display("failed!");
end
end
#10 $finish;
end
endmodule
Tol Console
constraint
video
'[하만]세미콘 아카데미 > verilog' 카테고리의 다른 글
0510 clockCounter, upCounter (0) | 2024.06.22 |
---|---|
0510_8bitAdder_display (0) | 2024.06.22 |
0508 4bit_Full_Adder (0) | 2024.06.22 |
0508 half_Adder, full_Adder (0) | 2024.06.22 |
0508 gate (0) | 2024.06.22 |