VHDL
* 이 기사에는 UpCloud VPS에 대한 광고 링크가 포함되어 있습니다
지속적인 전달과 지속적인 통합은 코드 변경과 배포 사이의 주기 시간을 단축하는 민첩한 소프트웨어 개발 방법론입니다. 자동화를 사용하여 코드 변경 사항을 확인하고 릴리스 파일을 구축함으로써 팀의 생산성과 효율성이 더욱 높아질 수 있습니다.
소프트웨어 회사는 오랫동안 지속적인 개발을 실천해 왔지만 FPGA 프로젝트에도 이러한 방법을 사용할 수 있습니다. 이 튜토리얼에서는 Jenkins, Xilinx Vivado 및 Git/GitHub 소스 제어 관리(SCM) 시스템을 사용하여 Virtual Private Server(VPS)에 자동화 서버를 설정하는 방법을 설명합니다.
Jenkins 자동화 서버는 Java로 작성된 무료 오픈 소스 프로그램입니다. Windows 또는 Linux에서 실행됩니다. 이 블로그 게시물에서는 헤드리스 서버에 가장 일반적인 플랫폼인 Linux를 사용하겠습니다.
Jenkins는 Linux에서는 데몬 프로세스로 실행되고 Windows에서는 서비스로 실행됩니다. Jenkins가 시작될 때 실행되는 내장 웹 서버는 사용자 인터페이스를 제공합니다. 대부분의 사용자는 웹 인터페이스를 사용하여 Jenkins와 상호 작용합니다. 웹 GUI를 통해 새로운 자동화 프로젝트를 추가하고 기존 프로젝트를 관리할 수 있습니다.
위 이미지는 오늘 설정할 Jenkins 서버의 메인 페이지입니다. 기본적으로 로그인한 사용자만 Jenkins에 액세스할 수 있지만 이 기사에서는 *데모 서버의 일부에 대한 공개 액세스를 활성화했습니다.
* 업데이트:2020년 5월 13일에 데모 서버를 중단했습니다
메인 페이지에 보이는 것은 채용 목록입니다. 이러한 작업에는 모든 작업이 포함될 수 있으며 웹 GUI에서 수동으로 트리거될 수 있습니다. 또는 스크립트, 웹후크를 통해 또는 다른 작업 완료의 결과로 자동으로 트리거될 수도 있습니다. 따라서 자동화 서버라는 용어가 사용되었습니다. .
이 예에서 각 작업은 별도의 GitHub 저장소에 보관된 VHDL 모듈에 해당합니다. 개발자가 모니터링되는 Git 저장소 중 하나에 코드를 푸시할 때마다 Jenkins가 시뮬레이션을 실행하고 프로젝트를 빌드하도록 할 것입니다. 테스트벤치가 실패하거나 빌드가 중단되면 Jenkins는 웹 인터페이스에서 작업을 실패로 표시하고 잘못된 코드를 커밋한 사람에게 자동으로 이메일을 보냅니다.
자동화 서버는 대규모 프로젝트를 진행하는 팀에 가장 유용합니다. 따라서 저는 8개의 Git 리포지토리로 구성된 예제 FPGA 프로젝트를 구성했습니다. 이 프로젝트는 Fast-Track 과정의 7세그먼트 디스플레이 카운터를 Xilinx ZedBoard에 포팅한 것입니다.
GitHub의 8개 저장소 링크:
각 저장소에는 VHDL 모듈과 해당 테스트벤치가 포함되어 있습니다. 패키지는 예외입니다. 상수와 유형을 정의하는 VHDL 패키지 세 개만 포함된 repo. 또한 seg7 최상위 모듈에는 물리적 구현의 클럭 속도와 핀 할당을 정의하는 제약 조건 파일이 포함되어 있습니다.
대부분의 대규모 VHDL 프로젝트는 둘 이상의 저장소의 모듈을 사용합니다. 회사에는 일반적으로 다양한 디자인에서 재사용할 수 있는 패키지 및 모듈 라이브러리가 있습니다. 이것이 바로 제가 이 단순한 디자인을 그렇게 많은 모듈로 분할하여 모방하고 있는 것입니다.
이 예에서 모든 모듈은 패키지 저장소에 종속되며 최상위 모듈도 모든 하위 모듈에 종속됩니다. 표준 Git 하위 모듈을 사용하여 필요에 따라 가져옴으로써 이 문제를 해결했습니다. 위 그래프는 이 프로젝트에 있는 모든 저장소의 콘텐츠와 종속성을 보여줍니다.
Git 리포지토리에는 Jenkins 구성 및 빌드 스크립트와 같은 여러 비설계 파일도 포함되어 있습니다. 이 기사의 다음 섹션에서 이에 대해 이야기하겠습니다.
Jenkins는 모든 Windows 또는 Linux 컴퓨터에서 실행할 수 있지만 실용적인 목적을 위해서는 전용 서버에서 실행하는 것이 좋습니다. 자동화 서버는 항상 가동되어 실행되어야 하며 모든 팀 구성원이 액세스할 수 있어야 합니다. 충분한 용량을 갖춘 물리적 서버가 주변에 있다면 정말 좋습니다. 하지만 우리 대부분에게 더 빠르고 저렴한 솔루션은 가상 사설 서버(VPS)를 사용하는 것입니다.
VPS는 인터넷을 통해 호스팅 회사에서 임대하는 가상 컴퓨터입니다. 이는 원하는 소프트웨어와 상호 작용하고 설치할 수 있는 실제 Windows 또는 Linux 컴퓨터처럼 보입니다. 우리는 Linux 컴퓨터를 사용할 예정입니다. 이것이 우리 사용 사례에 가장 적합하기 때문입니다.
VHDLwhiz 사이트는 지난 2년 동안 그랬던 것처럼 VPS에서 실행되고 있습니다. 저는 이미 가장 빠르고 최고의 VPS 제공업체인 UpCloud를 찾는 수고를 겪었습니다. 당연히 UpCloud를 사용하여 자동화 서버용 VPS를 설정할 예정입니다.
UpCloud를 사용해 보고 싶다면 $25 상당의 크레딧을 제공하는 추천 코드가 있습니다. 가입할 때.
>> $25 UpCloud 보너스를 받으려면 여기를 클릭하십시오. <<
또는 결제 시 내 프로모션 코드(NV78V6)를 사용하세요.
코드를 사용하면 보너스를 받고 동시에 VHDLwhiz를 지원하게 됩니다. UpCloud를 사용하는 모든 고객에 대해 내 UpCloud 계정에 일부 자금이 적립될 수 있습니다.
좋아요, 판매 이야기는 이쯤 할게요. 서버 설정을 시작해 보겠습니다.
새 UpCloud 계정에 로그인한 후 서버 → 서버 배포로 이동하여 새 VPS 인스턴스 생성 프로세스를 시작할 수 있습니다. .
UpCloud에는 전 세계에 많은 데이터 센터가 있습니다. 새 서버를 호스팅할 가장 가까운 위치를 선택하세요. 그런 다음 가상 머신에 제공할 리소스 양에 대한 계획을 선택해야 합니다. Jenkins는 많은 리소스를 사용하지 않지만 Xilinx Vivado는 RAM을 많이 사용합니다. 따라서 아래 이미지처럼 최소한 4GB RAM이 포함된 요금제를 선택하셔야 합니다.
메모리 사용량은 대상 FPGA의 복잡성과 밀접한 관련이 있으므로 Xilinx의 메모리 권장 사항 페이지를 살펴보는 것이 좋습니다. 이 페이지에는 제가 사용하고 있는 Zynq-7000 XC7Z045 FPGA의 최대 메모리 사용량이 1.9GB로 나열되어 있습니다. 2GB 계획은 디자인 라우팅에 너무 적다는 것을 알았습니다. Vivado가 충돌하고 dmesg에 다음 메시지가 나타납니다. 로그:
[807816.678940] 메모리 부족:종료된 프로세스 22605(vivado) total-vm:2046684kB, anon-rss:782916kB, file-rss:308kB, shmem-rss:0kB
UpCloud 계정 내에서 언제든지 서버의 RAM 및 CPU 리소스를 쉽게 업그레이드할 수 있습니다. VPS의 파일 시스템을 다시 분할하지 않으면 더 비싼 패키지와 함께 제공되는 추가 하드 드라이브 공간을 자동으로 얻을 수는 없지만 실행됩니다. 참고로 저는 50GB 스토리지로 계획을 시작했는데 전체 자동화 서버를 완성하고 나서 그 중 61%를 사용했습니다. Vivado만으로도 24GB의 공간을 차지합니다.
아래 이미지와 같이 최신 CentOS Linux 배포판을 운영 체제로 선택하는 것이 좋습니다. Xilinx Vivado는 공식적으로 무료가 아닌 Red Hat Linux만 지원합니다. 하지만 CentOS는 Red Hat을 밀접하게 따르는 무료 커뮤니티 지원 Linux 배포판입니다.
그런 다음 기본값으로 둘 수 있는 네트워킹에 대한 몇 가지 옵션이 있습니다. 비밀번호 없는 로그인을 위해 SSH 키를 업로드할 수 있는 섹션도 웹페이지에 있습니다. SSH 키를 업로드하기 위한 기존 Linux 방법을 사용하여 나중에 언제든지 이러한 항목을 구성할 수 있습니다.
마지막으로 아래 이미지와 같이 서버의 호스트 이름과 이름을 지정해야 합니다. 호스트 이름은 사용자가 Jenkins 서버에 액세스하기 위해 브라우저에 입력하는 공개 도메인입니다. 도메인이나 하위 도메인이 준비되어 있지 않은 경우 언제든지 해당 IP 주소를 사용하여 서버에 액세스할 수 있습니다. 설정에 만족하면 배포를 누르세요. 버튼을 눌러 서버를 생성하세요.
서버를 생성한 후에는 자동 생성된 비밀번호가 알림으로 표시됩니다. 나중에 Linux passwd를 사용하여 이를 변경할 수 있습니다. 명령. 서버를 배포하기 전에 SSH 키를 제공한 경우 비밀번호가 전혀 필요하지 않습니다. 서버에 액세스할 수 없는 경우 콘솔 연결 열기를 눌러 언제든지 UpCloud 계정 내에서 로그인할 수 있습니다. , 아래 이미지와 같습니다.
새 서버에는 서버->네트워크의 UpCloud 계정에 있는 영구 IPv4 및 IPv6 주소가 할당됩니다. . 공개 IPv4 주소의 루트 계정으로 SSH를 통해 서버에 접속할 수 있습니다.
아래 이미지의 예시 IP 주소를 사용하면 Linux 가정용 컴퓨터에 입력할 적절한 명령은 다음과 같습니다.
단지 실험용으로 수행하는 경우에는 IP 주소만 사용해도 괜찮습니다. 그러나 보다 실용적인 해결책은 서버에 영구 도메인 이름을 할당하는 것입니다. 그렇게 하려면 온라인에서 이용 가능한 많은 등록 기관 중 하나에서 도메인을 구입해야 합니다.
저는 이미 vhdlwhiz.com 도메인을 소유하고 있으므로 Jenkins 서버에 jenkins.vhdlwhiz.com이라는 하위 도메인을 만들기로 결정했습니다. . UpCloud 서버를 배포할 때 도메인 이름을 올바르게 설정했습니다. 다음으로 해야 할 일은 하위 도메인이 공개 IPv4 주소를 가리키는 것입니다.
아래 이미지는 내 도메인 이름 등록 기관의 DNS 영역 파일에 입력하는 설정을 보여줍니다. 서버가 최상위 도메인(vhdlwhiz.com)에 있기를 원했다면 호스트 이름 필드를 비워 두었을 것입니다. 하지만 저는 그것이 vhdlwhiz.com의 "jenkins" 하위 도메인에 있기를 원합니다. 그래서 하위도메인 이름을 입력합니다.
DNS 설정을 변경한 후 도메인 이름을 사용하여 웹 사이트에 액세스하려면 시간이 좀 걸립니다. 일반적으로 20분 이내에 완료되지만 극단적인 경우 변경 사항이 인터넷 전체에 적용되는 데 최대 48시간이 걸릴 수 있습니다.
변경 사항이 적용되면 SSH를 통해 서버에 로그인할 때 IP 주소 대신 도메인 이름을 사용할 수 있습니다.
ssh root@yoursub.yourdomain.com
새 Linux 서버에서 루트 계정으로 로그인한 후 가장 먼저 해야 할 일은 설치된 모든 패키지를 업데이트하는 것입니다. CentOS Linux에서는 yum 기본 패키지 관리자입니다. 우리는 yum을 사용할 것입니다. 대부분의 소프트웨어를 설치하기 위한 명령입니다.
설치된 모든 패키지를 최신 버전으로 업데이트하려면 다음 명령을 실행하십시오:
이제 시스템이 최신 상태임을 확인했으므로 설치를 진행할 수 있습니다. 하지만 yum을 실행하기 전에 Jenkins를 설치하는 명령을 사용하여 Java 버전 11을 명시적으로 설치하겠습니다. 그러면 나중에 Xilinx Vivado를 설치할 때 문제를 덜 수 있을 것입니다.
현재 우리 서버에는 Java 인터프리터가 없습니다. yum이라고 말하면 Jenkins를 설치하려면 Java 버전 8을 설치해야 합니다. Jenkins에서는 잘 작동하지만 Vivado는 Java 버전 11에 의존하기 때문에 나중에 문제가 발생합니다.
Jenkins를 설치하기 전에 다음 명령을 사용하여 Java 11을 설치하세요.
yum -y install java-11-openjdk-devel
Jenkins는 CentOS와 함께 제공되는 기본 소프트웨어 저장소에서 사용할 수 없습니다. 다행히 다음 명령을 사용하여 Red Hat에서 Jenkins 저장소를 가져올 수 있습니다:
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key
마지막으로 Jenkins를 설치해 보겠습니다.
Jenkins 서버는 다음 부팅 후 자동으로 시작되지만 다음과 같이 재부팅하지 않고도 서버를 시작할 수 있습니다.
systemctl을 사용하여 Jenkins 서버의 상태를 언제든지 확인할 수 있습니다. 명령:
오류 메시지와 함께 서버 상태를 인쇄합니다:
현재 Jenkins는 VPS의 포트 8080에서 실행 중이지만 웹 브라우저를 사용하여 연결할 수 있는 방법이 없습니다. CentOS 방화벽은 기본적으로 포트 8080과 포트 80(HTTP)을 차단하기 때문입니다. 이 문제를 해결하기 위해 할 수 있는 일은 방화벽에서 포트 80을 열고 iptables를 사용하여 포트 8080으로 다시 라우팅하는 것입니다. .
하지만 그렇게 하기 전에 HTTPS로 사이트를 보호할지 여부를 결정해야 합니다. HTTP와 포트 80만 사용할 때의 문제점은 웹 사이트가 안전하지 않다는 것입니다. 공용 Wi-Fi를 사용하여 액세스하는 경우 노트북과 쉽게 사용할 수 있는 해킹 소프트웨어를 사용하여 동일한 Wi-Fi에 있는 악의적인 사람이 연결을 도청하고 Jenkins의 로그인 자격 증명을 훔칠 수 있습니다.
암호화되지 않은 HTTP의 보안 위험을 피하려면 Jenkins용 HTTPS 설정에 대한 다음 섹션으로 건너뛰세요. 그렇지 않은 경우 계속 읽어보세요.
Jenkins에 대한 안전하지 않은 HTTP 액세스를 활성화하는 것은 다음 명령을 실행하는 것만큼 쉽습니다:
firewall-cmd --permanent --zone=public --add-port=80/tcp firewall-cmd --reload iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
그런 다음 즐겨 사용하는 브라우저에 도메인 이름을 입력하면 Jenkins 시작하기 페이지가 나타나야 합니다. 적어도 구글 크롬에서는 아래 이미지와 같이 주소 표시줄에 '안전하지 않음' 경고가 표시됩니다.
Jenkins 설정으로 건너뛰세요. 섹션에 만족하신다면 섹션을 선택하세요.
대중이 접근할 수 있는 보안되지 않은 웹사이트를 갖는 것은 엄청난 보안 위험입니다. Jenkins는 소스 코드에 액세스할 수 있으며 서버에 성공적으로 침입한 모든 해커도 액세스할 수 있습니다. 다행히 몇 가지 복사-붙여넣기 명령만으로 웹사이트를 보호할 수 있습니다.
Jenkins는 HTTPS를 자체적으로 처리할 수 없습니다. 따라서 보안 채널을 통해 도착하는 요청을 안전하지 않은 Jenkins 서버로 다시 라우팅하려면 일반 웹 서버를 설치해야 합니다. 저는 오늘날 가장 인기 있는 무료 오픈 소스 웹 서버 중 하나인 Nginx를 사용하겠습니다.
Nginx를 설치하고 시작하려면 다음 명령을 실행하십시오:
yum -y install nginx systemctl start nginx
그런 다음 방화벽에서 HTTP 및 HTTPS 포트를 모두 열어야 합니다. 우리는 HTTPS 요청만 제공할 것이지만 모든 안전하지 않은 요청을 보안 포트로 리디렉션하도록 Nginx를 구성할 것이기 때문에 HTTP 포트도 열어 두어야 합니다.
다음 명령은 웹 트래픽에 대한 방화벽을 엽니다:
firewall-cmd --permanent --zone=public --add-port=80/tcp firewall-cmd --permanent --zone=public --add-port=443/tcp firewall-cmd --reload
다음 단계는 웹 브라우저가 상호 작용하는 웹 사이트가 사기꾼이 아니라 귀하의 웹 사이트임을 인증하는 데 사용할 수 있는 인증서를 설치하는 것입니다. 우리는 사이트를 보호하기 위해 무료 Let’s Encrypt 인증 기관을 사용할 것입니다. 개별 단계는 복잡하지만 다행히도 certbot은 이를 자동으로 수행할 수 있는 스크립트를 제공합니다.
다음 명령을 사용하여 스크립트를 다운로드하고 준비하십시오:
apt update apt install snapd snap install core; snap refresh core snap install --classic certbot
다음으로 인증서를 설치하고 Nginx 구성 파일에 필요한 변경을 수행하는 스크립트를 실행합니다.
스크립트가 실행되면 정보를 묻는 메시지가 표시됩니다. HTTP 트래픽을 HTTPS로 리디렉션할지 여부를 선택하라는 메시지가 나타날 때까지 모든 질문에 긍정적(예, 수락)으로 대답하세요. 아래 목록에는 질문과 제가 제안한 답변(2)이 나와 있습니다. Nginx가 안전하지 않은 요청을 리디렉션하도록 허용하면 누구도 명시적으로 http://를 입력할 수 없습니다. yoursite.com 안전하지 않은 Jenkins 버전으로 이동하세요. Nginx는 보안 버전으로 리디렉션합니다.
... Deploying Certificate to VirtualHost /etc/nginx/nginx.conf Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
마지막으로 정기적으로 인증서를 갱신하려면 cron 작업을 활성화해야 합니다. 그렇지 않으면 만료되어 브라우저에서 사이트 열기가 전혀 거부됩니다.
일일 크론 작업을 추가하려면 다음 한 줄짜리 명령을 실행하세요:
echo "0 0 * * * /snap/bin/certbot renew --quiet" | crontab -
cron 데몬은 매일 자정에 갱신 스크립트를 실행합니다. crontab -l을 사용하여 크론 작업을 나열할 수 있습니다. 명령을 실행하고 crontab -e로 편집하세요. 명령. 지금 웹사이트를 방문하면 Jenkins가 아닌 Nginx 테스트 페이지가 표시됩니다. 이 문제는 곧 수정될 예정이지만 아래 이미지와 같이 Chrome 주소 표시줄에서 '보안되지 않음' 경고가 사라졌는지 확인하세요.
Nginx가 Jenkins를 제공하도록 하려면 /etc/nginx/nginx.conf를 일부 변경해야 합니다. 파일. 이 코드 조각에 대한 크레딧은 Kerren의 Medium 블로그에 있습니다. nano 편집기를 사용하는 것이 아마도 구성 파일을 편집하는 가장 쉬운 방법일 것입니다:
nano /etc/nginx/nginx.conf
도메인 이름이 나열된 서버 블록을 찾고 아래 목록에서 강조 표시된 줄을 nginx.conf 파일에 추가하세요. 세 개의 새 줄 중 첫 번째 줄은 서버 블록 위에 있고 나머지는 루트 위치 블록에 들어갑니다.
구성 파일을 업데이트한 후 변경 사항을 적용하려면 Nginx를 다시 로드해야 합니다. 선택적으로 다음 명령을 사용하여 다시 로드하기 전에 구성 파일을 테스트할 수 있습니다:
Nginx는 OK를 인쇄하거나 nginx.conf의 어느 줄에 있는지 알려줄 것입니다. 파일 오류입니다. 변경 사항에 만족하면 다음 명령을 사용하여 웹 서버를 다시 로드할 수 있습니다:
이제 브라우저에서 Jenkins 사이트를 방문하면 아래 이미지와 같이 Jenkins 시작하기 페이지가 표시됩니다. 이번에는 보안 연결을 통해 제공되며 웹 GUI 인터페이스 내에서 Jenkins를 안전하게 계속 구성할 수 있습니다.
Jenkins 웹사이트를 처음 방문하면 Linux 파일 시스템의 파일에 있는 비밀번호를 묻는 메시지가 표시됩니다. SSH를 통해 로그인한 상태에서 아래 명령을 사용하여 비밀번호를 표시하세요. 웹 GUI에 액세스하려면 브라우저에 복사하여 붙여넣으세요.
cat /var/lib/jenkins/secrets/initialAdminPassword
다음 화면에서 Jenkins는 제안된 플러그인을 설치할 것인지, 아니면 설치할 플러그인을 지정할 것인지 묻습니다. 추천 플러그인 설치를 선택하세요. 지금은 옵션입니다. 나중에 언제든지 플러그인을 추가하거나 제거할 수 있습니다.
다음 페이지에서는 관리자를 생성해야 합니다. 세부 정보를 입력하고 새 계정에 사용할 강력한 비밀번호를 만드세요. 기본적으로 로그인한 사용자만 Jenkins 서버에 액세스할 수 있습니다. 익명의 사용자는 귀하의 웹사이트를 방문하는 경우에만 로그인 대화 상자를 볼 수 있습니다. 당신이 내 *데모 사이트 jenkins.vhdlwhiz.com에 액세스할 수 있는 유일한 이유 서버를 변경했다는 것입니다. 일부 보기에 익명 액세스 권한을 부여하기 위해 Matrix Authorization Strategy 플러그인을 사용했습니다.
* 업데이트:2020년 5월 13일에 데모 사이트를 폐쇄했습니다
Jenkins가 플러그인 설치를 완료하면 "Jenkins가 준비되었습니다!"라는 메시지가 표시됩니다. 위 이미지처럼 메시지가 뜹니다. 새로운 Jenkins 설치의 빈 개요 페이지로 이동하는 버튼을 클릭하세요.
가장 먼저 해야 할 일은 여러 플러그인을 설치하는 것입니다. Jenkins에는 확장 프로그램 설치, 업데이트, 제거에 사용할 수 있는 플러그인 관리자가 내장되어 있습니다. 대부분의 요구 사항을 처리할 수 있는 플러그인을 찾을 수 있습니다. Jenkins에 기능을 추가해야 할 경우 플러그인 관리자의 검색 기능을 사용하세요.
예제 Jenkins 서버를 설정할 때 사용한 플러그인을 설치해 보겠습니다. 사이드바에서 Jenkins 관리->플러그인 관리->사용 가능을 선택합니다. . 검색 필드에 무언가를 입력하지 않으면 플러그인이 나열되지 않습니다. 입력하면 표시됩니다.
제가 설치를 권장하는 첫 번째 플러그인의 이름은 Blue Ocean입니다. 이 플러그인은 Jenkins 워크플로와 사용자 인터페이스를 현대화한 것입니다. 또한 다른 유용한 플러그인도 많이 제공하므로 개별적으로 설치할 필요가 없습니다. 아래 이미지와 같이 플러그인 관리자에서 '블루오션'을 검색하여 선택하여 설치하세요.
설치를 클릭한 후 나타나는 설치 진행 페이지에서 설치가 완료되고 실행 중인 작업이 없으면 Jenkins 다시 시작을 선택할 수 있는 옵션이 있습니다. . 옆에 있는 확인란을 선택하면 플러그인 설치가 완료된 후 Jenkins가 다시 시작됩니다. Jenkins를 다시 시작하는 또 다른 방법은 SSH를 통해 서버에 로그인하고 다음 명령을 실행하는 것입니다:
systemctl restart jenkins
Blue Ocean이 설치한 다른 플러그인의 긴 목록을 제외하면 언뜻 눈에 띄는 변화는 없습니다. 하지만 아래 이미지와 같이 사이드바에 새 메뉴 항목이 표시됩니다. 클릭하면 일반 Jenkins 인터페이스와는 상당히 다른 Blue Ocean GUI로 이동합니다. 시도해 보세요!
제가 항상 설치하는 다음 플러그인은 순전히 미용을 위한 것입니다. Green Balls 플러그인에는 구성이 필요하지 않습니다. 플러그인 관리자에서 'green ball'을 검색하여 아래 이미지와 같이 설치하시면 됩니다.
기본적으로 Jenkins는 개요 페이지에서 파란색 볼을 사용하여 작업 상태가 성공임을 나타냅니다. 그 이유는 Jenkins의 발명가가 일본인이라는 것과 관련이 있습니다. 흥미롭게도 일본에서는 OK 상태를 나타낼 때 파란색을 녹색과 바꿔 사용할 수 있습니다. 이에 대한 자세한 내용은 이 기사에서 작성자가 직접 이유를 설명하는 내용을 들을 수 있습니다.
세계 대부분의 다른 지역의 사용자는 아마도 녹색 상태 공을 선호할 것입니다. 아래 이미지와 같이 Green Balls 플러그인을 사용하면 이 문제를 쉽게 해결할 수 있습니다.
내가 설치한 다음 플러그인의 이름은 Locale입니다. 사용 가능에서 '로케일'을 검색하세요. 플러그인 관리자의 탭. 아래 이미지와 같이 플러그인을 설치하세요.
플러그인을 사용하면 Jenkins가 모든 사용자에 대해 GUI에서 동일한 언어를 사용하도록 할 수 있습니다. 기본적으로 Jenkins는 사용자 인터페이스를 웹 브라우저가 사용하는 언어로 변환합니다. 저는 노르웨이 사람이지만 영어로 된 Jenkins를 선호합니다. 번역이 좀 부족했어요. 또한 Jenkins에서 작업을 수행하는 방법을 알아야 할 경우 영어로 답변을 검색하는 것이 훨씬 더 쉽습니다.
물론, 이 플러그인을 원하는지는 전적으로 귀하에게 달려 있습니다. 설치하는 경우 Jenkins 관리->시스템 구성으로 이동해야 합니다. Locale이라는 섹션을 찾으세요. . 그런 다음 아래 이미지에 표시된 대로 "en_US"(또는 원하는 언어)를 입력하고 아래 상자를 선택하여 모든 사용자에게 이 언어를 적용해야 합니다. 페이지 하단으로 스크롤한 후 저장을 클릭하는 것을 잊지 마세요. .
내 설정을 복제하는 데 필요한 마지막 플러그인은 Sidebar Link 플러그인입니다. Jenkins 사이드바에 사용자 정의 링크를 추가할 수 있습니다. 나중에 이를 사용하여 FPGA 릴리스(비트파일)에 대한 링크를 추가할 것입니다. 아래 이미지와 같이 플러그인 관리자에서 '사이드바'를 검색하여 플러그인을 설치하세요.
저장소가 공개인지 비공개인지에 관계없이 Jenkins에게 GitHub 계정에 대한 일부 권한을 부여해야 합니다. 최소한 가장 쉬운 방법으로 이를 수행하려면 Jenkins GitHub 플러그인이 GitHub와의 인터페이스를 관리하도록 해야 합니다. Blue Ocean은 이미 GitHub 플러그인을 설치했습니다. 이를 구성하는 단계는 다음과 같습니다.
먼저 시스템에 Git을 설치해야 합니다. GitHub 플러그인에는 반드시 필요한 것은 아니지만 Jenkins 작업을 시작하려면 반드시 있어야 합니다. CentOS Linux에 Git을 설치하려면 다음 명령을 실행하세요:
GitHub에 로그인하고 오른쪽 상단에 있는 프로필 사진을 클릭한 다음 설정을 선택하고 개발자 설정으로 이동하세요. . 그런 다음 개인 액세스 토큰을 선택하세요. 왼쪽 사이드바 메뉴에서 클릭하거나 이 링크를 클릭하면 해당 페이지로 바로 이동됩니다.
여기에서 새 토큰 생성을 클릭해야 합니다. , 아래 이미지와 같이. GitHub는 다시 한 번 비밀번호를 묻습니다. 지금 하고 있는 일은 본질적으로 새로운 애플리케이션별 비밀번호를 만드는 것입니다. 실제 비밀번호를 공유하는 것보다 비밀번호를 취소할 수 있고 토큰에 부여된 권한을 제한할 수 있기 때문에 더 좋습니다. 이것이 열리는 페이지에서 할 일입니다.
비밀번호를 입력한 후 토큰에 이름을 지정해야 합니다. 그 이름은 바로 당신을 위한 것입니다. 예를 들어 "Jenkins" 등 무엇이든 될 수 있습니다. 그런 다음 최소한 admin:org_hook을 활성화해야 합니다. , admin:repo_hook 및 저장소 아래 이미지와 같이 권한을 부여합니다. 다른 모든 상자는 선택하지 않은 채로 둘 수 있습니다.
마지막으로 토큰 생성을 클릭하면 , 액세스 코드가 나타납니다. 다시 볼 수 없으므로 해당 페이지를 떠나기 전에 복사해야 합니다. 잊어버린 경우 토큰을 삭제하고 다시 만드세요.
토큰을 복사한 후 Jenkins로 이동하여 Jenkins 관리->시스템 구성을 선택합니다. , GitHub 섹션을 찾으세요. , 아래 이미지와 같이. 드롭다운 메뉴에서 GitHub 서버->GitHub 서버 추가를 선택하세요. .
표시되는 새 GitHub 서버 섹션에서 후크 관리 상자를 선택하세요. . 이렇게 하면 Jenkins는 모니터링 중인 저장소에 대해 GitHub에 웹후크를 설치합니다. 사용자가 관련 GitHub 저장소에 코드를 푸시할 때 Jenkins에서 시뮬레이션을 실행하거나 빌드하는 데 이를 사용하기 때문에 이것이 특히 유용하다는 것을 나중에 알게 될 것입니다.
자격 증명(추가)->Jenkins를 선택하세요. 아래 이미지와 같이 확인란을 선택한 후.
열리는 창에서 종류를 변경하세요. 비밀 텍스트 드롭다운 . 그런 다음 이전에 GitHub에서 생성한 개인 액세스 토큰을 비밀에 붙여넣으세요. 필드. ID 필드에 "GitHub"라고 쓰고 추가를 누르세요. .
마지막으로 기본 구성 메뉴로 돌아가서 비밀 텍스트를 추가한 후 새로운 GitHub를 선택하세요. 자격 증명의 키 메뉴. 그런 다음 연결 테스트를 누르세요. Jenkins가 액세스 토큰을 사용하여 GitHub와 통신할 수 있는지 확인합니다. 모든 것이 잘 진행되었다면 아래 이미지와 같은 메시지가 표시됩니다.
페이지 하단으로 스크롤한 후 저장을 클릭하세요. 구성 페이지를 떠나기 전에.
문제가 발생하여 여러 자격 증명을 추가하게 된 경우 Jenkins->사용자 관리 관리로 이동하여 삭제할 수 있습니다. 을 클릭하고 사용자 이름을 클릭합니다. 이제 왼쪽 사이드바에 자격 증명이라는 메뉴 항목이 있습니다. . 여기에서 Jenkins가 저장한 모든 키를 보고 편집할 수 있습니다.
코드에 문제가 있는 경우 자동 이메일을 보내도록 Jenkins를 구성할 예정입니다. 이를 위해서는 Jenkins 관리->시스템 구성에서 몇 가지 사항을 변경해야 합니다. 메뉴.
가장 먼저 해야 할 일은 Jenkins가 자동 이메일을 보낼 때 사용할 보낸 사람 주소를 입력하는 것입니다. 시스템 관리자 이메일 주소 찾기 구성 페이지의 필드에 Jenkins가 보낼 주소를 입력하세요.
참고 사항:Jenkins 도메인 이름으로 끝나는 주소를 입력하는 것이 가장 좋습니다. 그러면 이메일이 스팸 폴더에 들어갈 가능성이 최소화됩니다. Jenkins 서버에는 다른 도메인을 대신하여 이메일을 보낼 수 있는 권한이 없지만 대부분의 이메일 서비스는 보내는 서버와 동일한 도메인의 보낸 사람 주소를 허용합니다. 이에 대한 자세한 내용은 Wikipedia 기사를 참조하세요. 아래 이미지에는 Jenkins 서버와 동일한 도메인으로 끝나는 보낸 사람 주소를 입력했습니다.
다음으로 Jenkins에게 이메일을 보낼 수 있는 방법을 제공해야 합니다. 가장 간단한 방법은 VPS에 SMTP(메일) 서버를 설치하는 것입니다. 로그인하고 다음 명령을 실행하면 됩니다:
yum -y install sendmail systemctl enable sendmail systemctl restart sendmail
sendmail을 설치한 후 , Jenkins 시스템 구성으로 돌아가서 SMTP 서버에 "localhost"를 입력하세요. 필드는 아래 이미지와 같습니다.
이 시점에서 미등록 사용자에게 전송을 허용하는 확인란을 선택할 수도 있습니다. 이는 Jenkins 사용자 계정이 없는 사용자를 의미합니다. 나중에 GitHub에 잘못된 코드를 푸시하는 사람에게 이메일을 보내도록 Jenkins를 구성하겠습니다. Jenkins는 GitHub에서 범인의 이메일 주소를 가져오지만 해당 사람이 일치하는 Jenkins 계정을 가지고 있거나 이 상자를 선택한 경우에만 작동합니다.
마지막으로 위 이미지와 같이 구성을 테스트할 수 있습니다. 테스트 구성을 누른 후 , "이메일이 성공적으로 전송되었습니다"라는 메시지가 나타나고 이메일이 받은편지함에 도달해야 합니다. 5분 이내에 이메일을 받지 못한 경우 스팸 폴더를 확인해보세요.
저는 이 예제 프로젝트의 코드를 시뮬레이션, 컴파일 및 구현하기 위해 Xilinx Vivado를 사용하고 있습니다. 대상 장치는 ZebBoard 개발 보드의 Xilinx Zynq-7000 FPGA입니다. 이 섹션에서는 무료 WebPACK 라이선스를 사용하여 VPS에 Vivado를 설치하는 방법을 보여드리겠습니다.
첫 번째 단계는 아래 이미지에 표시된 Xilinx Unified Installer:Linux Self Extracting Web Installer를 다운로드하는 것입니다. 설치 프로그램을 다운로드하려면 로그인하거나 새로운 Xilinx 계정을 만들어야 합니다.
다운로드가 완료되면 데스크톱 컴퓨터에서 Jenkins 서버로 복사해야 합니다. 데스크탑에서 Linux 셸에 액세스할 수 있는 경우 다음 명령과 같이 보안 파일 복사를 사용하는 것이 좋습니다.
설치 프로그램을 실행하기 전에 Vivado의 종속성을 충족하기 위해 몇 가지 패키지를 설치해야 합니다. 이를 수행하려면 다음 명령을 실행하세요:
yum -y install tar yum -y install java-11-openjdk-devel yum -y install ncurses-compat-libs yum -y install gcc
그런 다음 다음과 같이 Xilinx Unified 설치 프로그램을 실행하십시오:
./Xilinx_Unified_2019.2_1106_2127_Lin64.bin --keep --noexec --target Xil_installer
.bin 파일은 Xil_installer라는 새 디렉터리에 설치 파일의 압축을 풉니다. . 대신 아래 나열된 오류가 발생하는 경우 tar를 설치하지 않았기 때문입니다. .
Verifying archive integrity... All good. Uncompressing Xilinx InstallerExtraction failed. Terminated
Xilinx Unified 설치 프로그램은 시스템에 다양한 Xilinx 도구를 설치할 수 있습니다. 따라서 xsetup을 실행해야 합니다. Xil_installer의 파일 관심 있는 소프트웨어를 지정하는 디렉토리:
cd Xil_installer/ ./xsetup -b ConfigGen
xsetup 스크립트는 어떤 도구를 갖고 싶은지 묻는 메시지를 표시합니다. Vivado에 "2"를 입력하세요. , Vivado HL WebPACK의 경우 “1” , 아래 목록과 같습니다.
Select a Product from the list: 1. Vitis 2. Vivado 3. On-Premises Install for Cloud Deployments 4. BootGen 5. Lab Edition 6. Hardware Server 7. Documentation Navigator (Standalone) Please choose: 2 Select an Edition from the list: 1. Vivado HL WebPACK 2. Vivado HL Design Edition 3. Vivado HL System Edition Please choose: 1
Xilinx WebPACK 에디션을 설치하려면 설치 중에 Xilinx 계정에 로그인해야 합니다. 데스크톱 컴퓨터에서는 설치 프로그램 GUI가 이 프로세스를 안내하지만 서버에는 GUI가 없으므로 xsetup을 사용하여 인증해야 합니다. 스크립트. 인증 토큰을 생성하려면 다음 명령을 실행하세요:
작동하기 전에 명령을 몇 번 실행해야했습니다. 처음에는 "인터넷 연결이 확인되었으며 인터넷에 연결할 수 있습니다."라는 오류와 함께 스크립트가 중지되었습니다. 그러나 몇 번 시도한 끝에 로그인할 수 있었습니다. 스크립트는 사용자 ID와 비밀번호를 묻습니다. 이는 xilinx.com에서 설치 프로그램을 다운로드할 때 사용한 이메일과 비밀번호입니다.
마지막으로 배치 모드로 Vivado를 설치할 준비가 되었습니다. 설정 스크립트를 호출할 때 xsetup이 실행되도록 설치 구성 파일을 지정해야 합니다. 다운로드할 도구를 알고 있습니다. 구성 파일은 .Xilinx에 있습니다. 루트 사용자의 홈 디렉터리에 있는 폴더입니다. 구성 파일을 사용하여 설치를 시작하려면 다음 명령을 실행하십시오:
./xsetup -a XilinxEULA,3rdPartyEULA,WebTalkTerms \ -b Install -c ~/.Xilinx/install_config.txt
설치 프로세스를 완료하는 데 오랜 시간이 걸립니다. Vivado 설치는 24GB의 공간을 사용합니다. 이제 이 모든 것이 상대적으로 느린 Xilinx 서버에서 다운로드되고 있습니다. 저에게는 다운로드가 2시간 조금 넘게 걸렸습니다.
설치가 완료된 후 Vivado가 배치 모드에서 성공적으로 시작되는지 테스트해야 합니다. Xilinx provides a shell script that sets up the environment for you. Before you can run Vivado, you need to use the source command to load the content of the script into your active shell:
source /tools/Xilinx/Vivado/2019.2/settings64.sh
Then, you are ready to run Vivado. But there’s no GUI environment installed on your server, so we have to start it in batch mode by using this command:
If Vivado starts and exists immediately without printing any errors, it’s an indication that Vivado has everything it needs, and you are ready to go. Note that if you are getting the error listed below, it’s because you haven’t installed the ncurses-compat-libs package, as we talked about at the start of this section.
application-specific initialization failed: couldn't load file "librdi_commontasks.so": libtinfo.so.5: cannot open shared object file: No such file or directory
To prepare Jenkins for Vivado, we need to make some changes to the general settings. Head to Manage Jenkins->Configure System and check that all the default settings make sense for you.
As I mentioned earlier, Vivado uses a lot of RAM. The resource usage depends on your target FPGA, and you can get an indication of how much you need from the Xilinx Memory Recommendations page. Therefore, I recommend that you change the default number of parallel jobs that can run from 2 to 1. Unless you allocated vast RAM resources on your VPS, you probably want to set # of executors to 1, as shown in the image below.
Instead of defining the environment variables in every Jenkins job, we will specify the PATH globally for all jobs. That makes it easier for you to swap to a newer version of Vivado in the future. Then you can refer to the ‘vivado’ executable in your scripts, and it will always point to the latest version, or whichever you decide.
Scroll to the Global properties section and check Environment variables . Click Add to get a new entry. Make sure to include the standard Linux PATH 뿐만 아니라. I used “PATH=/tools/Xilinx/Vivado/2019.2/bin:/sbin:/usr/sbin:/bin:/usr/bin”, as shown in the image below.
Don’t forget to scroll to the bottom of the page and click Save .
I chose to manage the Vivado projects in GUI mode. For each repository, I created a new project from within the regular Vivado GUI, adding source files, setting libraries, and all of that. However, the .xpr project files are binary and depend on a lot of other temporary files in the project directory.
Binary files are not suitable for SCMs like Git. Fortunately, Xilinx has thought of this and written a guideline (XAPP1165) for how to use Vivado with version control systems. What we do is to use the write_project_tcl command in Vivado to export the entire project into a Tcl script. The script contains human-readable Tcl code suitable for Git.
I’ve organized all of the Git repos so that all files that belong to the Vivado projects are in a subfolder named “vivado”, while the VHDL source files are in the parent directory. Check out the demo packages project on my GitHub to see what I mean. For each repo, we will put the Vivado Tcl scripts in the vivado folder. You will also find the create_vivado_proj.tcl file, which is the human-readable version of the Vivado project.
To create the create_vivado_proj.tcl file, start by setting up the Vivado project as you wish in the Vivado GUI. Make sure that the Vivado project resides within a vivado subfolder. When you’re happy with the project, export it by entering the following commands in the Vivado Tcl console:
cd [get_property DIRECTORY [current_project]] write_project_tcl -force -target_proj_dir . create_vivado_proj
Add the create_vivado_proj.tcl file to Git, and set up the gitignore to ignore the rest of the Vivado project. Here’s the content of my .gitignore file which ignores everything but Tcl scripts in the vivado folder:
It’s a good idea to test the Vivado project manually on the VPS before you start creating Jenkins jobs. By default, the daemon runs from a user account named jenkins on the Linux server. Therefore, you should test the Vivado project using the jenkins user.
Make sure that you have Git installed on the Linux server before you start this experiment. Run this command to install Git after logging in as root:
You can’t log in to the jenkins user directly, but you can change to it from the root user like this:
If you now run a pwd command, you will see that you are at /var/lib/jenkins :
[jenkins@jenkins ~]$ pwd /var/lib/jenkins
That’s because this isn’t a regular user account that has the home directory under /home , as is the norm on Linux systems. It’s only for running the Jenkins daemon, but we can log in to perform a manual walkthrough of the build process in the Jenkins environment.
The home folder is full of all the dynamic data like logs, user settings, and plugins that you have downloaded. When we later start running jobs in the Jenkins GUI, they will appear in the jobs folder.
Let’s go to the jobs folder to perform our experiment:
cd /var/lib/jenkins/jobs/
You can clone your Git repository directly into the jobs folder. Your Git repo has to be accessible without using a password. Either because it’s public, or because you have set up passwordless login as described on the GitHub help pages.
If you don’t have a Git repository with the Vivado project ready, feel free to clone one of my repos like this:
git clone https://github.com/jonasjj/Jenkins-demo-packages
Then, cd into the new directory of the Git repository, and further into the vivado folder:
cd Jenkins-demo-packages/vivado/
If you downloaded my example, you would find two Tcl files:create_vivado_proj.tcl and check_syntax.tcl . The first one is the Vivado project converted to a Tcl file, and the second one is a script that we haven’t talked about yet. It’s for checking the syntax of VHDL files in the Vivado project.
Before we can run any Vivado command, we need to set the PATH environment variable in the current shell. In Jenkins, we solved this by using Global properties , but now we are not coming through Jenkins, so we have to source the setup script from Xilinx like this:
source /tools/Xilinx/Vivado/2019.2/settings64.sh
Now that the vivado executable is in our path, let’s start by recreating the project. This is the command for doing that when running Vivado in batch mode:
vivado -mode batch -source create_vivado_proj.tcl
After you hit Enter, you should see a whole lot of Tcl code echoed to the console. It’s the code for recreating the Vivado project that’s executing. If you didn’t see any obvious errors, type the command “echo $?” in the terminal before you do anything else. The output should be 0 if everything went well, as we can see from the listing below.
INFO: [Common 17-206] Exiting Vivado at Sun Apr 19 18:32:48 2020... [jenkins@jenkins vivado]$ echo $? 0
The “echo $?” command shows you the exit status from the previous command that you executed in Linux. An exit status of 0 means that everything is OK, no error. Any other exit status than 0 is an indication of error. Those are old Unix conventions that you can read more about here. Anyway, the exit status is important for Jenkins because that’s how it decides if a job stage is a success or a failure.
If you now do a directory listing, you will see that Vivado has recreated the project’s binary files:
[jenkins@jenkins vivado]# ls -la total 72 drwxrwxr-x. 6 jenkins jenkins 4096 Apr 19 18:32 . drwxrwxr-x. 4 jenkins jenkins 4096 Apr 19 18:18 .. -rw-rw-r--. 1 jenkins jenkins 217 Apr 19 18:18 check_syntax.tcl -rw-rw-r--. 1 jenkins jenkins 23375 Apr 19 18:18 create_vivado_proj.tcl drwxrwxr-x. 3 jenkins jenkins 16 Apr 19 18:32 packages.cache drwxrwxr-x. 2 jenkins jenkins 26 Apr 19 18:32 packages.hw drwxrwxr-x. 2 jenkins jenkins 6 Apr 19 18:32 packages.ip_user_files -rw-rw-r--. 1 jenkins jenkins 9314 Apr 19 18:32 packages.xpr -rw-rw-r--. 1 jenkins jenkins 638 Apr 19 18:32 vivado.jou -rw-rw-r--. 1 jenkins jenkins 20153 Apr 19 18:32 vivado.log drwxrwxr-x. 2 jenkins jenkins 6 Apr 19 18:32 .Xil
Let’s try another experiment with running Tcl scripts in Vivado batch mode. Create a one-liner Tcl script by using the following command:
Now, run the script in Vivado batch mode:
vivado -mode batch -source test.tcl
After Vivado closes, check the exit code once more using the “echo $?” command:
[jenkins@jenkins vivado]# echo $? 1
It’s 1, which means exit failure in Unix. If you change the content of the test.tcl script to “exit 0”, and run Vivado once again, you will see that the exit status is now 0, indicating success. Try it!
The exit keyword is standard Tcl. We are going to use it as the interface between Vivado and Jenkins. Jenkins runs whatever Tcl script we create in Vivado, and looks at the exit status to determine if it shall mark the job stage as success or failure.
Remember to delete our little test project from the jobs folder when you are happy with the experiment:
cd /var/lib/jenkins/jobs/ [jenkins@jenkins jobs]# rm -rf Jenkins-demo-packages
This Tcl script runs a syntax check of the VHDL files in the project. If you are going to simulate or implement the code, you won’t need this script because any syntax errors will break the compilation. But for my packages project, it doesn’t make any sense to create a testbench for it. The files just contain constant and types declarations. I still want to catch any coding errors pushed to this repo, and that’s where the syntax check comes in handy.
In the script that is listed below, we start by opening the project file. Then, we call the Vivado check_syntax command while telling it to save the output to a variable called msg . After the check has completed, we look at the output message to see if there were any errors reported. If check_syntax reported anything at all, we set the exit status to 1 (failure). If there were no errors, we exit 0 (success).
check_syntax.tcl:
# Check for syntax errors
# Return exit code 1 on error, else 0
open_proj packages.xpr
set msg [check_syntax -fileset sim_1 -return_string]
set ret_val 0
if {$msg != ""} {
set ret_val 1
}
puts $msg
exit $ret_val
Vivado supports all of the standard Tcl keywords, and there are also a lot of built-in commands like check_syntax. I recommend taking a look at these two Xilinx documents that cover the Tcl scripting capabilities in great detail:
Vivado Design Suite Tcl Command Reference Guide (UG835)
Vivado Design Suite User Guide Using Tcl Scripting (UG894)
The next script that I created is for running the testbench in batch mode. For this to work, you have to configure the simulation sets in the Vivado GUI before you export the project to Tcl. Go ahead and recreate one of the simulation projects on your desktop computer using the create_vivado_proj.tcl script to see how I set it up beforehand. You can open the reconstructed projects in the Vivado GUI.
As you can see from the listing below, I start by opening the project. Then, I set the name of the simulation fileset to a variable (usually sim_1 ). After we launch the simulation, we also have to close it. Otherwise, the status of the simulation won’t get written to the log files.
run_simulation.tcl:
open_proj seg7.xpr set sim_fileset sim_1 launch_simulation -simset [get_filesets $sim_fileset] close_sim # Look for assertion failures in the simulation log set log_file [glob *sim/$sim_fileset/behav/xsim/simulate.log] set fp [open $log_file] set file_data [read $fp] exit [regex "Failure:" $file_data]
Now, I struggled to find a good way of getting the simulation status. My VHDL testbenches terminate on a VHDL finish keyword on success. Errors will result in a VHDL assertion failure. There’s no obvious way to find out why the simulator stopped by using Tcl commands in Vivado.
Fortunately, Tcl is a powerful scripting language. My workaround is to open the simulation log and look for the string “Failure:”, which indicates a VHDL assertion failure. Finally, we exit 1 if the word is in the log, or 0 if it isn’t.
In the Tcl script for synthesizing in Vivado batch mode, we start by opening the project file. Then, We assign the run name to a variable. You must have added the design files to the Vivado project before you exported it to Tcl. If you didn’t change the name of the synthesis run in the GUI, it’s will probably be “synth_1”.
You should set the CPU count variable to the number of logical processors that your server has. This number controls the degree of multithreading that Vivado uses. I opted for the VPS with 4 CPUs on UpCloud, and therefore set the CPU count to 4.
run_synthesis.tcl :
open_proj seg7.xpr
set run_name synth_1
set cpu_count 4
reset_runs $run_name
launch_runs $run_name -jobs $cpu_count
wait_on_run $run_name
set status [get_property STATUS [get_runs $run_name]]
if {$status != "synth_design Complete!"} {
exit 1
}
exit 0
The launch_runs command is non-blocking, meaning that it will complete before the actual synthesis. If we try to read the status right after calling launch_run , it will be “Running”. To pause the script until the synthesis completes, we call the wait_on_run command.
Finally, we get the run status and exit 0 or 1, depending on the status message.
The script for running Place and Route (PAR) in Vivado batch mode is similar to the synthesis script. The difference is that the run name is now “impl_1”, and that we are looking for another success message.
run_implementation.tcl :
open_proj seg7.xpr
set run_name impl_1
set cpu_count 4
reset_runs $run_name
launch_runs $run_name -jobs $cpu_count
wait_on_run $run_name
set status [get_property STATUS [get_runs $run_name]]
if {$status != "route_design Complete!"} {
exit 1
}
exit 0
Finally, after if the implementation completes successfully, we can generate a bitstream for programming the FPGA. The script is similar to the previous one, but the launch_runs command is slightly different. And of course, we are looking or a different status in the end.
generate_bitstream.tcl :
open_proj seg7.xpr
set run_name impl_1
set cpu_count 4
launch_runs $run_name -to_step write_bitstream -jobs $cpu_count
wait_on_run $run_name
set status [get_property STATUS [get_runs $run_name]]
if {$status != "write_bitstream Complete!"} {
exit 1
}
exit 0
A job in Jenkins refers to a set of grouped software tasks. Jenkins displays jobs and their current status as items listed on the overview page. You can start jobs manually from the web interface, or they can be triggered automatically, for example, when someone pushes code to a repo, or as a result of another job completing. We will do both.
Jenkins offers several ways of managing jobs. The traditional method is the Freestyle project , where you specify every action from within the Jenkins web GUI. The more modern way of managing Jenkins jobs is to use a pipeline script that stores all of the information about the execution flow. The pipeline scripts have the benefit that you can add them to your SCM.
To create a new pipeline script, select New item from the Jenkins sidebar. In the dialog that opens, select the Pipeline option and click OK, as shown in the image below.
The first thing we have to do in the job configuration is to add the GitHub repository that contains the source code. In this example, I am using the packages repo, but the procedure is the same for all the other jobs and repos. Check the GitHub project box and enter the address in the Project url field that appears, as shown in the image below.
After that, we can set up the build triggers for this job. I want this job to start when someone pushes code to the GitHub repo. To do that, we check the box that says GitHub hook trigger for GITScm polling , as shown in the image below. Note that this will only work if you have checked the Manage hooks box in the global settings, as we did earlier.
At the bottom of the job configuration page is the Pipeline 섹션. Here, you have to option to enter the pipeline script directly into the config page. But we want to version control the pipeline script. Therefore, we chose the Pipeline script from SCM 옵션. Make sure that Git is selected, as shown in the image below.
Paste in the URL of your GitHub repository, and select your credentials if it’s a private repo. Ours is public, so we will leave the credentials blank. We will also go with the default master branch selection.
Finally, we have to select the path to the Jenkins script within the Git repository. I have created a file named Jenkinsfile at the root of each repo. Don’t forget to click Save before you leave the page.
Pipeline scripts follow the same syntax rules as the Apache Groovy programming language, which I must admit I had never heard of before. Nevertheless, you won’t have a hard time understanding pipeline scripts if you’ve done any kind of modern programming. At first glance, it looks like a JSON schema without the commas separating the data items.
The scripts are quite versatile, and there are many options for things like executing stages in parallel or running tasks on multiple Jenkins servers. I suggest that you take a look at the official Jenkins pipeline documentation if you want to dig deeper into the matter.
Fortunately, you don’t need to know everything about them to benefit from pipeline scripts. We will use the format below as a template for all of your scripts. We will add as many stages as we need to split the job into logical steps.
pipeline {
agent any
stages {
stage('Stage name 1') {
steps {
// Command 1
// Command 2
// Etc.
}
}
stage('Stage name 2') {
steps {
// Command 1
// Command 2
// Etc.
}
}
}
post {
failure {
emailext attachLog: true,
body: '''Project name: $PROJECT_NAME
Build number: $BUILD_NUMBER
Build Status: $BUILD_STATUS
Build URL: $BUILD_URL''',
recipientProviders: [culprits()],
subject: 'Project \'$PROJECT_NAME\' is broken'
}
}
}
If somebody pushes faulty code to the repo, we want the culprit to receive an automated email with information about the failed job. To do that, we use a failure section within a post 섹션. This part of the script will only execute if any of the stages fail. Then, the job will stop. Jenkins won’t go to the next stage if one fails. Instead, it will jump into the failur e section. Jenkins then lifts the email addresses from the latest Git commits and sends them an email with a link to the broken build.
The only repo in our design that doesn’t have a testbench is the packages repo—instead, we user our check_syntax.tcl script to verify that the code is at least valid VHDL.
In the first step of our pipeline script, we call deleteDir() . That’s one of the basic commands available in Jenkins pipeline scripts. It cleans the working directory by removing any leftover from previous builds.
On the next line, we call git . Note that this is not the git Linux command, but a command referencing the git Jenkins plugin. We tell it to clone the repository into the workspace.
Finally, on the third line of the Create project stage, we use the sh keyword to call a Linux shell command. Here, we change to the vivado directory and run the create_vivado_proj.tcl script in Vivado batch mode to recreate the Vivado project.
Jenkinsfile:
pipeline {
agent any
stages {
stage('Create project') {
steps {
deleteDir() // clean up workspace
git 'https://github.com/jonasjj/Jenkins-demo-packages'
sh 'cd vivado && vivado -mode batch -source create_vivado_proj.tcl'
}
}
stage('Check VHDL syntax') {
steps {
sh 'cd vivado && vivado -mode batch -source check_syntax.tcl'
}
}
}
post {
failure {
emailext attachLog: true,
body: '''Project name: $PROJECT_NAME
Build number: $BUILD_NUMBER
Build Status: $BUILD_STATUS
Build URL: $BUILD_URL''',
recipientProviders: [culprits()],
subject: 'Project \'$PROJECT_NAME\' is broken'
}
}
}
In the second stage, the one named Check VHDL syntax , the Vivado project already exists, so we can jump to running our Tcl script. We use the shell command again to run the check_syntax.tcl file, which will exit 0 on success, or 1 on error, causing Jenkins to mark the build as a failure.
For all other jobs than the packages repo, the git one-liner command won’t work for checking out the code from GitHub. The problem is that these repos have dependencies in the form of submodules. The submodules reference other Git repositories, which the simple git command doesn’t pull by default. But that’s OK; we can fix the issue by using the more versatile checkout call, also well-documented on the Git plugin page.
Jenkinsfile;
pipeline {
agent any
stages {
stage('Create project') {
steps {
deleteDir() // clean up workspace
checkout([$class: 'GitSCM', branches: [[name: '*/master']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'SubmoduleOption',
disableSubmodules: false,
parentCredentials: false,
recursiveSubmodules: true,
reference: '',
trackingSubmodules: true]],
submoduleCfg: [],
userRemoteConfigs: [[
url: 'https://github.com/jonasjj/Jenkins-demo-bcd_encoder']]])
sh 'cd vivado && vivado -mode batch -source create_vivado_proj.tcl'
}
}
stage('Run simulation') {
steps {
sh 'cd vivado && vivado -mode batch -source run_simulation.tcl'
}
}
}
post {
failure {
emailext attachLog: true,
body: '''Project name: $PROJECT_NAME
Build number: $BUILD_NUMBER
Build Status: $BUILD_STATUS
Build URL: $BUILD_URL''',
recipientProviders: [culprits()],
subject: 'Project \'$PROJECT_NAME\' is broken'
}
}
}
Finally, we run the run_simulation.tcl script in Vivado in the next stage.
The above listing shows the script used in the bcd_encoder repo. Identical scripts, only with different repo URLs, are used for the counter, digit_selector, output_mux, reset, and seg7_encoder repos as well.
The seg7 repo contains the top module for our FPGA project. It pulls in all of the other repos as submodules. The pipeline script is similar to the one used for the simulation-only jobs, but with four added stages:Run simulation , Run implementation , Generate bitstream , and Release bitfile .
The first two stages create the project and run the simulation. I have already covered how they work in the previous sections of this article. The next three stages work the same way as the simulation stage, but with the Tcl script replaced with the ones that are relevant for the task.
Jenkinsfile:
pipeline {
agent any
stages {
stage('Create project') {
steps {
deleteDir() // clean up workspace
checkout([$class: 'GitSCM', branches: [[name: '*/master']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'SubmoduleOption',
disableSubmodules: false,
parentCredentials: false,
recursiveSubmodules: true,
reference: '',
trackingSubmodules: true]],
submoduleCfg: [],
userRemoteConfigs: [[
url: 'https://github.com/jonasjj/Jenkins-demo-seg7']]])
sh 'cd vivado && vivado -mode batch -source create_vivado_proj.tcl'
}
}
stage('Run simulation') {
steps {
sh 'cd vivado && vivado -mode batch -source run_simulation.tcl'
}
}
stage('Run synthesis') {
steps {
sh 'cd vivado && vivado -mode batch -source run_synthesis.tcl'
}
}
stage('Run implementation') {
steps {
sh 'cd vivado && vivado -mode batch -source run_implementation.tcl'
}
}
stage('Generate bitstream') {
steps {
sh 'cd vivado && vivado -mode batch -source generate_bitstream.tcl'
}
}
stage('Release bitfile') {
steps {
sh '''
PROJ_NAME=seg7
RELEASE_DIR=/usr/share/nginx/html/releases/
BASE_NAME=$PROJ_NAME-`date +"%Y-%m-%d-%H-%H:%M"`
BITFILE=$BASE_NAME.bit
INFOFILE=$BASE_NAME.txt
git log -n 1 --pretty=format:"%H" >> $INFOFILE
echo -n " $PROJ_NAME " >> $INFOFILE
git describe --all >> $INFOFILE
echo "" >> $INFOFILE
echo "Submodules:" >> $INFOFILE
git submodule status >> $INFOFILE
cp $INFOFILE $RELEASE_DIR
cp vivado/seg7.runs/impl_1/top.bit $RELEASE_DIR/$BITFILE
'''
}
}
}
post {
failure {
emailext attachLog: true,
body: '''Project name: $PROJECT_NAME
Build number: $BUILD_NUMBER
Build Status: $BUILD_STATUS
Build URL: $BUILD_URL''',
recipientProviders: [culprits()],
subject: 'Project \'$PROJECT_NAME\' is broken'
}
}
}
The final stage of the implementation job is named Release bitfile . It contains a shell script that copies the newly generated FPGA programming file to a release folder. The shell command renames the file to include the name of the project and a timestamp.
To maintain traceability, we also generate a text file that contains the Git hash of the main repo (seg7 ) and all of the submodules. When working with Git submodules, it’s not enough to store the hash of the main repo. To generate a hash for the main repo that includes changes in all submodules, we would have to commit the main repo after pulling and updating all submodules. We don’t want to do that automatically from Jenkins.
Note that implementing the FPGA for every single push, like I am doing in the example, is probably not what you want for a real-life Jenkins project. It can take hours to build a large-scale FPGA project, and that wouldn’t work when you have a team of developers pushing multiple times per day. Instead of building after each push to the repo, you can configure Jenkins to route the FPGA only once a day. For example, at midnight, as shown by the screenshot below from the job configuration page.
Our example project consists of several Git repositories, but they are all tied together as Git submodules. Except for packages, all the other repos depend on at least one other repository. Most depend on the packages repository. Have a look at the dependency graph that I presented earlier in this article to see how it all fits together.
Therefore, we should trigger jobs not only by pushes to the repo in question but also after any of the submodules are touched. We can achieve this in Jenkins by visiting every job and setting the Build after other projects are built option accordingly.
The image below shows the trigger for the bcd_encoder project. It will start after the packages repo, which it depends on, completes a build successfully.
The top module depends on all other repos. I have added them as watch projects in a comma-separated list, as shown in the image below. Note that you may not want to do this for the FPGA implementation job if it takes a long time to route, as I mentioned in the previous section.
Since we already have a web server running, we can use if for serving the release files over HTTP. I want all new bitfiles to appear on the URL jenkins.vhdlwhiz.com/releases . Let’s see how we can use Nginx for this.
Our implementation job already copies new bitfiles to a directory on the Nginx HTML root, but we haven’t created it yet. Create the release dir and give the Jenkins user write permissions by issuing the following commands:
mkdir /usr/share/nginx/html/releases/ chown jenkins.root /usr/share/nginx/html/releases/
Then we have to make a change to the /etc/nginx/nginx.conf file. Find the server section in the config file with a name equal to your domain. Add the following location section inside of it, directly below the root (‘/’) location section:
location ^~ /releases {
alias /usr/share/nginx/html/releases/;
autoindex on;
}
Finally, after you have saved the file, test the configuration file, and reload the Nginx server:
nginx -t systemctl reload nginx
If everything worked, you should be able to list the content of the release directory, as shown in the screenshot below from Google Chrome.
To tie the Jenkins web interface to the release dir, I want to create a link to if from the Jenkins sidebar. We have already installed the Sidebar Link plugin that enables custom links in the sidebar.
The next step is to go to Manage Jenkins->Configure System and scroll down to the Additional Sidebar Links 섹션. Here, we can specify the name and URL of the new link, as shown in the image below. The link icon field is optional. I reused one of the icons that came with the Jenkins server.
After completing the previous step, you should now have a custom link to the bitfile releases in the sidebar, complete with a nice-looking folder icon, as you can see from the image below.
Jenkins can be a valuable tool also for FPGA teams. Automating tasks can save your company time and improve the quality of your code. By using automatic build triggers and automated job pipelines, fewer coding errors will go unnoticed.
As we have seen from the example project presented in this article, Jenkins can implement a complete suite of regression tests for your VHDL code. It shows the current health of your project in a pleasant graphical web interface, suitable for even the most VHDL-illiterate project manager.
If you wish to try out Jenkins for FPGA development, I recommend following the steps in this article on an UpCloud VPS instance. I thoroughly researched all VPS providers a few years ago before moving VHDLwhiz to a VPS. I found that UpCloud was the fastest and best alternative. I’m still 100% pleased with the service.
If you decide to open an account on UpCloud, I kindly ask that you use my referral link or code:NV78V6 . Not only do you support VHDLwhiz, but you also get $25 of credit on UpCloud when using the promo code.
VHDL
압축 테스트는 압축 하중을 받을 때 재료의 거동에 대한 귀중한 통찰력을 제공하는 널리 사용되는 기계적 테스트입니다. 이 테스트는 항공우주, 자동차, 건설 등 산업 분야의 다양한 응용 분야에 적합한 재료를 선택하는 데 필수적입니다. 이 문서에서는 정의, 목적, 응용 프로그램, 압축 테스트 작동 방식은 물론 압축 테스트 수행과 관련된 단계를 자세히 살펴보겠습니다. 압축 테스트란 무엇인가요? 압축 시험은 압축 하중을 받을 때 재료의 거동을 결정하는 데 사용되는 기계적 시험입니다. 압축 테스트에서 수집된 데이터는 다양한 재료의 기계적 특
상호 인덕터는 상호 인덕턴스의 효과를 이용하는 인덕터입니다. 상호 인덕턴스는 인덕터의 자기장이 인접한 인덕터에 자기장을 유도할 때 발생합니다. 상호 인덕턴스는 변압기를 만드는 기본입니다. 위는 상호 인덕터 유형의 가장 일반적인 도식 기호입니다. 관련 워크시트: 승압, 강압 및 절연 변압기 워크시트