2020년 9월 26일 토요일

Very Large FFT for TMS320C6678

Introduction

이 백서는 TI의 TMS320C6678 8 코어 고정형 DSP 코어의 1, 2, 4 및 8 DSP 코어에서 16K ~ 1024K 샘플 크기의 1 차원 복합 단 정밀도 부동 소수점 FFT를 구현하는 초대형 FFT (VLFFT) 데모에 대해 설명합니다. C66x DSP 코어의 기능과 추가 된 코어 수에 비례하는 성능 향상을 통해 여러 코어에 걸친 병렬화를 수용하는 아키텍처의 기능을 보여주기위한 부동 소수점 DSP. FFT는 의료 영상, 통신, 군사 및 상업용 레이더, 전자전 (재머, 안티 재머)과 같은 애플리케이션에 사용되는 일반적인 신호 처리 빌딩 블록이므로이 데모의 알고리즘으로 FFT가 선택되었습니다. 1024K 샘플 FFT는 알고리즘이 1GHz에서 TMS320C6678 장치의 8 개 DSP 코어 모두에서 실행될 때 6.4ms에 불과한 것으로 나타났습니다.


TMS320C6678 SoC

TMS320C6678 장치는 TI의 C66x 고정 및 부동 소수점 DSP 코어를 기반으로하는 8 코어 DSP이며 완전한 멀티 코어 권한을 지원하는 TI의 혁신적인 KeyStone ™ 아키텍처를 기반으로합니다.

최대 1.25GHz에서 작동 할 수 있으며이 속도에서 160GFLOPS를 생성 할 수 있으며 일반적인 사용 사례에서 10W 미만을 소비합니다. 또한 DSP 코어 당 512KB의 L2 메모리와 총 8MB의 온칩 메모리를위한 4MB의 공유 메모리가 있으며 모두 ECC를 사용합니다. DDR3 인터페이스는 최대 1600MTPS를 실행할 수 있으며 최대 8GB의 외부 메모리에 액세스 할 수 있으며 64 비트 + 8 비트 ECC 인터페이스입니다. 주변 장치에는 PCIe, Serial RapidIO® 및 기가비트 이더넷, 타사 IP 블록을 통해 FPGA뿐만 아니라 다른 TI DSP, ARM® 및 ARM + DSP 프로세서에 최대 50Gbps 연결을 제공하는 TI의 HyperLink 인터페이스가 포함됩니다. .

VLFFT 데모에서 TMS320C6678 장치는 1333MHz에서 DDR3 전송을 사용하여 1GHz에서 작동합니다.


VLFFT 데모

VLFFT 알고리즘을 사용하려면 입력 데이터를 장치의 외부 메모리에 배치해야합니다. 데모 중에 데이터는 DSP 코어에 의해 액세스, 배포 및 처리 된 다음 출력이 외부 메모리에 배치됩니다. 측정 된주기 수와 시간은이 전체 프로세스를 포함합니다. 다음 크기의 FFT에서 계산을 수행하기 위해 다른 수의 코어 (1, 2, 4 또는 8)를 사용하도록 소프트웨어를 구성 할 수 있습니다.

• 16K

• 32K

• 64K

• 128K

• 256K

• 512K

• 1024K

FFT 구현은 계산 부하를 여러 코어에 분산하고 C66x DSP 코어의 고성능 계산 능력을 완전히 활용하여 최대 성능을 달성하도록 설계되었습니다. 기본적인 데시 메이션-인-타임 접근법은 1 차원 매우 큰 FFT 계산을 2 차원 FFT 계산과 유사한 형태로 공식화하는 데 사용됩니다.

매우 큰 N의 경우 N = N1 * N2로 계수 될 수 있습니다. 크기가 매우 큰 경우 1 차원 입력 배열을 N1 행과 N2 열의 2 차원 배열로 나타낼 수 있으며 다음 단계를 수행하여이 표현에서 매우 큰 1 차원 FFT를 계산할 수 있습니다.

1. 열 방향에서 N1 크기의 N2 FFT 계산

2. 회전 계수로 곱하기

3. N1 크기의 N2 FFT를 행 방향으로 저장하여 N2 x N1 2 차원 배열을 형성합니다.

4. N2 크기의 N1 FFT를 열 방향으로 계산

5. 데이터를 열 방향으로 저장하여 N2 x N1 2 차원 배열 형성

