재밍 시스템은 고주파의 신호를 다룬다. FPGA에서 다룰 드론을 향해 송수신하는 신호 또한 고주파이므로 굉장히 빠르게 동작하는 클럭(약 125MHz)에 맞춰 데이터를 보내야 한다.
=>고속 전송 가능한 동기화 통신인 SPI 통신을 선택하면 시스템에 적합할 것으로 판단했다.
동기화 신호에 맞춰서 데이터를 보낸다. 동기화 신호의 어떤 타이밍에 데이터를 보낼지에 따라 모드가 결정된다.
1) SCLK의 초기값이 0인지 1인지(CPOL)
2) 데이터를 SCLK의 상승에지에 보낼지 하강에지에 보낼지(CPHA)
조합하면 4가지 모드가 나온다.

원리를 이해했으니 직접 FSM 그려서 코드 작성했다. 시뮬레이션 동작하는데 타이밍이 한 클럭씩 어긋났고 무엇보다 level trigger와 edge trigger를 함께 동작하도록 하는 중대한 실수를 하였다. 이렇게 하면 synthesis 안된다.

=> 예제 코드로 공부하고 내 입맛에 맞게 변경하기로 결정하였다.
https://www.youtube.com/watch?v=TR0Pw89EuGk&list=PLsskX2sA20kfSg64biDONnC-unVdoa-sX
https://github.com/nandland/spi-master/blob/master/Verilog/sim/SPI_Master_TB.sv

