[VerilogHDL] System Verilog, 4bit Adder FND 출력VerilogHDL/Study2024. 5. 16. 01:45
Table of Contents
1. System Verilog 문법 사용하여 Verification
4bit Adder Simulation
- 콘솔창에 출력하기
더보기
4bit Adder Desing source
`timescale 1ns / 1ps
module Adder (
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), // 1bit 이진수 0
.sum(sum[0]),
.cout(w_carry[0])
);
fullAdder U_FA1 (
.a(a[1]),
.b(b[1]),
.cin(w_carry[0]), // 1bit 이진수 0
.sum(sum[1]),
.cout(w_carry[1])
);
fullAdder U_FA2 (
.a(a[2]),
.b(b[2]),
.cin(w_carry[1]), // 1bit 이진수 0
.sum(sum[2]),
.cout(w_carry[2])
);
fullAdder U_FA3 (
.a(a[3]),
.b(b[3]),
.cin(w_carry[2]), // 1bit 이진수 0
.sum(sum[3]),
.cout(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 cout
);
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 cout = w_carry1 | w_carry2;
endmodule
Simulation source
`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 ( // design under test
.a (a),
.b (b),
.cin(1'b0),
.sum(sum),
.co (co)
);
initial begin
trans = new();
for (int i = 0; i < 10; i++) begin
trans.randomize();
a = trans.a;
b = trans.b;
#10 $display("a: %d + b: %d", trans.a, trans.b);
end
#10 $finish;
end
endmodule
더보기
`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 ( // design under test
.a (a),
.b (b),
.cin(1'b0),
.sum(sum),
.co (co)
);
initial begin
trans = new();
for (int i = 0; i < 10; i++) begin
trans.randomize();
a = trans.a;
b = trans.b;
#10 $display("a: %d + b: %d", trans.a, trans.b);
if((a+b) == sum) begin
$display("passed!");
end
else begin
$display("failed!");
end
end
#10 $finish;
end
endmodule
2. 4bit Adder FND 출력
- 4bit Adder 결과 값을 FND에 출력할 수 있는 형태로 바꿈
- ex) 결과 값이 9면 FND에서 9를 표시할 수 있도록 해당 segment ON
2-1. BCD to Seg Decoder 설계
- 2진수 4bit를 입력받아 그 값에 따라 16진수 형태로 FND 출력
DP | G | F | E | D | C | B | A | HEX | |
0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | C0 |
1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | F9 |
2 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | A4 |
3 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | B0 |
4 | 99 | ||||||||
5 | 92 | ||||||||
6 | 82 | ||||||||
7 | F8 | ||||||||
8 | 80 | ||||||||
9 | 90 | ||||||||
A | 99 | ||||||||
V | 83 | ||||||||
C | C6 | ||||||||
D | A1 | ||||||||
E | 86 | ||||||||
F | 8E |
구현
[BCDtoSEG 코드]
`timescale 1ns / 1ps
module BCDtoSEG (
input [3:0] bcd,
output reg [7:0] seg
// output은 기본적으로 wire(레지스터 할당 X) 형태로 되어 있어 값을 저장하지 못함
// -> ouput reg로 선언하면 저장 가능
);
always @(bcd) begin
case (bcd)
4'h0: seg = 8'hc0; // 4bit HEX 0, 8bit HEX C0
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
1. output은 기본적으로 wire(레지스터 할당 X) 형태로 되어 있어 값을 저장하지 못함
→ `output reg`로 선언하여 저장 후 FND로 출력
2. `always @(bcd)` : 감시하고 있다가 bcd값의 변화가 감지되면 case문 실행
ex) bcd == 1 이면 FND segment F9(숫자 1) 출력
⇒ Adder의 SUM을 bcd 입력으로 넣어주면 해당 값 FND segment 출력
2-2. Adder ~ Decoder 설계
- 오른쪽 자리 FND 하나만 출력
- 4bit Adder Sum값을 BCD to Seg의 입력으로 넣어준다.
위 그림대로 코딩
구현
[Design source 코드]
`timescale 1ns / 1ps
module Adder_FND (
input [3:0] a, // input 4bit
input [3:0] b, // input 4bit
output [3:0] fndCom, // FND Common
output [7:0] fndFont, // FND Segment
output carry
);
wire [3:0] w_sum;
assign fndCom = 4'b1110;
Adder U_4bitAdder (
.a (a),
.b (b),
.cin(1'b0),
.sum(w_sum),
.co (carry)
);
BCDtoSEG U_BcdToSeg (
.bcd(w_sum),
.seg(fndFont)
// output은 기본적으로 wire(레지스터 할당 X) 형태로 되어 있어 값을 저장하지 못함
// -> ouput reg로 선언하면 저장 가능
);
endmodule
하드웨어 구성
## Switches
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { a[0] }]; #IO_L19N_T3_A09_D25_VREF_14 ,Sch=SW0
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { a[1] }]; #IO_L19P_T3_A10_D26_14 ,Sch=SW1
set_property -dict { PACKAGE_PIN W16 IOSTANDARD LVCMOS33 } [get_ports { a[2] }]; #IO_L20P_T3_A08_D24_14 ,Sch=SW2
set_property -dict { PACKAGE_PIN W17 IOSTANDARD LVCMOS33 } [get_ports { a[3] }]; #IO_L20N_T3_A07_D23_14 ,Sch=SW3
set_property -dict { PACKAGE_PIN W15 IOSTANDARD LVCMOS33 } [get_ports { b[0] }]; #IO_L21N_T3_DQS_A06_D22_14 ,Sch=SW4
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { b[1] }]; #IO_L21P_T3_DQS_14 ,Sch=SW5
set_property -dict { PACKAGE_PIN W14 IOSTANDARD LVCMOS33 } [get_ports { b[2] }]; #IO_L22N_T3_A04_D20_14 ,Sch=SW6
set_property -dict { PACKAGE_PIN W13 IOSTANDARD LVCMOS33 } [get_ports { b[3] }]; #IO_L22P_T3_A05_D21_14 ,Sch=SW7
## LEDs
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { carry }]; #IO_L23N_T3_A02_D18_14 ,Sch=LED0
##7 segment display
set_property -dict { PACKAGE_PIN W7 IOSTANDARD LVCMOS33 } [get_ports { fndFont[0] }]; #IO_L13P_T2_MRCC_34 ,Sch=CA
set_property -dict { PACKAGE_PIN W6 IOSTANDARD LVCMOS33 } [get_ports { fndFont[1] }]; #IO_L13N_T2_MRCC_34 ,Sch=CB
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS33 } [get_ports { fndFont[2] }]; #IO_L14P_T2_SRCC_34 ,Sch=CC
set_property -dict { PACKAGE_PIN V8 IOSTANDARD LVCMOS33 } [get_ports { fndFont[3] }]; #IO_L14N_T2_SRCC_34 ,Sch=CD
set_property -dict { PACKAGE_PIN U5 IOSTANDARD LVCMOS33 } [get_ports { fndFont[4] }]; #IO_L16P_T2_34 ,Sch=CE
set_property -dict { PACKAGE_PIN V5 IOSTANDARD LVCMOS33 } [get_ports { fndFont[5] }]; #IO_L16N_T2_34 ,Sch=CF
set_property -dict { PACKAGE_PIN U7 IOSTANDARD LVCMOS33 } [get_ports { fndFont[6] }]; #IO_L19P_T3_34 ,Sch=CG
set_property -dict { PACKAGE_PIN V7 IOSTANDARD LVCMOS33 } [get_ports { fndFont[7] }]; #IO_L19N_T3_VREF_34 ,Sch=DP
set_property -dict { PACKAGE_PIN U2 IOSTANDARD LVCMOS33 } [get_ports { fndCom[0] }]; #IO_L9N_T1_DQS_34 ,Sch=DP
set_property -dict { PACKAGE_PIN U4 IOSTANDARD LVCMOS33 } [get_ports { fndCom[1] }]; #IO_L11P_T1_SRCC_34 ,Sch=DP
set_property -dict { PACKAGE_PIN V4 IOSTANDARD LVCMOS33 } [get_ports { fndCom[2] }]; #IO_L11N_T1_SRCC_34 ,Sch=DP
set_property -dict { PACKAGE_PIN W4 IOSTANDARD LVCMOS33 } [get_ports { fndCom[3] }]; #IO_L12N_T1_MRCC_34 ,Sch=D
- 스위치 : 덧셈 연산 할 4bit 2진수 2개 → 스위치 총 8개
- LED : Adder에서 Carry 발생할 경우 출력
- segment display : Segment 단자 8개 + Common 단자 4개
결과
2-3. 원하는 위치에 FND 출력
- 2x4 Decoder(입력 2개, 출력 4개)를 이용하여 2bit 입력하고 그 값에 따라 출력할 FND 선택
- 2x4 Decoder
입력 | 출력 | ||||
x1 | x2 | y3 | y2 | y1 | y0 |
0 | 0 | 1 | 1 | 1 | 0 |
0 | 1 | 1 | 1 | 0 | 1 |
1 | 0 | 1 | 0 | 1 | 1 |
1 | 1 | 0 | 1 | 1 | 1 |
구현
[2x4 Decoder 코드]
`timescale 1ns / 1ps
module Decoder2x4 (
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;
endcase
end
endmodule
ex) 스위치 2개로 10(2) 입력하면 왼쪽에서 2번째 FND 출력
⇒ 스위치의 상태에 따라 원하는 FND 출력
[Design source]
`timescale 1ns / 1ps
module Adder_FND (
input [3:0] a, // input 4bit
input [3:0] b, // input 4bit
input [1:0] fndSel,
output [3:0] fndCom, // FND Common
output [7:0] fndFont, // FND Segment
output carry
);
wire [3:0] w_sum;
//assign fndCom = 4'b1110;
Adder U_4bitAdder (
.a (a),
.b (b),
.cin(1'b0),
.sum(w_sum),
.co (carry)
);
BCDtoSEG U_BcdToSeg (
.bcd(w_sum),
.seg(fndFont)
// output은 기본적으로 wire(레지스터 할당 X) 형태로 되어 있어 값을 저장하지 못함
// -> ouput reg로 선언하면 저장 가능
);
Decoder2x4 U_2x4Decoder (
.x(fndSel),
.y(fndCom)
);
endmodule
- FND Selecter switch 2개 추가
set_property -dict { PACKAGE_PIN T1 IOSTANDARD LVCMOS33 } [get_ports { fndSel[0] }]; #IO_L3P_T0_DQS_34 ,Sch=SW14
set_property -dict { PACKAGE_PIN R2 IOSTANDARD LVCMOS33 } [get_ports { fndSel[1] }]; #IO_L1P_T0_34 ,Sch=SW15
결과
2-4. FND 10진수로 출력
- Adder의 결과값을 자리수에 맞춰 분리하는 회로 필요
⇒ Digit Splitter
- Digit Splitter : 10진수 0 ~ 9999 표현 → 약 2^14(14bit)
But, Adder는 출력이 Sum 4bit, Carry 1bit
⇒ 비트 결합 연산자 `{ }` 사용 → `{9'b0, carry, w_sum}` → MSB부터 9bit 0, carry 1bit, w_sum 4bit로 만들어준다.
구현
[Digit Splitter]
`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; // 1의 자리
assign o_digit_10 = i_digit / 10 % 10; // 10의 자리
assign o_digit_100 = i_digit / 100 % 10; // 100의 자리
assign o_digit_1000 = i_digit / 1000 % 10; // 1000의 자리
endmodule
[MUX]
`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 @(*) begin // ==always @(sel, x0, s1, 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
[Design source]
`timescale 1ns / 1ps
module Adder_FND (
input [3:0] a, // input 4bit
input [3:0] b, // input 4bit
input [1:0] fndSel,
output [3:0] fndCom, // FND Common
output [7:0] fndFont, // FND Segment
output carry
);
wire [3:0] w_sum;
wire [3:0] w_digit_1, w_digit_10, w_digit_100, w_digit_1000;
wire [3:0] w_digit;
Adder U_4bitAdder (
.a (a),
.b (b),
.cin(1'b0),
.sum(w_sum),
.co (carry)
);
DigitSplitter U_DigitSplitter(
.i_digit({9'b0, carry, w_sum}), // i_digit : 14bit
// {} : 비트 결합 연산자 -> MSB부터 9bit 0으로 채우고 Carry 1bit, w_sum 4bit
.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_4x1MUX (
.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)
// output은 기본적으로 wire(레지스터 할당 X) 형태로 되어 있어 값을 저장하지 못함
// -> ouput reg로 선언하면 저장 가능
);
Decoder2x4 U_2x4Decoder (
.x(fndSel),
.y(fndCom)
);
endmodule
결과
Made By Minseok KIM
'VerilogHDL > Study' 카테고리의 다른 글
[VerilogHDL] FSM 코딩(Moore, Mealy) - 버튼, UpCounter (0) | 2024.05.19 |
---|---|
[VerilogHDL] 조합 논리 회로 & 순차 논리 회로, Latch & FlipFlop (0) | 2024.05.19 |
[VerilogHDL] C&Verilog차이, SystemVerilog 기본, 8bit Adder FND, 만진 카운터 (0) | 2024.05.16 |
[VerilogHDL] HalfAdder, FullAdder, 4bit Adder (0) | 2024.05.09 |
[VerilogHDL] 반도체 칩 설계과정, Vivado 시작하기, 시뮬레이션, Logic Gates (0) | 2024.05.09 |
@민바Minba :: Minba's blog
Let's Be Happy!
도움이 되었으면 좋겠어요 :)