이 알고리즘은 Takahashi가 "Hitachi SR8000 용 고성능 병렬 FFT 알고리즘"에서 자세히 설명합니다. [1] 멀티 코어 구현에서 1 단계는 각 코어에서 N1 크기의 N2 / (코어 수) FFT를 계산하여 수행됩니다. 각 코어에서 N1 / (코어 수) 크기 N2의 FFT를 계산하여 4 단계. 코어 0은 마스터 코어로 사용되며 모든 코어를 동기화하고 나머지 코어는 슬레이브 코어로 사용됩니다. 각 코어에서 N1 및 N2의 크기에 따라 각 코어의 총 FFT 수는 코어 당 L2 SRAM의 크기를 수용하기 위해 여러 개의 작은 블록으로 나뉩니다. 각 데이터 블록은 DMA에 의해 외부 메모리에서 L2 SRAM으로 프리 페치되고 FFT 결과는 DDR에 의해 외부 메모리에 다시 기록됩니다. 각 코어는 2 개의 DMA 채널을 사용하여 외부 메모리 (DDR3)와 내부 메모리 (L2 SRAM)간에 입력 및 출력 샘플을 전송합니다.

2020년 9월 25일 금요일

DSP GPIO Interrupt

Tool 정보 : ccsv9

Board 정보 : EVM C6678 

keystone 인터럽트 관련 참고 사이트 : 

https://processors.wiki.ti.com/index.php/Configuring_Interrupts_on_Keystone_Devices

gpio 관련 문서 : https://www.ti.com/lit/ug/sprugv1/sprugv1.pdf

TEST_PH1(80PIN)



GPIO Memory Map Address : 

Start : 0x02320000  

End : 0x023200FF 

SIZE : 256

GPIO0 ~ GPIO15

인터럽트로 사용 GPIO -> GPIO14, GPIO15

사용 라이브러리 및 Products : 

Products : c667x PDK(2.0.16), SYS/BIOS (6.76.3.01)

라이브러리 : 

C:\ti\pdk_c667x_2_0_16\packages\ti\platform\evmc6678l\platform_lib\lib\debug\ti.platform.evm6678l.lite.lib

C:\ti\pdk_c667x_2_0_16\packages\ti\csl\lib\c6678\c66\release\ti.csl.ae66

C:\ti\pdk_c667x_2_0_16\packages\ti\csl\lib\c6678\c66\release\ti.csl.intc.ae66


시험 설명 

GPIO#13번핀을 인터럽트 신호 발생원으로 사용하고 GPIO#14, #15번을 각각 인터럽트핀으로 사용한다.

GPIO#13은 Clock함수를 이용하여 일정 주기(100msec)마다 인터럽트를 발생하고 발생된 인터럽트는 EventCombiner를 거쳐 Hwi인터럽트 설정 함수를 호출하여 인터럽트 처리를 한다.

인터럽트 처리는 Global변수를 증가하여 인터럽트 발생횟수를 확인한다.


소스코드 위치 

https://github.com/pcw1029/tms320C6678/tree/main/gpioInterrupt


TMS320C6678문서에 따르면 인터럽트 Event Number를 보면 GPIO핀은 GPIO8 ~ GPIO15을 인터럽트 사용할수 있으며, 이벤트번호 82 ~ 89까지 맵핑되어 있다.