ADC를 통과한 데이터가 FIFO 메모리에 저장되어 있다가 PC로 내보내는 상황의 통신을 먼저 고려하였다. 즉, 외부에서 들어오는 데이터가 아니라 내부에 저장되어 있던 데이터를 MOSI를 통해 내보내는 상황을 가정했다.
입력 데이터인 i_TX_Byte 대신에 임의의 내부에서 준 test값(10010010)을 넣고 이 데이터가 SCLK에 맞게 MOSI 출력으로 나오는지 확인했다.
module SPI_Master
#(parameter SPI_MODE = 3,
parameter CLKS_PER_HALF_BIT = 4) //SPI Clock 주기의 반에 i_clk이 얼마나 들어가냐
(
// Control/Data Signals,
input i_Rst_L, // FPGA Reset //reset 신호
input i_Clk, // FPGA Clock -fpga reference clock 말하는듯
// TX (MOSI) Signals
input [7:0] i_TX_Byte, // Byte to transmit on MOSI -MOSI핀으로 전송할 8비트 데이터
input i_TX_DV, // Data Valid Pulse with i_TX_Byte -데이터 다 보냈다고 보내는 펄스인듯
output reg o_TX_Ready, // Transmit Ready for next byte -다음 바이트를 보낼 준비가 되었다(바이트를 비트로 바꾸기 위해서 필요?)
//MISO 안쓰니까 필요 없을듯
// RX (MISO) Signals
output reg o_RX_DV, // Data Valid pulse (1 clock cycle)
//output reg [7:0] o_RX_Byte, // Byte received on MISO
// SPI Interface
output reg o_SPI_Clk, //SCK 만들어주기 위한거인듯
input i_SPI_MISO,
output reg o_SPI_MOSI //이게 내가 필요한 핀일듯-slave로 전달하기 위한 핀
);
// SPI Interface (All Runs at SPI Clock Domain)
wire w_CPOL; // Clock polarity
wire w_CPHA; // Clock phase
reg [$clog2(CLKS_PER_HALF_BIT*2)-1:0] r_SPI_Clk_Count;
reg r_SPI_Clk;
reg [4:0] r_SPI_Clk_Edges;
reg r_Leading_Edge;
reg r_Trailing_Edge;
reg r_TX_DV;
reg [7:0] r_TX_Byte;
reg [2:0] r_RX_Bit_Count;
reg [2:0] r_TX_Bit_Count;
// CPOL: Clock Polarity
// CPOL=0 means clock idles at 0, leading edge is rising edge.
// CPOL=1 means clock idles at 1, leading edge is falling edge.
assign w_CPOL = (SPI_MODE == 2) | (SPI_MODE == 3);
// CPHA: Clock Phase
// CPHA=0 means the "out" side changes the data on trailing edge of clock
// the "in" side captures data on leading edge of clock
// CPHA=1 means the "out" side changes the data on leading edge of clock
// the "in" side captures data on the trailing edge of clock
assign w_CPHA = (SPI_MODE == 1) | (SPI_MODE == 3);
// Purpose: Generate SPI Clock correct number of times when DV pulse comes
//내가 원하는 SPI_clk(SCK) 만들어주는 부분
always @(posedge i_Clk or negedge i_Rst_L)
begin
if (~i_Rst_L) //active-low로 동작하는 reset
begin //초기
o_TX_Ready <= 1'b0;
r_SPI_Clk_Edges <= 0;
r_Leading_Edge <= 1'b0;
r_Trailing_Edge <= 1'b0;
r_SPI_Clk <= w_CPOL; // assign default state to idle state, w_CPOL 0이면 clk값 0부터 시작, 1이면 clk값 1부터 시작
r_SPI_Clk_Count <= 0;
end
else
begin
// Default assignments
r_Leading_Edge <= 1'b0;
r_Trailing_Edge <= 1'b0;
if (i_TX_DV)
begin
o_TX_Ready <= 1'b0;
r_SPI_Clk_Edges <= 16; // Total # edges in one byte ALWAYS 16
end
//
else if (r_SPI_Clk_Edges > 0)
begin
o_TX_Ready <= 1'b0;
if (r_SPI_Clk_Count == CLKS_PER_HALF_BIT*2-1) //r_SPI_Clk_count==7(시뮬레이션에서 4로해놔서)
begin
r_SPI_Clk_Edges <= r_SPI_Clk_Edges - 1'b1;
r_Trailing_Edge <= 1'b1; //trailing: 하강
r_SPI_Clk_Count <= 0;
r_SPI_Clk <= ~r_SPI_Clk;
end
else if (r_SPI_Clk_Count == CLKS_PER_HALF_BIT-1) //3
begin
r_SPI_Clk_Edges <= r_SPI_Clk_Edges - 1'b1;
r_Leading_Edge <= 1'b1; //leading: 상승
r_SPI_Clk_Count <= r_SPI_Clk_Count + 1'b1;
r_SPI_Clk <= ~r_SPI_Clk;
end
else
begin
r_SPI_Clk_Count <= r_SPI_Clk_Count + 1'b1;
end
end
//
else
begin
o_TX_Ready <= 1'b1;
end
end // else: !if(~i_Rst_L)
end // always @ (posedge i_Clk or negedge i_Rst_L)
//여기까지 내가 원하는 SCK 생성 파트
// Purpose: Register i_TX_Byte when Data Valid is pulsed.
// Keeps local storage of byte in case higher level module changes the data
always @(posedge i_Clk or negedge i_Rst_L)
begin
if (~i_Rst_L)
begin
r_TX_Byte <= 8'h00;
r_TX_DV <= 1'b0;
end
else
begin
r_TX_DV <= i_TX_DV; // 1 clock cycle delay
if (i_TX_DV)
begin
r_TX_Byte <= 8'b10010010;
end
end // else: !if(~i_Rst_L)
end // always @ (posedge i_Clk or negedge i_Rst_L)
// Purpose: Generate MOSI data
// Works with both CPHA=0 and CPHA=1
always @(posedge i_Clk or negedge i_Rst_L)
begin
if (~i_Rst_L)
begin
o_SPI_MOSI <= 1'b0;
r_TX_Bit_Count <= 3'b111; // send MSb first
end
else
begin
// If ready is high, reset bit counts to default
if (o_TX_Ready)
begin
r_TX_Bit_Count <= 3'b111; //8비트니까
end
// Catch the case where we start transaction and CPHA = 0
else if (r_TX_DV & ~w_CPHA)
begin
o_SPI_MOSI <= r_TX_Byte[3'b111]; //MSB 전송
r_TX_Bit_Count <= 3'b110;
end
else if ((r_Leading_Edge & w_CPHA) | (r_Trailing_Edge & ~w_CPHA)) //시뮬레이션에서 모드 3으로 해서 CPHA 계속 1임
//CPHA 1일때는 상승에지일 때, CPHA 0일 때는 하강에지일 때 (CPOL 1일때로 가정하는건가?)
//1비트씩 수신
begin
r_TX_Bit_Count <= r_TX_Bit_Count - 1'b1;
o_SPI_MOSI <= r_TX_Byte[r_TX_Bit_Count]; //나머지 7비트 전송
end
end
end
/*
// Purpose: Read in MISO data.
always @(posedge i_Clk or negedge i_Rst_L)
begin
if (~i_Rst_L)
begin
o_RX_Byte <= 8'h00;
o_RX_DV <= 1'b0;
r_RX_Bit_Count <= 3'b111;
end
else
begin
// Default Assignments
o_RX_DV <= 1'b0;
if (o_TX_Ready) // Check if ready is high, if so reset bit count to default
begin
r_RX_Bit_Count <= 3'b111;
end
else if ((r_Leading_Edge & ~w_CPHA) | (r_Trailing_Edge & w_CPHA))
begin
o_RX_Byte[r_RX_Bit_Count] <= i_SPI_MISO; // Sample data
r_RX_Bit_Count <= r_RX_Bit_Count - 1'b1;
if (r_RX_Bit_Count == 3'b000)
begin
o_RX_DV <= 1'b1; // Byte done, pulse Data Valid
end
end
end
end
*/
// Purpose: Add clock delay to signals for alignment.
always @(posedge i_Clk or negedge i_Rst_L)
begin
if (~i_Rst_L)
begin
o_SPI_Clk <= w_CPOL;
end
else
begin
o_SPI_Clk <= r_SPI_Clk;
end // else: !if(~i_Rst_L)
end // always @ (posedge i_Clk or negedge i_Rst_L)
endmodule // SPI_Master
## This file is a general .xdc for the Zybo Z7 Rev. B
## It is compatible with the Zybo Z7-20 and Zybo Z7-10
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project
##Clock signal
set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports {i_Clk}]; #IO_L12P_T1_MRCC_35 Sch=sysclk
create_clock -add -name sys_clk_pin -period 80 -waveform {0 40} [get_ports { i_Clk }];
##Switches
set_property -dict { PACKAGE_PIN G15 IOSTANDARD LVCMOS33 } [get_ports { i_Rst_L }]; #IO_L19N_T3_VREF_35 Sch=sw[0]
#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L24P_T3_34 Sch=sw[1]
#set_property -dict { PACKAGE_PIN W13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L4N_T0_34 Sch=sw[2]
#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L9P_T1_DQS_34 Sch=sw[3]
##Buttons
set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { i_TX_DV }]; #IO_L12N_T1_MRCC_35 Sch=btn[0]
#set_property -dict { PACKAGE_PIN P16 IOSTANDARD LVCMOS33 } [get_ports { btn[1] }]; #IO_L24N_T3_34 Sch=btn[1]
#set_property -dict { PACKAGE_PIN K19 IOSTANDARD LVCMOS33 } [get_ports { btn[2] }]; #IO_L10P_T1_AD11P_35 Sch=btn[2]
#set_property -dict { PACKAGE_PIN Y16 IOSTANDARD LVCMOS33 } [get_ports { btn[3] }]; #IO_L7P_T1_34 Sch=btn[3]
##LEDs
#set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { test_LED }]; #IO_L23P_T3_35 Sch=led[0]
#set_property -dict { PACKAGE_PIN M15 IOSTANDARD LVCMOS33 } [get_ports { led[1] }]; #IO_L23N_T3_35 Sch=led[1]
#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { led[2] }]; #IO_0_35 Sch=led[2]
#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { test_LED }]; #IO_L3N_T0_DQS_AD1N_35 Sch=led[3]
##RGB LED 5 (Zybo Z7-20 only)
#set_property -dict { PACKAGE_PIN Y11 IOSTANDARD LVCMOS33 } [get_ports { led5_r }]; #IO_L18N_T2_13 Sch=led5_r
#set_property -dict { PACKAGE_PIN T5 IOSTANDARD LVCMOS33 } [get_ports { led5_g }]; #IO_L19P_T3_13 Sch=led5_g
#set_property -dict { PACKAGE_PIN Y12 IOSTANDARD LVCMOS33 } [get_ports { led5_b }]; #IO_L20P_T3_13 Sch=led5_b
##RGB LED 6
#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led6_r }]; #IO_L18P_T2_34 Sch=led6_r
#set_property -dict { PACKAGE_PIN F17 IOSTANDARD LVCMOS33 } [get_ports { led6_g }]; #IO_L6N_T0_VREF_35 Sch=led6_g
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { led6_b }]; #IO_L8P_T1_AD10P_35 Sch=led6_b
##Audio Codec
#set_property -dict { PACKAGE_PIN R19 IOSTANDARD LVCMOS33 } [get_ports { ac_bclk }]; #IO_0_34 Sch=ac_bclk
#set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { ac_mclk }]; #IO_L19N_T3_VREF_34 Sch=ac_mclk
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { ac_muten }]; #IO_L23N_T3_34 Sch=ac_muten
#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { ac_pbdat }]; #IO_L20N_T3_34 Sch=ac_pbdat
#set_property -dict { PACKAGE_PIN T19 IOSTANDARD LVCMOS33 } [get_ports { ac_pblrc }]; #IO_25_34 Sch=ac_pblrc
#set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { ac_recdat }]; #IO_L19P_T3_34 Sch=ac_recdat
#set_property -dict { PACKAGE_PIN Y18 IOSTANDARD LVCMOS33 } [get_ports { ac_reclrc }]; #IO_L17P_T2_34 Sch=ac_reclrc
#set_property -dict { PACKAGE_PIN N18 IOSTANDARD LVCMOS33 } [get_ports { ac_scl }]; #IO_L13P_T2_MRCC_34 Sch=ac_scl
#set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { ac_sda }]; #IO_L23P_T3_34 Sch=ac_sda
##Additional Ethernet signals
#set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 PULLUP true } [get_ports { eth_int_pu_b }]; #IO_L6P_T0_35 Sch=eth_int_pu_b
#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { eth_rst_b }]; #IO_L3P_T0_DQS_AD1P_35 Sch=eth_rst_b
##USB-OTG over-current detect pin
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { otg_oc }]; #IO_L3P_T0_DQS_PUDC_B_34 Sch=otg_oc
##Fan (Zybo Z7-20 only)
#set_property -dict { PACKAGE_PIN Y13 IOSTANDARD LVCMOS33 PULLUP true } [get_ports { fan_fb_pu }]; #IO_L20N_T3_13 Sch=fan_fb_pu
##HDMI RX
#set_property -dict { PACKAGE_PIN W19 IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_hpd }]; #IO_L22N_T3_34 Sch=hdmi_rx_hpd
#set_property -dict { PACKAGE_PIN W18 IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_scl }]; #IO_L22P_T3_34 Sch=hdmi_rx_scl
#set_property -dict { PACKAGE_PIN Y19 IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_sda }]; #IO_L17N_T2_34 Sch=hdmi_rx_sda
#set_property -dict { PACKAGE_PIN U19 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_clk_n }]; #IO_L12N_T1_MRCC_34 Sch=hdmi_rx_clk_n
#set_property -dict { PACKAGE_PIN U18 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_clk_p }]; #IO_L12P_T1_MRCC_34 Sch=hdmi_rx_clk_p
#set_property -dict { PACKAGE_PIN W20 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_n[0] }]; #IO_L16N_T2_34 Sch=hdmi_rx_n[0]
#set_property -dict { PACKAGE_PIN V20 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_p[0] }]; #IO_L16P_T2_34 Sch=hdmi_rx_p[0]
#set_property -dict { PACKAGE_PIN U20 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_n[1] }]; #IO_L15N_T2_DQS_34 Sch=hdmi_rx_n[1]
#set_property -dict { PACKAGE_PIN T20 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_p[1] }]; #IO_L15P_T2_DQS_34 Sch=hdmi_rx_p[1]
#set_property -dict { PACKAGE_PIN P20 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_n[2] }]; #IO_L14N_T2_SRCC_34 Sch=hdmi_rx_n[2]
#set_property -dict { PACKAGE_PIN N20 IOSTANDARD TMDS_33 } [get_ports { hdmi_rx_p[2] }]; #IO_L14P_T2_SRCC_34 Sch=hdmi_rx_p[2]
##HDMI RX CEC (Zybo Z7-20 only)
#set_property -dict { PACKAGE_PIN Y8 IOSTANDARD LVCMOS33 } [get_ports { hdmi_rx_cec }]; #IO_L14N_T2_SRCC_13 Sch=hdmi_rx_cec
##HDMI TX
#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_hpd }]; #IO_L5P_T0_AD9P_35 Sch=hdmi_tx_hpd
#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_scl }]; #IO_L16P_T2_35 Sch=hdmi_tx_scl
#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_sda }]; #IO_L16N_T2_35 Sch=hdmi_tx_sda
#set_property -dict { PACKAGE_PIN H17 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_clk_n }]; #IO_L13N_T2_MRCC_35 Sch=hdmi_tx_clk_n
#set_property -dict { PACKAGE_PIN H16 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_clk_p }]; #IO_L13P_T2_MRCC_35 Sch=hdmi_tx_clk_p
#set_property -dict { PACKAGE_PIN D20 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_n[0] }]; #IO_L4N_T0_35 Sch=hdmi_tx_n[0]
#set_property -dict { PACKAGE_PIN D19 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_p[0] }]; #IO_L4P_T0_35 Sch=hdmi_tx_p[0]
#set_property -dict { PACKAGE_PIN B20 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_n[1] }]; #IO_L1N_T0_AD0N_35 Sch=hdmi_tx_n[1]
#set_property -dict { PACKAGE_PIN C20 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_p[1] }]; #IO_L1P_T0_AD0P_35 Sch=hdmi_tx_p[1]
#set_property -dict { PACKAGE_PIN A20 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_n[2] }]; #IO_L2N_T0_AD8N_35 Sch=hdmi_tx_n[2]
#set_property -dict { PACKAGE_PIN B19 IOSTANDARD TMDS_33 } [get_ports { hdmi_tx_p[2] }]; #IO_L2P_T0_AD8P_35 Sch=hdmi_tx_p[2]
##HDMI TX CEC
#set_property -dict { PACKAGE_PIN E19 IOSTANDARD LVCMOS33 } [get_ports { hdmi_tx_cec }]; #IO_L5N_T0_AD9N_35 Sch=hdmi_tx_cec
##Pmod Header JA (XADC)
#set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { ja[0] }]; #IO_L21P_T3_DQS_AD14P_35 Sch=JA1_R_p
#set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { ja[1] }]; #IO_L22P_T3_AD7P_35 Sch=JA2_R_P
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { ja[2] }]; #IO_L24P_T3_AD15P_35 Sch=JA3_R_P
#set_property -dict { PACKAGE_PIN K14 IOSTANDARD LVCMOS33 } [get_ports { ja[3] }]; #IO_L20P_T3_AD6P_35 Sch=JA4_R_P
#set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { ja[4] }]; #IO_L21N_T3_DQS_AD14N_35 Sch=JA1_R_N
#set_property -dict { PACKAGE_PIN L15 IOSTANDARD LVCMOS33 } [get_ports { ja[5] }]; #IO_L22N_T3_AD7N_35 Sch=JA2_R_N
#set_property -dict { PACKAGE_PIN J16 IOSTANDARD LVCMOS33 } [get_ports { ja[6] }]; #IO_L24N_T3_AD15N_35 Sch=JA3_R_N
#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { ja[7] }]; #IO_L20N_T3_AD6N_35 Sch=JA4_R_N
##Pmod Header JB (Zybo Z7-20 only)
#set_property -dict { PACKAGE_PIN V8 IOSTANDARD LVCMOS33 } [get_ports { jb[0] }]; #IO_L15P_T2_DQS_13 Sch=jb_p[1]
#set_property -dict { PACKAGE_PIN W8 IOSTANDARD LVCMOS33 } [get_ports { jb[1] }]; #IO_L15N_T2_DQS_13 Sch=jb_n[1]
#set_property -dict { PACKAGE_PIN U7 IOSTANDARD LVCMOS33 } [get_ports { jb[2] }]; #IO_L11P_T1_SRCC_13 Sch=jb_p[2]
#set_property -dict { PACKAGE_PIN V7 IOSTANDARD LVCMOS33 } [get_ports { jb[3] }]; #IO_L11N_T1_SRCC_13 Sch=jb_n[2]
#set_property -dict { PACKAGE_PIN Y7 IOSTANDARD LVCMOS33 } [get_ports { jb[4] }]; #IO_L13P_T2_MRCC_13 Sch=jb_p[3]
#set_property -dict { PACKAGE_PIN Y6 IOSTANDARD LVCMOS33 } [get_ports { jb[5] }]; #IO_L13N_T2_MRCC_13 Sch=jb_n[3]
#set_property -dict { PACKAGE_PIN V6 IOSTANDARD LVCMOS33 } [get_ports { jb[6] }]; #IO_L22P_T3_13 Sch=jb_p[4]
#set_property -dict { PACKAGE_PIN W6 IOSTANDARD LVCMOS33 } [get_ports { jb[7] }]; #IO_L22N_T3_13 Sch=jb_n[4]
##Pmod Header JC
#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { jc[0] }]; #IO_L10P_T1_34 Sch=jc_p[1]
#set_property -dict { PACKAGE_PIN W15 IOSTANDARD LVCMOS33 } [get_ports { jc[1] }]; #IO_L10N_T1_34 Sch=jc_n[1]
#set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { jc[2] }]; #IO_L1P_T0_34 Sch=jc_p[2]
#set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { jc[3] }]; #IO_L1N_T0_34 Sch=jc_n[2]
#set_property -dict { PACKAGE_PIN W14 IOSTANDARD LVCMOS33 } [get_ports { jc[4] }]; #IO_L8P_T1_34 Sch=jc_p[3]
#set_property -dict { PACKAGE_PIN Y14 IOSTANDARD LVCMOS33 } [get_ports { jc[5] }]; #IO_L8N_T1_34 Sch=jc_n[3]
#set_property -dict { PACKAGE_PIN T12 IOSTANDARD LVCMOS33 } [get_ports { jc[6] }]; #IO_L2P_T0_34 Sch=jc_p[4]
#set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { jc[7] }]; #IO_L2N_T0_34 Sch=jc_n[4]
##Pmod Header JD
#set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { o_SPI_MOSI }]; #IO_L5P_T0_34 Sch=jd_p[1]
#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { i_SPI_MISO }]; #IO_L5N_T0_34 Sch=jd_n[1]
#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { o_SPI_Clk }]; #IO_L6P_T0_34 Sch=jd_p[2]
#set_property -dict { PACKAGE_PIN R14 IOSTANDARD LVCMOS33 } [get_ports { o_RX_DV}]; #IO_L6N_T0_VREF_34 Sch=jd_n[2]
#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { o_TX_Ready }]; #IO_L11P_T1_SRCC_34 Sch=jd_p[3]
#set_property -dict { PACKAGE_PIN U15 IOSTANDARD LVCMOS33 } [get_ports { i_Clk }]; #IO_L11N_T1_SRCC_34 Sch=jd_n[3]
#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { jd[6] }]; #IO_L21P_T3_DQS_34 Sch=jd_p[4]
#set_property -dict { PACKAGE_PIN V18 IOSTANDARD LVCMOS33 } [get_ports { jd[7] }]; #IO_L21N_T3_DQS_34 Sch=jd_n[4]
##Pmod Header JE
set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { o_SPI_MOSI }]; #IO_L4P_T0_34 Sch=je[1]
set_property -dict { PACKAGE_PIN W16 IOSTANDARD LVCMOS33 } [get_ports { i_SPI_MISO }]; #IO_L18N_T2_34 Sch=je[2]
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { o_SPI_Clk }]; #IO_25_35 Sch=je[3]
set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { o_RX_DV }]; #IO_L19P_T3_35 Sch=je[4]
set_property -dict { PACKAGE_PIN V13 IOSTANDARD LVCMOS33 } [get_ports { o_TX_Ready}]; #IO_L3N_T0_DQS_34 Sch=je[7]
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports {need_clk }]; #IO_L9N_T1_DQS_34 Sch=je[8]
#set_property -dict { PACKAGE_PIN T17 IOSTANDARD LVCMOS33 } [get_ports { je[6] }]; #IO_L20P_T3_34 Sch=je[9]
#set_property -dict { PACKAGE_PIN Y17 IOSTANDARD LVCMOS33 } [get_ports { je[7] }]; #IO_L7N_T1_34 Sch=je[10]
##Pcam MIPI CSI-2 Connector
## This configuration expects the sensor to use 672Mbps/lane = 336 MHz HS_Clk
#create_clock -period 2.976 -name dphy_hs_clock_clk_p -waveform {0.000 1.488} [get_ports dphy_hs_clock_clk_p]
#set_property INTERNAL_VREF 0.6 [get_iobanks 35]
#set_property -dict { PACKAGE_PIN J19 IOSTANDARD HSUL_12 } [get_ports { dphy_clk_lp_n }]; #IO_L10N_T1_AD11N_35 Sch=lp_clk_n
#set_property -dict { PACKAGE_PIN H20 IOSTANDARD HSUL_12 } [get_ports { dphy_clk_lp_p }]; #IO_L17N_T2_AD5N_35 Sch=lp_clk_p
#set_property -dict { PACKAGE_PIN M18 IOSTANDARD HSUL_12 } [get_ports { dphy_data_lp_n[0] }]; #IO_L8N_T1_AD10N_35 Sch=lp_lane_n[0]
#set_property -dict { PACKAGE_PIN L19 IOSTANDARD HSUL_12 } [get_ports { dphy_data_lp_p[0] }]; #IO_L9P_T1_DQS_AD3P_35 Sch=lp_lane_p[0]
#set_property -dict { PACKAGE_PIN L20 IOSTANDARD HSUL_12 } [get_ports { dphy_data_lp_n[1] }]; #IO_L9N_T1_DQS_AD3N_35 Sch=lp_lane_n[1]
#set_property -dict { PACKAGE_PIN J20 IOSTANDARD HSUL_12 } [get_ports { dphy_data_lp_p[1] }]; #IO_L17P_T2_AD5P_35 Sch=lp_lane_p[1]
#set_property -dict { PACKAGE_PIN H18 IOSTANDARD LVDS_25 } [get_ports { dphy_hs_clock_clk_n }]; #IO_L14N_T2_AD4N_SRCC_35 Sch=mipi_clk_n
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVDS_25 } [get_ports { dphy_hs_clock_clk_p }]; #IO_L14P_T2_AD4P_SRCC_35 Sch=mipi_clk_p
#set_property -dict { PACKAGE_PIN M20 IOSTANDARD LVDS_25 } [get_ports { dphy_data_hs_n[0] }]; #IO_L7N_T1_AD2N_35 Sch=mipi_lane_n[0]
#set_property -dict { PACKAGE_PIN M19 IOSTANDARD LVDS_25 } [get_ports { dphy_data_hs_p[0] }]; #IO_L7P_T1_AD2P_35 Sch=mipi_lane_p[0]
#set_property -dict { PACKAGE_PIN L17 IOSTANDARD LVDS_25 } [get_ports { dphy_data_hs_n[1] }]; #IO_L11N_T1_SRCC_35 Sch=mipi_lane_n[1]
#set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVDS_25 } [get_ports { dphy_data_hs_p[1] }]; #IO_L11P_T1_SRCC_35 Sch=mipi_lane_p[1]
#set_property -dict { PACKAGE_PIN G19 IOSTANDARD LVCMOS33 } [get_ports { cam_clk }]; #IO_L18P_T2_AD13P_35 Sch=cam_clk
#set_property -dict { PACKAGE_PIN G20 IOSTANDARD LVCMOS33 PULLUP true} [get_ports { cam_gpio }]; #IO_L18N_T2_AD13N_35 Sch=cam_gpio
#set_property -dict { PACKAGE_PIN F20 IOSTANDARD LVCMOS33 } [get_ports { cam_scl }]; #IO_L15N_T2_DQS_AD12N_35 Sch=cam_scl
#set_property -dict { PACKAGE_PIN F19 IOSTANDARD LVCMOS33 } [get_ports { cam_sda }]; #IO_L15P_T2_DQS_AD12P_35 Sch=cam_sda
##Unloaded Crypto Chip SWI (for future use)
#set_property -dict { PACKAGE_PIN P19 IOSTANDARD LVCMOS33 } [get_ports { crypto_sda }]; #IO_L13N_T2_MRCC_34 Sch=crypto_sda
##Unconnected Pins (Zybo Z7-20 only)
#set_property PACKAGE_PIN T9 [get_ports {netic19_t9}]; #IO_L12P_T1_MRCC_13
#set_property PACKAGE_PIN U10 [get_ports {netic19_u10}]; #IO_L12N_T1_MRCC_13
#set_property PACKAGE_PIN U5 [get_ports {netic19_u5}]; #IO_L19N_T3_VREF_13
#set_property PACKAGE_PIN U8 [get_ports {netic19_u8}]; #IO_L17N_T2_13
#set_property PACKAGE_PIN U9 [get_ports {netic19_u9}]; #IO_L17P_T2_13
#set_property PACKAGE_PIN V10 [get_ports {netic19_v10}]; #IO_L21N_T3_DQS_13
#set_property PACKAGE_PIN V11 [get_ports {netic19_v11}]; #IO_L21P_T3_DQS_13
#set_property PACKAGE_PIN V5 [get_ports {netic19_v5}]; #IO_L6N_T0_VREF_13
#set_property PACKAGE_PIN W10 [get_ports {netic19_w10}]; #IO_L16P_T2_13
#set_property PACKAGE_PIN W11 [get_ports {netic19_w11}]; #IO_L18P_T2_13
#set_property PACKAGE_PIN W9 [get_ports {netic19_w9}]; #IO_L16N_T2_13
#set_property PACKAGE_PIN Y9 [get_ports {netic19_y9}]; #IO_L14P_T2_SRCC_13

