본문 바로가기
[Nexys4 DDR]

[Nexys4 DDR 프로젝트] Behavioral Modeling

by choice1219 2019. 2. 21.

안녕하세요. VeriLog입니다.


오늘은 HDL의 마지막 방법인 Behavioral Modeling에 대해서 배워보고자 합니다.


Behavioral ModelingC언어와 가장 유사한 방법이라서, 사용하기에는 제일 친숙하지만, VivadoSynthesis하는 과정에서, LUTFlip Flop들을 지나치게 많이 사용할 수도 있는 단점을 가지고 있습니다


따라서, Gate-Level, Dataflow Modeling과 적절하게 사용해야 좋은 Hardware Design을 할 수 있습니다.

 


Behavioral Modeling은 설계의 기능을 알고리즘 위주로 기술하는 방법입니다


Initial, Always 등의 구문을 주로 사용하는 방식입니다.


Initial Time = 0 일때 실행되는 구문이며, always는 내부 구문을 반복 실행하는 무한루프와도 같은 구문입니다.

 

예를 들어,

-------------------------------------

Initial beign

clk = 0;

end

 

always begin

#10; clk = ~clk;

end

-------------------------------------

 

이와 같이 작성할 경우, clk의 초기값은 0이 되며, 매 10 unit이 지날때마다 toggle이 되는 구문입니다. 


always 구문 뒤에 조건문을 넣어서 조건이 성사할때만 반복적으로 수행하게 만들수도 있습니다. 


-------------------------------------

always @ (posedge clk)

begin

cnt = cnt + 1;

end

-------------------------------------


여기서 posedge 는 clk의 rising edge를 의미하며, falling edge는 negedge로 표현 가능합니다. 


자세한 내용은 이강 교수님 저 "VHDL 사용자를 배려한 Verilog-2001 디지털시스템 설계" 를 참고해주시면 됩니다.





오늘은 Behavioral Modeling을 사용해서, Nexys4DDR의 7-Segment Decoder를 만들어 보려고 합니다.


7-Segment는 LED의 집합으로 숫자를 표현할 수 있는 LED 입니다. 


7-Segment는 Anode와 Cathode로 이루어져있습니다. 


위의 사진에서 a~g 까지를 cathode라고 합니다. 만약 1을 표현 하고자 하면, b와 c를 켜고, 나머지를 꺼주면 됩니다. 


2를 출력하기 위해서는 a, b, g, e, d 를 켜면 되겠죠?



하지만, 여기서 유의해야 할 사항은 Nexys4DDR에서 7-Segment LED를 켜기 위해서는 '1'이 아닌 '0'을 인가해야 합니다. 



Anode는 Segment 의 On / Off 를 결정해주는 부분입니다.  Anode도 Cathode와 마찬가지로 켜기 위해서는 '1'이 아닌 '0'을 인가해야 합니다. 


만약 2라는 숫자를 표현하고 싶다면, Anode -> 0, Cathode -> a, b, g, e, d에 0을 인가해주면 되겠죠.


하지만, 여기서 또 유의해야할 점은, 보통 Segment는 4개가 통으로 연결이 되어 있습니다. 즉, Cathode에 2를 표

현하면, 4개의 Segment 모두 2를 표시합니다. 




만약 각각의 Segment에 다른 숫자를 표현하고 싶으면, 사람 눈보다 빠르게 각각의 Segment를 끄고 켜고를 반복해야 합니다. 


이 부분에 대해서는 다음 시간에 다루도록 하겠습니다. 



이번 시간에는 Switch에 입력된대로 한개의 Segment에 표시하는 것에 대해서 배우면서 Behavioral Modeling을 연습해보겠습니다. 



코드는 아래와 같습니다. 



여기서 always @ (*)의 의미는 변화가 생기면 무조건 이라는 뜻입니다. 


변화가 생기면,  always 구문 안으로 들어가서, Input 값인 A에 따라, cathodedata에 값을 넣어주는 구문입니다. 


case 구문은 C에서 Switch 구문과 같다고 생각하시면 됩니다. 여기서 유의해야 할 점은, case 문 끝에 꼭 endcase로 닫아주셔야 합니다!


따라서, 위의 코드를 보시면, Anode는 0번째만 On인 상태이며,


Input 값이 4비트로 들어오는데, 만약 Input 이 3이라면,


cathodedata의 값이 00001101로 인가가 됩니다. 즉, a, b, c, d, g의 값은 On, 나머지는 Off 상태가 됩니다.



위의 코드를 보드에서 확인하기 위해서, constraint 파일에서 7-segment 부분과 switch 부분을 수정하셔야합니다. 


A[3:0] : Switch3~0

CA ~ CDP : CA~CDP

AN[3:0] : AN3~0


위와 같이 수정 후, 출력을 하시면, 아래와 같은 결과가 출력이 됩니다. 




Input A의 값이 1010 -> 10일 때, 7-Segment의 결과가 A로 (16진수)로 결과가 잘 나온것을 확인할 수 있습니다.


위에서 언급한바와 같이, 7-segment cathode에 값을 주게 되면, 모든 segment에서 같은 값을 출력하게 됩니다. 


따라서, 각각의 segment에서 다른 값을 출력하려면, segment를 사람 눈보다 빠르게 껐다가 켜야합니다.


이 부분은 다음 시간에 다루도록 하겠습니다.


코드는 첨부하였습니다. 질문이 있으시면 댓글로 남겨주시면 답해드리겠습니다. 



Nexys4DDR_Master.xdc

ss_decoder.v