(https://www.ti.com/lit/ds/symlink/tms320c6678.pdf 169페이지 참고)

설정(XGCONF)

  • SYS/BIOS -> Scheduling -> Hwi : 
    • Instance로 이동하여 아래 내용 설정
    • ISR Function이름, Interrupt number를 설정한다. 총 2개의 인터럽트를 생성할것이기 때문에 ADD를 눌러 인터럽트 1개를 더 추가하여 설정한다. [(인터럽트 번호는 각각 4,5를 사용할 것이며 인터럽트 0~3 예약되어 있어 사용할수 없다.)( 인터럽트가 발생되었을때 콜백될 함수는 gpio14Interrupt, gpio15Interrupt로 사용한다.)]
    • Event ID 설정 : 이벤트는 88, 89를 사용할 계획이므로 각각 88, 89를 설정한다. 이벤트 번호는 위에 그림에서 확인할수있고 또는 GPIO번호 + 74를 하면된다.

  • SYS/BIOS : Device Support로 이동하여 Event Combiner를 선택한다. 
    • Module : Add the EventCombiner module to my configuration을 체크
    • Event group 2 Hwi 항목에 6으로 설정 (이벤트 그룹 2를 선택한 이유는 event Combiner의 논리적 표현을 보면 124개의 시스템 이벤트가 있고 이를 4개의 그룹으로 나눴다. 즉 [Group#1 : event#04 ~ event#31], [Group#2 : event#32 ~ event#63], [Group#2 : event#64 ~ event#95], [Group#3 : event#96 ~ event#127]이다. Event 88,89가 GPIO인터럽트로 사용할수 있으면 이는 Event Combiner Group#2에 속해있기 때문이다. 
    • Events : Event 88, 89번의 Unmake를 false->true로 변경하고, 실행 함수명을 설정해준다. 함수명은 hwiCombinGpio14Gpio15다.

  • 프로젝트 생성시 ccs project인경우 task가 기본적으로 추가되어있으며 실험에선 사용하지 않으므로 삭제한다. 실험에서는 Clock함수를 생성하여 사용할것이기 때문이다.

  • SYS/BIOS -> Scheduling -> Clock  :  
    • Module  : Add the Clock support module to my configuration 체크
    • Instance :  Add
      • Function : gpio13InterruptOccursEveryCycle
      • Initial timeout : 50
      • Period : 50
      • Start at boot time when instance is created : 체크

보드 연결 상태


결과 화면




2020년 9월 17일 목요일

라즈베리파이4 시리얼 이름지정

  • 시리얼 정보 보기 : 
    • $ sudo udevadm info -q all -a /dev/ttyUSB0 
명령 실행시 아래와 같이 많은 정보들이 출력된다. 시리얼의 이름을 지정하기 위해서는 알아야 하는 정보는 ATTRS {idVendor} == "0403", ATTRS {idProduct} == "6001", ATTRS {serial} == "A6008isP" 가된다.
여기서 시리얼을 구분하는 정보가 ATTRS {serial}이다.

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/ttyUSB0/tty/ttyUSB0':
    KERNEL=="ttyUSB0"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.1/1-1.1:1.0/ttyUSB0':
    KERNELS=="ttyUSB0"
    SUBSYSTEMS=="usb-serial"
    DRIVERS=="ftdi_sio"
    ATTRS{latency_timer}=="16"
    ATTRS{port_number}=="0"

    • 동일한 USB to Serial의 정보(ATTRS {serial})를 보면 아래와 같다.
root@raspberrypi:/proc/tty/driver# udevadm info -q all -a /dev/ttyUSB0 | grep serial
    SUBSYSTEMS=="usb-serial"
    ATTRS{serial}=="A100XD7O"
    ATTRS{serial}=="0000:01:00.0"
root@raspberrypi:/proc/tty/driver# udevadm info -q all -a /dev/ttyUSB1 | grep serial
    SUBSYSTEMS=="usb-serial"
    ATTRS{serial}=="A500YNK3"
    ATTRS{serial}=="0000:01:00.0"
  • UDEV 규칙 만들기
    • /etc/udev/rules.d 폴더에 99-usb-serial.rules 파일을 만들고 아래와 같이 규칙을 입력해준다.
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A100XD7O", SYMLINK+="POSITION"
  • 변경된 이름확인
    • ls -al /dev/POSITION 
lrwxrwxrwx 1 root root 7 Sep 18 02:14 /dev/POSITION -> ttyUSB0

2020년 9월 16일 수요일

라즈베리파이4 설치 유틸

  • SSH : SD카드의 /boot/폴더 밑에 ssh이름의 빈 파일을 생성
  • tftp : sudo apt-get install tftp
  • vim : sudo apt-get install vim
  •  

라즈베리파이4 SD카드 만들기

  • 라즈베리 파이 4에서 SD카드 이미지 생성을 위해 Raspberry Pi Imager 유틸리티를 사용한다.
  • Raspberry Pi Imager 다운로드 : 
    • 윈도우용 https://downloads.raspberrypi.org/imager/imager_1.4.exe
    • 리눅스용 https://downloads.raspberrypi.org/imager/imager_1.4_amd64.deb
  • 이미지 생성후 콘솔을 이용하기 위해 GPIO14, GPIO15핀의 시리얼 연결
    • 라즈베리파이의 시리얼은 3.3v로 동작한다. 시중에 판매하는 USB to Serial를 이용하게 되면 핀이 망가질수 있다.
  • 콘솔을 이용하기 위해서는 생성된 이미지중 boot폴더에 cmdline.txt, config.txt 파일을 수정해야한다. 
    • config.txt 파일에 아래를 추가
      • dtoverlay=disable-bt
      • enable_uart=1
      • boot_delay=2


VITIS Git + Doxygen Config

 Doxygen Configure 1. Vitis 메뉴의 Window->Preference의 C/C++ -> Editor의 Documentation tool comments 기본 설정값을 Doxygen으로 변경 설정 후 함수 바로 위에서 /...