SCLK의 하강에지마다 1비트씩 출력되는 것을 확인할 수 있다.
(영상은 구글 드라이브 참고)
1️⃣ reference clock을 80ns로 했고, CLKS_PER_HALF_BIT값이 4기 때문에 SCLK 주기가 640ns가 나와야 하는데 60ns밖에 안 나온다.
2️⃣ 노이즈가 왜 저렇게 끼는지 모르겠다.
일단 파형이 나오는 기준으로 1s를 맞추기 위해서 CLKS_PER_HALF_BIT 값을 67108864로 늘렸다.

1초마다 1비트씩 출력된다. 실제론 이렇게 큰 주기를 안 쓸건데 PC상에 잘 출력되는지 보려고 1초 단위로 확인해봤다.
나는 SPI 통신을 구현했더라도 ISP 케이블 연결해서 Putty로 확인하면 될 줄 알았는데 아무런 출력값이 안 나온다. 일단 Putty가 UART만 지원한다고 하고 지피티 말로는 추가적인 HW 케이블이나 SW 툴이 필요하다는데.. 생각을 좀 해봐야 할 것 같다.
1️⃣ 만약 PC로 넘길 때 말고 FMCW에서 RF단과 수신할 때도 SPI 통신이 필요하다면 MISO도 사용해야 한다.
2️⃣ FIFO 메모리에 있던 데이터를 PC로 넘겨줘야 하는데 이거를 바이트 단위로 잘라서 넣어야 하는데 어떻게 구현해야 할지 고민. <- FIFO 메모리를 구현해야 좀 더 명확해질 듯하다.