Study/Digital System Design and Lab[Verilog]

#3 Modeling Flip-Flops Using Always Block

얼죽아여뜨샤 2023. 10. 14. 17:05

*Compliation, Simulation, and Synthesis of Verilog Code

  • Simulation and synthesis process:

- A netlist a list of required components and their interconnections.

 

*Summary

 

*Verilog Data Types and Operators

  • Two main groups of data types:

    Variable:
    - An abstraction of a data storage element.
    - Stores a value from one assignment to the next.
    An assignment statement in a procedure acts as a trigger that changes the value in the data storage element.
    - Examples: reg, time, integer, real, real-time.

    Net:
    - Represent physical connections between structural entites, such as gate.
    - Generally, it does not store values.
    Instead, value is determined by the values of its drivers.
    Examples: wire, tri, wand, wor.

 

  • Bitwise and Logical Operators:
Bitwise : 1bit씩 계산하라

Ex)
reg[3:0] A = 4'b1100;
reg[3:0] B = 4'b0101;

*Bitwise
~A -> 0011
A&B -> 0100
A|B -> 1101
A^B -> 1001 // XOR은 같으면 0, 다르면 1 // 1의 갯수가 홀수이면 1
A~^B -> 0110 // XNOR은 다르면1, 같으면 0 // 1의 갯수가 짝수이면 1

*Logical
if(!A) return 1
A&&B return 1
A||B return 1

 

  • Reduction and shift operators:
    축약 연산자는 단항 연산자로 하나의 피연산자에 사용된다.
    하나하나의 비트 연산을 수행한다.

Logical Shift는 빈자리에 0을 채운다.

Arithmetical Shift는 왼쪽 시프트(<<<)는 0을 채우지만 >>>는 빈자리에 MSB를 채운다.

Ex)
reg[3:0] A = 4'b1100;
reg[3:0] B = 4'b0101;

*Reduction
: 4bit -> 1bit 축약(한줄을 모두 계산)
&A -> 1&1&0&0 -> 0
~&A -> 1 //AND를 nor취하면 됌
|A -> 1
~|A -> 0
^A -> 0
~^A -> 1

*Shift
A>>2 -> 0011
A<<2 -> 0000
A>>>2 -> 1001 //빈자리에 MSB를  채운다.
A<<<2 -> 0000 //0을 채운다

 

  • Shift/Arithmetic Shift
module Logic;
parameter tlimit = 100;

reg signed[3:0] temp0 = 4'b1101, temp1  = 4'b1010, temp6=4'b0110, temp7=4'b0101;
integer temp2 = -3, temp3 = -6;

//shift right = quotient when divided by 2

initial $display("1101>>1=%b, 1101>>>1=%b", temp0>>1, temp0>>>1);
initial $display("1010>>1=%b, 1010>>>1=%b", temp1>>1, temp1>>>1);
initial $display("-3>>1=%d, -3>>>1=%d", temp2>>1, temp2>>>1);
initial $display("-6>>1=%d, -6>>>1=%d", temp3>>1, temp3>>>1);
initial $display("-3>>1=%b, -3>>>1=%b", temp2>>1, temp2>>>1);
initial $display("-6>>1=%b, -6>>>1=%b", temp3>>1, temp3>>>1);

//shift left = multiplied by 2
initial $display("1101<<1=%b, 1101<<<1=%b", temp0<<1, temp0<<<1);
initial $display("1010<<1=%b, 1010<<<1=%b", temp1<<1, temp1<<<1);
initial $display("-3<<1=%d, -3<<<1=%d", temp2<<1, temp2<<<1);
initial $display("-6<<1=%d, -6<<<1=%d", temp3<<1, temp3<<<1);

initial begin #tlimit $stop; end

endmodule
# 1101>>1=0110, 1101>>>1=1110
# 1010>>1=0101, 1010>>>1=1101
# -3>>1= 2147483646, -3>>>1= -2
# -6>>1= 2147483645, -6>>>1= -3
# -3>>1=01111111111111111111111111111110, -3>>>1=11111111111111111111111111111110
# -6>>1=01111111111111111111111111111101, -6>>>1=11111111111111111111111111111101

# 1101<<1=1010, 1101<<<1=1010
# 1010<<1=0100, 1010<<<1=0100
# -3<<1= -6, -3<<<1= -6
# -6<<1= -12, -6<<<1= -12

 

  • Relational, logical and bitwise operators:

case따지는 방법
case는 unknown값(x,등등) 여기서는 이진수라 ==과 같다.
A = 111x
B = 111x
(A===B) return1
A==B return x
reg[3:0] A = 4'b1100;
reg[3:0] B = 4'b0101;

*Relational
if(A>B) return1
A<B return0
A>=B return1
A<=B return0

