-
과제 1주차 Verilog (18.11.20 ~ 25)Soliloquy 2018. 11. 25. 14:22
Verilog와의 싸움
Verilog를 이용한 회로 설계를 팀 과제로 받았다. 자유 주제여서 주제를 뭐로 할지 고민하다가, 도어락, 게임 중 하나를 골라서 만들기로 했다. 도어락은 하는 사람들이 많을것 같아서, 게임을 만들기로 했다. 마침 게임을 만들면 좀 재미있게 만들 수 있지 않을까 라는 생각에 HBE COMBO 2라는 키트에 게임 하나를 만들어보기로 했다. 어떤 게임을 만들면 좀 자신있게 만들 수 있을지랑 좋을지 가닥을 잡았다.
2개월 가량의 이론 공부와 4주 남짓의 짧은 실습 경험으로 코드를 만들면서 당연하게도 수 많은 [⚠️Warning]과 [❌Error] 를 겪었다. 정말 한번에 되는 날이 없었다. 설령 없었을 때도, 컴파일은 되는데, 합성이 안되는 경우도 있고... 때로는 에러가 648개를 넘어가기도 하고 우여곡절이 많았다.
Detailed Reports [-] Report Name Status Generated Errors Warnings Infos Synthesis Report Current 토 11 24 02:02:25 2018 0 648 Warnings (181 new) 37 Infos (0 new) 정말 어떻게 해야 할까...짜증난다...
가장 짜증나는 점들 중 하나는 도움을 구하기가 힘들다는 것이었다. 주변에 Verilog를 잘 하는 사람찾기도 힘들고, 인터넷에는 워낙 마이너한 언어 인건지 한국어로 된 문서가 많이 없다. 예제를 찾아보려고 해도, 배운지 얼마 안되서 그런지 검색하는 것도 힘들고, 참... 고통의 연속이었다.
특히 수업시간에 무심코 지나간 배열의 비트 단위 접근을 하고 싶은데, 어떻게 하면 좋을까... 하고 열심히 찾아다녔는데, 이거 하나 찾는데도 거의 1시간 가까이 걸렸다. 변수이름[배열인덱스][비트 인덱스] 라는 것을 결국 찾아냈긴 하지만... 참...
'C언어' 를 한국어로 검색했을 때 나오는 갯수
검색결과 약 26,600,000개 (0.50초)
'Verilog'를 한국어로 검색했을 때 나오는 갯수
검색결과 약 66,400개 (0.37초)
구글로 검색을 했을 때
네이버 검색에서는 카페 블로그 합쳐서 7000건이 안된다.
두 번째로 컴파일러가 좀 불친절한 면이 많았다. 결국 현재 Xilinx ISE를 사용하고 있는데, 같은 Warning이라도 나의 상황과 인터넷에 올려진 글과 다른 상황이라서 인터넷에 올려진 해결책이 나에게 먹히지 않는 상황도 많았다. 그리고 종종 몇 번째 줄이 문제인지 알려주는 기능을 만들수가 없는건지 어느 문단이 문제인지 보여주지 않고 에러코드와 에러 메세지 하나만 띄워 놓는다. 비주얼 스튜디오가 절로 그리워진다.
❌ERROR:Xst:528 - Multi-source in Unit <snake> on signal <snakebody<3><6>>; this signal is connected to multiple drivers. 1
내가 겪은 에러중 하나
세 번째로 언어자체의 어려움이 있었다. for이나 if 등 C언어와 문법은 비슷한 점이 있지만, Verilog는 하드웨어, C언어는 소프트웨어 언어로 종류 달라서, 적응하는데는 시간이 꽤 필요했다. 회사에서 C언어나 어셈블리를 사용했던 분도 실습한지 2주차가 넘도록 감이 안잡힌다는 것을 볼 때, 참... 쉬운 언어는 아닌 것 같다.
게다가 코드가 잘 작동하는지 확인 하고 싶으면 확인을 위한 코드도 따로 짜야한다. 하드웨어가 있으면 직접 입력해서 확인할 수도 있겠지만, 그것도 한계가 있다. 만들어진 회로에 신호를 어떻게 넣을 지 그래픽으로 된 도구가 있어서 즉시즉시 확인할 수 있다면 좋겠지만... 그런건 없다. 일일이 수작업으로 해야했다. 비록 테스트 코드를 아주 길게 짤 일은 없었지만, 생각해야할 것이 늘어나니까... 여러모로 불편했다. 2
module testtb2();
reg clk, rst;
reg [2:0] keyinputdata;
wire [13:0] d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13;
integer i=0;
snake u1 (clk, rst, keyinputdata, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13);
initial begin
...
for(i=0 ; i<30 ; i=i+1) begin #20 clk <= ~clk; #20 rst <=0;
if( i< 5)
...
end
endmodule이런 식으로 테스트를 위한 입력 신호를 짠다고 생각하면 된다.
이 외에도 평소에 많이 쓰던 블럭구분 문자인 괄호 {} 를 사용하지 않고, begin end를 사용한 블럭 표기 방식 때문에 햇갈리는 점이 있었다. 그리고 이러한 방식이 가독성에서도 불편했다. 간단한 코드야 관계 없지만, 복잡한 코드를 수정해야할 때, begin end를 잘 생각하지 않으면, begin - end 갯수 맞추기 상당히 짜증난다. 소스 에디터에서는 엄한 줄에서 오류났다고 알려주기도 하고... 소스 수정에 혼선이 좀 있었다.
always @(posedge clk) begin
if (rst)
state <= no_scan;
else begin
if (!key_stop) begin
case (state)
no_scan : state <= column1;
column1 : state <= column2;
column2 : state <= column3;
column3 : state <= column1;
default : state <= no_scan;
endcase
end
end...
end구문이 복잡해 질수록 다른 구문들과 햇갈린다. 탭을 잘 사용해서 구문이 잘 구분되게 해야 한다.
물론 처음이라 그렇고 나중에는 적응하면 많이 나아지겠지만, 괄호를 쓰고 싶은 기분이 많이 든다. Xilinx 에디터 대신 notepad++라는 에디터를 쓰면 확실히 낫긴 하다만... 구문 검사를 하려면 다시 Xilinx ISE로 다시 가져와 검사를 해야 한다는 점이 불편해서 다시 Xilinx ISE 편집기로 넘어왔다. 이 외에도 배열은 input이나 output에 사용할 수 없는 등 3 여러 짜증나는 점이 많았다. 4
내가 겪은 오류들
수 많은 경고와 에러들 중 기억에 남는게 몇가지 있는데 다음과 같다.
1. 함수를 파일로 만들었을 때 생기는 오류
❌ERROR:HDLCompilers:26 - "test123.v" line 1 expecting 'EOF', found 'function'Xilinx ISE에서 .v 파일을 생성한 뒤, Function 문만 덩그라니 놓아두고 저장하면 EOF 인데 왜 endmodule이 없냐는 둥 에러가 발생한다. 그냥 무시하고 본래의 모듈에 `include < ~~~ .v> 로 함수 파일을 불러오면 Xilinx에서는 해당 오류를 내뿜지 않았다. 유효성 검사를 항상 모듈타입에 맞는지 검사해서 그런가 보다...
2. ⚠️This FF/Latch will be trimmed during the optimization process.
⚠️Xst:1895 - Due to other FF/Latch trimming, FF/Latch name1 (without init value) has a constant value of 0 in block <...>. This FF/Latch will be trimmed during the optimization process.말 그대로 초기값이 주어지지 않아서 입력 값을 받아도 달라지지 않는 않는 경우다.
- 만약 if( in1 ==0) name1<=1; 으로 구문을 짰을 경우 in1의 값이 변하지를 못해서 name1을 바꿀수 없는 경우
- case()에 default 문이 없어서 실행될 일이 없을때
- 실행 구문이 name1 <= ~name1; 인 경우 name1이 초기값이 선언되지 않아서 (기본값이 x) ~x 을 하고 있을때 일어났다.
3. ⚠️ Xst:2677 - Node <testinstance2/name1> of sequential type is unconnected in block <main>.
나의 경우에는 말 그대로 연결이 잘 안된 경우였다. wire 벡터 선언을 깜빡하고 안해줬을 때 이런 오류가 많이 나왔다.
4. ❌ERROR:Xst:528 - Multi-source in Unit <...> on signal <name1<3><6>>; this signal is connected to multiple drivers.
서로 다른 always 블록 안에 동일한 변수가 있거나, 이유는 모르겠지만, 동일한 변수를 같은 always에서 동시에 여러번 사용하면 이러한 문구가 나왔다.
여담
Verilog 가 begin end 를 사용 하는 이유를 찾아봤다. Verilog가 만들어 졌을 당시인 80년도에는 Pascal 이라는 프로그래밍 언어가 유행했었는데, Pascal이 begin end 구조를 사용했었고 Verilog는 이러한 구조를 따라 사용해서 그렇다 한다.. 5
에러 파일 로그는 프로젝트 폴더 내의 _xmsgs폴더의 xst.xmsgs를 열어서 확인할 수 있었다.
참... 힘들다 에러 몇개 잡으려고 하루 종일 컴퓨터 앞에 하루 종일 앉아 있어야 했다... 물론 다른 사람들도 똑같겠지...
내가 개발새발로 짠 코드를 논리회로로 표현해 보았다...
물론 제대로 작동은 안했다.
[본문 SVG 파일]
- 다른 always 블럭내에 같은 입력을 발생시키면 일어나는 일. [본문으로]
- 이 코드를 Testbench 코드 라고 한다. [본문으로]
- 어째서 오픈 소스가 소스를 쓰는데 더 편한지 모르겠다. 이거 프로그램 하나에 가격이 얼마였더라... [본문으로]
- 이후의 언어인 System Verilog 라는 언어에서는 가능하다고 한다... [본문으로]
- www.quora.com/Why-did-the-developers-of-Verilog-decide-to-use-begin-and-end-syntax-to-open-and-close-modules-and-not-incorporate-as-used-in-most-common-programming-languages-thus-making-it-easier-for-the-hardware-engineers [본문으로]