시스템 아키텍처 개요
Xilinx ZYNQ-7000 SoC 기반의 실시간 데이터 수집 장치로, TCP/IP 네트워크를 통해 상위 시스템과 통신하며 고속/저속 이중 채널 데이터 처리를 수행합니다. 주요 특징은 다음과 같습니다:
| 구성 요소 | 사양 |
|---|---|
| 프로세싱 유닛 | ARM Cortex-A9 듀얼 코어 |
| 로직 블록 | 사용자 정의 데이터 수집 IP |
| 데이터 버퍼 | CMA (연속 물리 메모리 할당) |
| 통신 인터페이스 | 100Mbps 이더넷 (TCP) |
소스 코드 구조
src/
├── core/
│ ├── hardware_ctl.c // FPGA 제어 핵심 모듈
│ ├── network_mgr.c // 네트워크 세션 관리
│ └── scheduler.c // 작업 스케줄러
├── protocols/
│ ├── packet_codec.c // 프로토콜 인코딩/디코딩
│ └── msg_types.h // 메시지 구조체 정의
├── dataflow/
│ ├── dma_engine.c // DMA 전송 엔진
│ ├── image_proc.c // 신호 재구성 알고리즘
│ └── buffer_mgr.c // 이중 버퍼 관리
└── utils/
├── config_parser.c // 설정 파일 파서
└── memory_map.c // 물리 메모리 매핑
하드웨어 제어 모듈 심층 분석
FPGA 레지스터 접근 메커니즘
물리 메모리 매핑을 통한 직접 접근 구현:
#define FPGA_CTRL_BASE 0x43C00000
#define DMA_CTRL_BASE 0x43C10000
#define DMA_BLOCK_SIZE (12 * 1024 * 1024) // 12MB 블록
int init_hardware_access() {
int mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (mem_fd < 0) return -1;
// 제어 레지스터 영역 매핑
ctrl_regs = mmap(NULL, 0x1000, PROT_READ|PROT_WRITE,
MAP_SHARED, mem_fd, FPGA_CTRL_BASE);
// DMA 제어 영역 매핑
dma_regs = mmap(NULL, 0x10000, PROT_READ|PROT_WRITE,
MAP_SHARED, mem_fd, DMA_CTRL_BASE);
return (ctrl_regs && dma_regs) ? 0 : -1;
}
신호 조정 알고리즘
가변 이득 증폭기(VGA) 동적 설정 로직:
int configure_signal_gain(float ch0_gain_db, float voltage_mag) {
// PGA 비활성화
write_register(REG_PGA_ENABLE, 0);
// 공통 모드 전압 설정 (1.1V → 16비트 DAC)
uint16_t vcm_val = (uint16_t)(1.1f / 5.0f * 65535);
write_register(REG_VCM_CH0, vcm_val | 0x340000);
// 전압 증폭 계수 설정 (0~10배)
uint16_t vmag_val = (uint16_t)(voltage_mag / 10.0f * 65535);
write_register(REG_VMAG_CH0, vmag_val | 0x320000);
// dB 이득 설정 (-10dB ~ +40dB)
uint16_t db_val = (uint16_t)((ch0_gain_db + 10.0f) / 50.0f * 65535);
write_register(REG_DB_GAIN_CH0, db_val | 0x310000);
// PGA 활성화
write_register(REG_PGA_ENABLE, 1);
return 0;
}
트리거 시스템 구성
void setup_trigger_system(trigger_config_t *config) {
write_register(REG_TRIG_MODE, config->mode);
write_register(REG_TRIG_SOURCE, config->source);
write_register(REG_HS_THRESHOLD, config->high_speed_th);
write_register(REG_LS_THRESHOLD, config->low_speed_th);
write_register(REG_PRE_TRIGGER, config->pre_trigger);
write_register(REG_TOTAL_LENGTH, config->total_samples);
}
이중 버퍼 DMA 전송
#define BUFFER_COUNT 2
static void *dma_buffers[BUFFER_COUNT];
static int active_buffer = 0;
void start_dma_transfer() {
// 활성 버퍼 물리 주소 설정
write_register(REG_DMA_ADDR, get_physical_addr(dma_buffers[active_buffer]));
// 전송 크기 설정 (128바이트 단위)
write_register(REG_DMA_SIZE, DMA_BLOCK_SIZE / 128);
// DMA 엔진 활성화
write_register(REG_DMA_CTRL, DMA_START | DMA_WRITE_ENABLE);
// 트리거 시스템 동기화
enable_trigger_system();
// 다음 버퍼 인덱스 계산
active_buffer = (active_buffer + 1) % BUFFER_COUNT;
}
네트워크 통신 프로토콜
메시지 헤더 구조
| 필드 | 크기 | 설명 |
|---|---|---|
| version | 1바이트 | 프로토콜 버전 (0x01) |
| packet_type | 1바이트 | 메시지 유형 코드 |
| module_id | 1바이트 | 대상 모듈 식별자 |
| flags | 1바이트 | 추가 제어 플래그 |
| payload_len | 4바이트 | 페이로드 길이 (바이트) |
주요 메시지 유형
- 0x01: 시스템 제어 명령 (시작/중지/쿼리)
- 0x02: 하드웨어 구성 파라미터
- 0x03: 실시간 데이터 스트림
- 0x04: 상태 응답 코드
데이터 처리 흐름
- 상위 시스템에서 구성 파라미터 전송 (0x02 패킷)
- 장치에서 VGA/트리거 파라미터 적용
- 데이터 수집 명령 수신 (0x01 패킷)
- FPGA 기반 이중 버퍼 DMA 활성화
- 완료된 버퍼 재구성 알고리즘 처리
- 처리된 데이터를 0x03 패킷으로 전송
핵심 구현 기술
- CMA 메모리 관리: 물리적 연속 메모리 할당을 통해 DMA 전송 효율성 향상
- 이벤트 기반 스케줄링: 네트워크 I/O와 하드웨어 상태 쿼리의 우선순위 기반 처리
- 동적 재구성 알고리즘: 실시간 신호 처리를 위한 최적화된 수학 연산
- 지능형 재연결: 지수 백오프 알고리즘 적용 네트워크 장애 대응