*Logical&bitwise
A==B return0
A!=B return1
A===B return0
A!==B return1

 

  • Arithmetic, concatenation, replication, conditional operators:

reg[3:0] A = 4'b1100;
reg[3:0] B = 4'b0101;

*Arithmetic
A+B -> 5'b10001
A-B -> 4'0111 //https://eunhee-programming.tistory.com/66 : 뺄셈
-A ->> 4'0100
A*2 -> 5'11000 //왼쪽 shift 한번
A/2 -> 4'b0110 //오른쪽 shift 한 번
A**2 -> 12^2
*
{A, B} = 11000101 //붙여쓰기
{2{A}} = 11001100 //2번 반복
assign C = (A)? 3 : 5 //A이면 3 아니면 5

 

*Modeiling Flip-Flops Using Always Block

  • Flip-flop은 clk의 input edge를 사용해 state를 바꿀 수 있다.
    : always block으로 모델 가능하다.
  • posedge 또는 negedge로 표현해 edge-triggerd device를 수행한다.

D-FF

D Flip-Flop특징 : 항상 D를 쫓아간다. => Q+ = D

D Q Q+
0 0 0
0 1 0
1 0 1
1 1 1

 

<Latch사용 불가 - 의도하지 않는 latch생기면 불안정해진다.>

: 입력이 변경 될 때마다 저장된 이진정보도 변경된다. 그러므로 레벨에 민감하다.

<수정 코드>
reg Q; // 선언 필요
always@(G or D) //combination logic임을 알려준다
begin
	if (G)
    	Q = D; //<=사용 불가
    else		//else가 없으면 이전 값을 유지하려고 한다 = latch => 불안정
    	Q = 0;
end

 

  • posedge 나 negedge 동작 중 하나라도 되면 if문 수행
  • negedge ClrN : Clk과 Asynchronous하게 동작한다. Bubble이 붙어있는 것이 특징!

JK Flip-Flop특징 : Q+ = JQ' + K'Q

//J-K Flip-Flop Model
module JKFF (SN, RN, J, K, CLK, Q, QN);
input SN, RN, J, K, CLK;
output Q, QN;

reg Qint;

always@(negedge CLK or RN or SN)
begin
	if (~RN)
    	#8 Qint <= 0;	//RN이 0이면 다음상태 0으로 만든다.
    else if (~SN)
    	#8 Qint <= 1;	//SN이 0이면 다음상태 1로 만든다.
    else
    	Qint <= #10 ((J && ~Qint) || (~K && Qint)); //J_K FF동작
end

assign Q = Qint;
assign QN = ~Qint;

endmodule
J K Q Q+
0 0 0 0
0 0 1 1
0 1 0 0
0 1 1 0
1 0 0 1
1 0 1 1
1 1 0 1
1 1 1 0

J=K=0 : 현재상태 유지.

J=1 K=0, J=0 K=1 : J를 쫓아간다.

J=K=1 : 현재상태를 뒤집는다.

 

=> 위와 같은 복잡한 logic구성도 가능하다!

 

위 코드의 오류
1. input, output선언이 안 되어있다.

2. sum, carry를 reg로 선언한다.

3. 2줄 이상이 if문 안에 사용되면 begin-end로 고정 해야한다.

4. else를 넣어줘야 latch가 안 일어난다.

=> Compile은 되지만 Simulation은 안된다.

//수정코드
module Halfadder(input x, y, add, output sum, carry);

//initial begin sum = 0; carry = 0; end

always@(*) //combinational logic
begin
	if(add == 1) begin
    	sum = x ^ y;
        carry = x & y;
    else				//else를 안써주려면 always시작 전에 initlalized해야한다.
    	Sum, carry = 0; 
    end
end

endmodule

 

 

+FullAdder과 HalfAdder 비교

(1) HalfAdder

HalfAdder은 carry가 없어서 자리 올림이 불가하다.

 

(2) FullAdder

FullAdder은 Cin이 있어서 자리 올림이 가능하다.

 

HalfAdder과 FullAdder의 차이는 Cin으로 자리 올림 숫자를 input으로 받느냐이다.
FullAdder을 여러 개를 사용해 여러 자릿수의 덧셈을 할 수있기에 FullAdder을 병렬로 연결해 사용하곤 한다.

2023.10.04 - [Study/Digital System Design and Lab] - #1-1 Design a full adder

 

#1-1 Design a full adder

*Full Adder *Full Adder Design Using Verilog FullAdder.v file `timescale 1ns/100ps module FullAdder (input x, y, Cin, output Cout, Sum); assign Sum = x ^ y ^ Cin; assign Cout = (x & y) | (x & Cin) | (y & Cin); endmodule timescale 1ns/100ps : time 프리시

jgewjsrhdms.tistory.com

2023.10.11 - [Study/Digital System Design and Lab] - #2-1 Design a 4-Bit Adder