Kraklog
[Study] 디지털 논리 회로 설계 본문
프로그램 : Quaturs Prime lite edition 18.1, VScode , Model SIM
사용문법 : Verilog 2001
보드 : DE1-SOC
들어가기에 앞서,
Verilog HDL은 VHDL과 함께 가장 일반적으로 쓰이는 HDL중 하나이다.
Verilog는 95년도에 IEEE 표준으로 채택되었고, verilog-95 standard로 이용되었으나, 2001년 문법체계가 업데이트 되었다.
HDL을 이용해 모델링때 사용되는 Abstraction level (추상화 레벨)은 다음과 같다.
- 알고리즘 레벨 : Behavior level (동작레벨)이라고도 불리며, 순차적인 방법으로 표현된다. 즉, 알고리즘이 순서에 맞게 실행되는 명령어로 구성되어 있다.
- 레지스터 전달 레벨 : Data flow 라고도 불리며 회로를 데이터 이동으로 표현 한 것.
RTL 설계에서는 외부 클럭이 사용되고, 동기화된 시간에 동작이 발생하도록 스케줄 된다. - 게이트 레벨 : 시스템 동작을 논리 게이틔 연결로 표현 한다. 모든 신호들의 입력 값은 0 1 x z 의 논리 값을 갖으며 논리 소자들을 연결하는 것과 유사함.
- 스위치 레벨 : 가장 저 레벨의 추상화이며, MOS 트랜지스터를 이용해 게이트 내부의 동작을 나타낸다.
1. 기본 논리 게이트
◎ 코드 작성
// Verilog code for logic gates
module AndOr(
input a ,
input b ,
output OUT_OR ,
output OUT_AND ,
output OUT_NOT
);
assign OUT_AND = a&b;
assign OUT_OR = a|b;
assign OUT_NOT = ~a;
endmodule
a,b의 입력을 받는 AND OR NOT 게이트의 블록 다이어그램을 작성하고, 이를 Verilog 를 이용해서 표현했다.
입력에는 1과 0 의 2진수만을 받을것이기 때문에 [1:0]을 선언해주었어도 되었을듯하다.
assign 구문을 통해 출력부를 할당해주었고, & (and 연산) | (or 연산) ~ (Not 연산) 을 통해 값을 넣도록 했다.
&& 와 &의 차이점은 논리연산인지 아닌지에대한 차이점을 갖고 있다.
◎ Simulation
model sim을 사용하위해 test bench (테스트 벤치)를 작성해주었다. 입력핀은 reg로 연결해주고 출력핀은 wire를 통해 연결해주었다.
이를 다이어그램으로 표현하면 다음과 같다.
module tb_AndOr();
reg a ;
reg b ;
wire OUT_OR ;
wire OUT_AND ;
wire OUT_NOT ;
AndOr U_AndOr(
.a (a ),
.b (b ),
.OUT_OR (OUT_OR ),
.OUT_AND(OUT_AND),
.OUT_NOT(OUT_NOT)
);
initial begin
a=0;
b=0;
#10
a=2'b1;
b=2'b0;
#10 a=2'b0;
b=2'b1;
#10 a=2'b1;
b=2'b1;
end
endmodule
model sim의 tcl 기능을 사용하기 위해 do 파일을 작성했다.
work 라이브러리를 선언하고, AndOr과 tb_AndOr의 코드를 비교하는데 시뮬레이션은 tb_AndOr를 이용하기로 선언하고
tb_AndOr 중 a b OUT_AND OUT_OR OUT_NOT을 wave에 추가하라는 명령어이다.
vlib work
vlog AndOr.v tb_AndOr.v
vsim -t ns work.tb_AndOr
view wave
add wave -radix bin /a
add wave -radix bin /b
add wave -radix bin /OUT_AND
add wave -radix bin /OUT_OR
add wave -radix bin /OUT_NOT
run 50 ns
그 값을 시뮬레이션을 통해서 봤을때 예상한 값이 나옴을 알 수 있다.
예시로 15ns 값을 보면 a와 b는 각 1,0 이 들어오고 있다.
and 연산을 하면 0, OR 연산을 하면 1, ~a 는 0 임을 계산해볼 수 있는데 시뮬레이션 또한 같은 값을 보인다.
2. 전가산기
앞선 포스트에서 Full Adder는 많이 다뤘지만, 다시 해보기로 했다.
Full Adder 는 조합 논리회로를 이해하기 좋은 예제로 잘 알려져 있다.
이번 과정에서는 카르노맵, 진리표, 논리식을 이용해서 작성하는것이 목표이다.
◎ 코드 작성
module Full_Adder (
input X ,
input Y ,
input Z ,
output reg C ,
output reg S
);
assign k_C = (X&Y)|(X&Z)|(Y&Z); //Used Karnaugh Map
assign k_S = (X&~Y&~Z)|(~X&~Y&Z)|(X&Y&Z)|(~X&Y&~Z);
//used Logic
assign o_XY1 = (X^Y);
assign o_Sum = (o_XY1 ^ Z);
assign O_carry = ((o_XY1)&Z)|(X&Y);
wire [2:0] w_full;
assign w_full = {X , Y , Z}; //Used Truth table
always @(w_full) begin
case (w_full)
3'b001 : begin
C <= 1'b0;
S <= 1'b1;
end
3'b010 : begin
C <= 1'b0;
S <= 1'b1;
end
3'b011 : begin
C <= 1'b1;
S <= 1'b0;
end
3'b100 : begin
C <= 1'b0;
S <= 1'b1;
end
3'b101 : begin
C <= 1'b1;
S <= 1'b0;
end
3'b110 : begin
C <= 1'b1;
S <= 1'b0;
end
3'b111 : begin
C <= 1'b1;
S <= 1'b1;
end
default: begin
C <= 1'b0;
S <= 1'b0;
end
endcase
end
endmodule
설계 순서는 다음과 같다.
1. 카르노맵을 이용한 설계
2. 논리식을 이용한 설계
3. 진리표를 이용한 설계
◎ Simulation
module tb_Full_Adder ();
reg X;
reg Y;
reg Z;
wire C;
wire S;
Full_Adder u_Full_Adder(
.X(X) ,
.Y(Y) ,
.Z(Z) ,
.C(C) ,
.S(S)
);
initial begin
X=0; Y=0; Z=0;
#10
X=0; Y=0; Z=1;
#20
X=0; Y=1; Z=0;
#30
X=0; Y=1; Z=1;
#40
X=1; Y=0; Z=0;
#50
X=1; Y=0; Z=1;
#60
X=1; Y=1; Z=0;
#70
X=1; Y=1; Z=1;
end
endmodule
vlib work
vlog Full_Adder.v tb_Full_Adder.v
vsim -t ns work.tb_Full_Adder
view wave
add wave -radix bin /X
add wave -radix bin /Y
add wave -radix bin /Z
add wave tb_Full_Adder/u_Full_Adder/k_C
add wave tb_Full_Adder/u_Full_Adder/k_S
add wave tb_Full_Adder/u_Full_Adder/o_Sum
add wave tb_Full_Adder/u_Full_Adder/O_carry
add wave tb_Full_Adder/u_Full_Adder/w_full
run 500ns
k_C, k_S 는 카르노맵을 이용한 Carry와 Sum
o_Carry , o_Sum 은 논리식을 이용한 Carry 와 Sum
C와 S는 진리표를 이용한 Carry 와 Sum이다.
모두 진리표와 같은 출력을 갖는다.
3. 디코더
//build Decorder - Case
module Decoder1 (
input [2:0] inp ,
input en ,
output reg [7:0] o_Dec
);
always @(*) begin
0_Dec = 8'h00; //define case default
if (en) begin
case (inp)
3'h1 : o_Dec = 8'h01;
3'h2 : o_Dec = 8'h02;
3'h3 : o_Dec = 8'h03;
3'h4 : o_Dec = 8'h04;
3'h5 : o_Dec = 8'h05;
3'h6 : o_Dec = 8'h06;
3'h7 : o_Dec = 8'h07;
default : o_Dec = 8'h00;
endcase
end
end
endmodule
//build Decorder - assign
module Decoder2 (
input [2:0] inp ,
input en ,
output [7:0] o_Dec
);
assign o_Dec = (en) ? 1'b1 << inp : 8'h00;
endmodule
4. 입출력 장치 실습
푸시버튼 스위치 값 LED 표현
module SwitchEncoder (
input clk ,
input [15:0] key ,
output reg [3:0] keyval
);
always @(posedge clk) begin
case (key)
16'b0000_0000_0000_0001 : keyval = 4'b0000;
16'b0000_0000_0000_0010 : keyval = 4'b0001;
16'b0000_0000_0000_0100 : keyval = 4'b0010;
16'b0000_0000_0000_1000 : keyval = 4'b0011;
16'b0000_0000_0001_0000 : keyval = 4'b0100;
16'b0000_0000_0010_0000 : keyval = 4'b0101;
16'b0000_0000_0100_0000 : keyval = 4'b0110;
16'b0000_0000_1000_0000 : keyval = 4'b0111;
16'b0000_0001_0000_0000 : keyval = 4'b1000;
16'b0000_0010_0000_0000 : keyval = 4'b1001;
16'b0000_0100_0000_0000 : keyval = 4'b1010;
16'b0000_1000_0000_0000 : keyval = 4'b1011;
16'b0001_0000_0000_0000 : keyval = 4'b1100;
16'b0010_0000_0000_0000 : keyval = 4'b1101;
16'b0100_0000_0000_0000 : keyval = 4'b1110;
16'b1000_0000_0000_0000 : keyval = 4'b1111;
default: ;
endcase
end
endmodule
module SwitchEncoder_tb;
reg clk;
reg [15:0] key;
wire [3:0] keyval;
SwitchEncoder uut (
.clk(clk),
.key(key),
.keyval(keyval)
);
// 클럭 생성
initial begin
clk=0;
forever
#10 clk = ~clk;
end
initial begin
key = 16'b0;
#10 key=16'b1;
#20 key=16'd2;
forever
#20 key = key +2;
end
endmodule
vlib work
vlog SwitchEncoder.v SwitchEncoder_tb.v
vsim -t ns work.SwitchEncoder_tb
view wave
add wave -radix bin /clk
add wave -radix unsigned /key
add wave -radix unsigned /keyval
run 200ns
7segment 2개를 이용한 16진수 표현
세그먼트를 나타내는 방식은 다음과 같다.
case (input value)
트리거 1 : FND = 7'b000_0000;
...
트리거 last : FND = 7'b000_0000;
default : ;
endcase
module Segment (
input clk ,
input [3:0] sw1 ,
input [3:0] sw2 ,
output reg [6:0] FND1 ,
output reg [6:0] FND2
);
always @(posedge clk) begin
case (sw1)
4'b0001 : FND1 = 7'b011_0000;
4'b0010 : FND1 = 7'b110_1101;
4'b0011 : FND1 = 7'b111_1001;
4'b0100 : FND1 = 7'b011_0011;
4'b0101 : FND1 = 7'b101_1011;
4'b0110 : FND1 = 7'b101_1111;
4'b0111 : FND1 = 7'b111_0010;
4'b1000 : FND1 = 7'b111_1111;
4'b1001 : FND1 = 7'b111_1011;
4'b1010 : FND1 = 7'b111_0111;
4'b1011 : FND1 = 7'b001_1111;
4'b1100 : FND1 = 7'b100_1110;
4'b1101 : FND1 = 7'b011_1101;
4'b1110 : FND1 = 7'b100_1111;
4'b1111 : FND1 = 7'b100_0111;
default: FND1 = 7'b111_1110;
endcase
case (sw2)
4'b0001 : FND2 = 7'b011_0000;
4'b0010 : FND2 = 7'b110_1101;
4'b0011 : FND2 = 7'b111_1001;
4'b0100 : FND2 = 7'b011_0011;
4'b0101 : FND2 = 7'b101_1011;
4'b0110 : FND2 = 7'b101_1111;
4'b0111 : FND2 = 7'b111_0010;
4'b1000 : FND2 = 7'b111_1111;
4'b1001 : FND2 = 7'b111_1011;
4'b1010 : FND2 = 7'b111_0111;
4'b1011 : FND2 = 7'b001_1111;
4'b1100 : FND2 = 7'b100_1110;
4'b1101 : FND2 = 7'b011_1101;
4'b1110 : FND2 = 7'b100_1111;
4'b1111 : FND2 = 7'b100_0111;
default: FND2 = 7'b111_1110;
endcase
end
endmodule
module tb_Segment (
);
reg clk ;
reg [3:0] sw1 ;
reg [3:0] sw2 ;
wire [6:0] FND1 ;
wire [6:0] FND2 ;
Segment u_segment1(
.clk (clk ),
.sw1 (sw1 ),
.sw2 (sw2 ),
.FND1(FND1),
.FND2(FND2)
);
initial begin
clk=0;
forever
#10 clk = ~clk;
end
initial begin
sw1=4'b0;
#10 sw1=4'd1;
forever
#10 sw1 = sw1+1;
end
initial begin
sw2=4'b0;
forever
#10 sw2 = sw2+sw1;
end
endmodule
module Segment_kar (
input [3:0] sw1 ,
output [6:0] FND
);
assign FND[6] = ~sw1[3] & ~sw1[2] & ~sw1[1] & sw1[0]
| ~sw1[3] & sw1[2] & ~sw1[1] & ~sw1[0]
| sw1[3] & sw1[2] & ~sw1[1] & sw1[0]
| sw1[3] & ~sw1[2] & sw1[1] & sw1[0] ; //a
assign FND[5] = sw1[2] & sw1[1] & ~sw1[0]
| sw1[3] & sw1[1] & sw1[0]
| ~sw1[3] & sw1[2] & ~sw1[1] & sw1[0]
| sw1[3] & sw1[2] & ~sw1[1] & ~sw1[0] ; //b
assign FND[4] = ~sw1[3] & ~sw1[2] & sw1[1] & ~sw1[0]
| sw1[3] & sw1[2] & sw1[1]
| sw1[3] & sw1[2] & ~sw1[0]; //c
assign FND[3] = ~sw1[3] & ~sw1[2] & ~sw1[1] & sw1[0]
| ~sw1[3] & sw1[2] & ~sw1[1] & ~sw1[0]
| sw1[3] & ~sw1[2] & sw1[1] & ~sw1[0]
| sw1[2] & sw1[1] & sw1[0] ; //d
assign FND[2] = ~sw1[3] & sw1[0]
| ~sw1[3] & sw1[2] & ~sw1[1]
| ~sw1[2] & ~sw1[1] & sw1[0] ;//e
assign FND[1] = ~sw1[3] & ~sw1[2] & sw1[0]
| ~sw1[3] & ~sw1[2] & sw1[1]
| ~sw1[3] & sw1[1] & sw1[0]
| sw1[3] & sw1[2] & ~sw1[1] & sw1[0] ; //f
assign FND[0] = ~sw1[3] & ~sw1[2] & ~sw1[1]
| sw1[3] & sw1[2] & ~sw1[1] & ~sw1[0]
| ~sw1[3] & sw1[2] & sw1[1] & sw1[0] ; //g
endmodule
module tb_Segment_kar (
);
reg [3:0] sw1 ;
wire [6:0] FND ;
Segment_kar u_Segment_kar1(
.sw1 (sw1 ),
.FND (FND )
);
initial begin
sw1=4'b0;
#10 sw1=4'd1;
forever
#10 sw1 = sw1+1;
end
endmodule
5. 4x1멀티플렉서
module my_mux4x1(
input [1:0] s,
input [3:0] i,
output reg y
);
always @(*)
begin : MUX
case(s)
2'b01:y=i[1];
2'b10:y=i[2];
2'b11:y=i[3];
default : y=i[0];
endcase
end
endmodule
`timescale 1ns/1ns // 시뮬레이션 스케일을 설정합니다.
module tb_my_mux4x1();
reg [1:0] s;
reg [3:0] i;
wire y;
// 모듈을 인스턴스화합니다.
my_mux4x1 uMy_mux4x1 (
.s(s),
.i(i),
.y(y)
);
initial begin
s = 2'b00;
forever #40 s= s+2'b01;
end
initial begin
i=4'b0101;
#160;
i=4'b0000;
end
endmodule
6. 크기 비교기
`define param 4
module my_comparator (
input [`param-1:0] a ,
input [`param-1:0] b ,
output reg aLessb ,
output reg aGreaterb ,
output reg aEqualb
);
always @(*) begin
if (a>b) begin
aLessb <= 1'b0;
aEqualb <= 1'b0;
aGreaterb <= 1'b1;
end else if (a==b) begin
aLessb <= 1'b0;
aEqualb <= 1'b1;
aGreaterb <= 1'b0;
end else begin
aLessb <= 1'b1;
aEqualb <= 1'b0;
aGreaterb <= 1'b0;
end
end
endmodule
`define param 4
module tb_my_comparator (
reg [`param-1:0] a ;
reg [`param-1:0] b ;
wire aLessb ;
wire aGreaterb ;
wire aEqualb ;
);
my_comparator uMy_comparator (
.a (a ) ,
.b (b ) ,
.aLessb (aLessb ) ,
.aGreaterb(aGreaterb) ,
.aEqualb (aEqualb )
);
initial begin
a=4'b0000;
forever #20 a=a+4'b0001;
end
initial begin
b=4'b0000;
forever #25 b=b+4'b0001;
end
endmodule
7 n비트 가감산기
module my_nBitAddSub3 (
input clk ,
input m ,
input [3:0] a ,
input [3:0] b ,
output reg [6:0] FND1 ,
output reg [6:0] FND2 ,
output reg [1:0] FND1Sel ,
output reg [1:0] FND2Sel
);
integer ai=0, bi=0;
integer hex1=0, hex2=0;
integer result;
integer k=0;
reg sign;
reg [6:0] FND1Val1, FND1Val2; // Separate variables for FND1Val1 and FND1Val2
reg clk100Hz;
always @(posedge clk) begin
if (k >= 499999) begin
k <= 0;
clk100Hz <= ~clk100Hz;
end else
k <= k+1;
end
always @ (a or b or result) begin
ai = a;
bi = b;
if (m==1'b0)
result = ai+bi;
else
result = ai-bi;
if (m == 1'b0) begin
sign = 1'b1;
hex2 = ~result / 16;
hex1 = ~result % 16;
end else begin
sign = 1'b0;
hex2 = result / 16;
hex1 = result % 16;
end
end
always @ (hex1 or hex2) begin
case (hex2)
0 : FND1Val2 = 7'b1111110;
1 : FND1Val2 = 7'b0110000;
2 : FND1Val2 = 7'b1101101;
3 : FND1Val2 = 7'b1111001;
4 : FND1Val2 = 7'b0110011;
5 : FND1Val2 = 7'b1011011;
6 : FND1Val2 = 7'b1011111;
7 : FND1Val2 = 7'b1110000;
8 : FND1Val2 = 7'b1111111;
9 : FND1Val2 = 7'b1110011;
10 : FND1Val2 = 7'b1111101;
11 : FND1Val2 = 7'b0011111;
12 : FND1Val2 = 7'b0001101;
13 : FND1Val2 = 7'b0111101;
14 : FND1Val2 = 7'b1101111;
15 : FND1Val2 = 7'b1000111;
default : FND1Val2 = 7'b0000000;
endcase
case (hex1)
0 : FND1Val1 = 7'b1111110;
1 : FND1Val1 = 7'b0110000;
2 : FND1Val1 = 7'b1101101;
3 : FND1Val1 = 7'b1111001;
4 : FND1Val1 = 7'b0110011;
5 : FND1Val1 = 7'b1011011;
6 : FND1Val1 = 7'b1011111;
7 : FND1Val1 = 7'b1110000;
8 : FND1Val1 = 7'b1111111;
9 : FND1Val1 = 7'b1110011;
10 : FND1Val1 = 7'b1111101;
11 : FND1Val1 = 7'b0011111;
12 : FND1Val1 = 7'b0001101;
13 : FND1Val1 = 7'b0111101;
14 : FND1Val1 = 7'b1101111;
15 : FND1Val1 = 7'b1000111;
default : FND1Val1 = 7'b0000000;
endcase
end
always @(posedge clk) begin
if (clk100Hz) begin
FND1Sel[0] <= 1'b0;
FND1Sel[1] <= 1'b1;
FND1 <= FND1Val1;
end else begin
FND1Sel[0] <= 1'b0;
FND1Sel[1] <= 1'b1;
FND1 <= FND1Val2;
end
end
always @* begin
if (sign == 1'b1)
FND2 <= 7'b0000001;
else
FND2 <= 7'b0000000;
end
always @(posedge clk100Hz or posedge clk) begin
if (clk100Hz) begin
FND2Sel[0] <= 1'b0;
FND2Sel[1] <= 1'b1;
end else begin
FND2Sel[0] <= 1'b0;
FND2Sel[1] <= 1'b1;
end
end
endmodule
module tb_my_nBitAddSub3();
reg clk ;
reg m ;
reg [3:0] a ;
reg [3:0] b ;
wire [6:0] FND1 ;
wire [6:0] FND2 ;
wire [1:0] FND1Sel ;
wire [1:0] FND2Sel ;
my_nBitAddSub3 uMy_nBitAddSub3(
.clk (clk ) ,
.m (m ) ,
.a (a ) ,
.b (b ) ,
.FND1 (FND1 ) ,
.FND2 (FND2 ) ,
.FND1Sel(FND1Sel) ,
.FND2Sel(FND2Sel)
);
initial fork
clk_gen();
data_gen();
cntrl_gen();
join
task clk_gen;
begin
clk = 1'b0;
forever #10 clk = clk+1'b1;
end
endtask
/*
task data_gen;
begin
a=3'b0;
b=3'b0;
repeat(3)@(negedge clk);
forever begin
#20;
a=a+1;
b=b+1;
end
end
endtask
*/
task data_gen;
integer i;
begin
a=3'd0;
b=3'd0;
repeat(3)@(negedge clk);
for (i =0 ;i<16 ;i=i+1 ) begin
#20;
a=a+1;
b=b+1;
end
end
endtask
task cntrl_gen;
begin
m=1'b0;
repeat(19) @(negedge clk);
m=1'b1;
repeat(19)@(negedge clk);
end
endtask
endmodule
DE1-SOC 에 맞춰 다시 빌드한 코드
module my_nBitAddSub3 (
input clk ,
input m ,
input [3:0] a ,
input [3:0] b ,
output reg [6:0] FND1 ,
output reg [6:0] FND2 ,
output [1:0] FND2Sel ,
output reg [1:0] FND1Sel
);
integer ai=0, bi=0;
integer hex1=0, hex2=0;
integer result;
reg sign;
reg [6:0] FND1Val1, FND1Val2; // Separate variables for FND1Val1 and FND1Val2
reg clk100Hz;
integer k=0;
always @(posedge clk) begin
if (k >= 249999) begin
k <= 0;
clk100Hz <= ~clk100Hz;
end else
k <= k+1;
end
always @ (a or b or m or result) begin
ai = a;
bi = b;
if (m==1'b0)
result = ai+bi;
else
result = ai-bi;
if (m == 1'b0) begin
sign = 1'b0;
hex2 = -result / 16;
hex1 = -result % 16;
end else begin
sign = 1'b1;
hex2 = result / 16;
hex1 = result % 16;
end
end
always @ (hex1 or hex2) begin
case (hex2)
//0 : FND1Val2 = 7'bgfedcba;
0 : FND1Val2 = ~7'b0111111;
1 : FND1Val2 = ~7'b0000110;
2 : FND1Val2 = ~7'b1011011;
3 : FND1Val2 = ~7'b1001111;
4 : FND1Val2 = ~7'b1100110;
5 : FND1Val2 = ~7'b1101101;
6 : FND1Val2 = ~7'b1111101;
7 : FND1Val2 = ~7'b0100111;
8 : FND1Val2 = ~7'b1111111;
9 : FND1Val2 = ~7'b1100111;
10 : FND1Val2 = ~7'b1110111;
11 : FND1Val2 = ~7'b1111100;
12 : FND1Val2 = ~7'b0111001;
13 : FND1Val2 = ~7'b1011110;
14 : FND1Val2 = ~7'b1111001;
15 : FND1Val2 = ~7'b1110001;
default : FND1Val2 = ~7'b0000000;
endcase
case (hex1)
0 : FND1Val2 = ~7'b0111111;
1 : FND1Val2 = ~7'b0000110;
2 : FND1Val2 = ~7'b1011011;
3 : FND1Val2 = ~7'b1001111;
4 : FND1Val2 = ~7'b1100110;
5 : FND1Val2 = ~7'b1101101;
6 : FND1Val2 = ~7'b1111101;
7 : FND1Val2 = ~7'b0100111;
8 : FND1Val2 = ~7'b1111111;
9 : FND1Val2 = ~7'b1100111;
10 : FND1Val2 = ~7'b1110111;
11 : FND1Val2 = ~7'b1111100;
12 : FND1Val2 = ~7'b0111001;
13 : FND1Val2 = ~7'b1011110;
14 : FND1Val2 = ~7'b1111001;
15 : FND1Val2 = ~7'b1110001;
default : FND1Val1 = ~7'b0000000;
endcase
end
assign FND2Sel[1]= 1'b0;
assign FND2Sel[0]= 1'b1;
always @(sign) begin
if (sign == 1'b1)
FND2 = ~7'b1000000;
else
FND2 = ~7'b0000000;
end
always @(clk100Hz, FND1Val2, FND1Val1) begin
if (clk100Hz) begin
FND1Sel[0] = 1'b0;
FND1Sel[1] = 1'b1;
FND1=FND1Val1;
end else begin
FND1Sel[0] = 1'b0;
FND1Sel[1] = 1'b1;
FND1=FND1Val2;
end
end
endmodule
8. '1' 개수 카운터
module one_counter(
input [7:0] d ,
output reg [6:0] FND ,
output FNDSel1 ,
output FNDSel2
);
integer oneCount, i=0;
always @(d or oneCount) begin
oneCount =0;
for (i =0 ;i<8 ;i=i+1 ) begin
if (d[i]) begin
oneCount = oneCount +1;
end
end
end
assign FNDSel2 = 1'b1;
assign FNDSel1 = 1'b0;
always @(oneCount) begin
case (oneCount)
0: FND = 7'b1111110;
1: FND = 7'b0110000;
2: FND = 7'b1101101;
3: FND = 7'b1111001;
4: FND = 7'b0110011;
5: FND = 7'b1011011;
6: FND = 7'b1011111;
7: FND = 7'b1110000;
8: FND = 7'b1111111;
default: FND=7'b1011011;
endcase
end
endmodule
'Study > VerilogHDL' 카테고리의 다른 글
[Study] 기타회로 설계 [진행중] (0) | 2023.09.02 |
---|---|
[Study] 순차논리회로 설계 [진행중] (0) | 2023.09.02 |
자습 방향 설정 (0) | 2023.09.02 |
[Vivado] FSM (Stop Watch, 가산기) with button. (0) | 2023.08.04 |
레지스터와 카운터 (0) | 2023.08.04 |