8bitAdder_display
: 8비트의 두 이진수를 더하는 디지털 회로이다.



adder.v
`timescale 1ns / 1ps
module Adder_8bit (
input [7:0] a,
input [7:0] b,
input cin,
output [7:0] sum,
output co
);
wire w_carry0;
Adder_4bit U_4bit_Adder0(
.a(a[3:0]),
.b(b[3:0]),
.cin(cin),
.sum(sum[3:0]),
.co(w_carry0)
);
Adder_4bit U_4bit_Adder1(
.a(a[7:4]),
.b(b[7:4]),
.cin(w_carry0),
.sum(sum[7:4]),
.co(co)
);
endmodule
module Adder_4bit(
input [3:0] a,
input [3:0] b,
input cin,
output [3:0] sum,
output co
);
wire [2: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 (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
adder_fnd.v
`timescale 1ns / 1ps
module adder_fnd (
input clk,
input [7:0] a,
input [7:0] b,
output [3:0] fndCom,
output [7:0] fndFont
);
wire [7:0] w_sum;
wire w_carry;
Adder_8bit U_Adder (
.a (a),
.b (b),
.cin(1'b0),
.sum(w_sum),
.co (w_carry)
);
fndController U_fndController (
.clk(clk),
.digit({5'b0, w_carry, w_sum}),
.fndFont(fndFont),
.fndCom(fndCom)
);
endmodule
fndController
`timescale 1ns / 1ps
module fndController (
input clk,
input [13:0] digit,
output [ 7:0] fndFont,
output [ 3:0] fndCom
);
wire [3:0] w_digit_1, w_digit_10, w_digit_100, w_digit_1000;
wire [3:0] w_digit;
wire [1:0] w_count;
wire w_clk_1khz;
clkDiv #(.MAX_COUNT(100_000)) U_ClkDiv( // (100_000)이 없으면 default
.clk(clk),
.o_clk(w_clk_1khz)
);
counter #(.MAX_COUNT(4)) U_Counter_2bit(
.clk(w_clk_1khz),
.count(w_count)
);
Decoder U_Decoder_2x4 (
.x(w_count),
.y(fndCom)
);
digitSplitter U_DigitSplitter (
.i_digit(digit),
.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 (
.sel(w_count),
.x0 (w_digit_1),
.x1 (w_digit_10),
.x2 (w_digit_100),
.x3 (w_digit_1000),
.y (w_digit)
);
BCDtoSEG U_BcdToSeg0 (
.bcd(w_digit),
.seg(fndFont)
);
endmodule
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
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
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
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
module counter #(parameter MAX_COUNT = 4)(
input clk,
output [1:0] count
);
reg [1:0] counter = 0;
assign count = counter; // wire은 assign으로 연결해야함.
always @(posedge clk) begin
if (counter == MAX_COUNT - 1) begin
counter <= 0;
end
else begin
counter <= counter + 1;
end
end
endmodule
module clkDiv #(parameter MAX_COUNT = 100)(
input clk,
output o_clk
);
reg [$clog2(MAX_COUNT)-1:0] counter = 0; // [16:0]으로 만들어줌. $clog2 : log2()
reg r_tick = 0 ;
assign o_clk = r_tick;
always @(posedge clk) begin
if (counter == (MAX_COUNT - 1)) begin // 100M -> 100k
counter <= 0;
r_tick <= 1'b1;
end
else begin
counter <= counter + 1;
r_tick <= 1'b0;
end
end
endmodule
schematic


tb_adder
`timescale 1ns / 1ps
class transaction;
rand logic [7:0] a;
rand logic [7:0] b; // logic = reg
endclass // transaction
module tb_adder();
transaction trans;
logic [7:0] a, b, sum;
logic co;
Adder_8bit dut(
.a(a),
.b(b),
.cin(1'b0),
.sum(sum),
.co(co)
);
initial begin
trans = new();
repeat(10000) begin
trans.randomize();
a = trans.a;
b = trans.b;
#10;
$display("%t : a(%d) + b(%d) = sum(%d)", $time, trans.a, trans.b, {co,sum});
if ((trans.a + trans.b) == {co, sum}) $display("passed!");
else $display("failed!");
end
end
endmodule
simulation

- co : 256
constraint


video
'[하만]세미콘 아카데미 > verilog' 카테고리의 다른 글
0513 clock_upCounter | 2024.06.22 |
---|---|
0510 clockCounter, upCounter | 2024.06.22 |
0509 4bit_Full_Adder & FND 표시 | 2024.06.22 |
0508 4bit_Full_Adder | 2024.06.22 |
0508 half_Adder, full_Adder | 2024.06.22 |