Introduction
만일 Design Guide for MIG IP (1/3)과 Design Guide for MIG IP (2/3)의 내용을 보지 않았다면....
아래의 Design Guide for MIG IP (1/3)과 Design Guide for MIG IP (2/3)을 보고 난 후에
지금 보고 있는 BLOG를 보아 주세요.
여기서는 실제 Data_Gen code ( data_gen.vhd )를 구현하고 앞서 설명한 MIG_CTRL code ( mig_ctrl.vhd )와 연결하여 MIG IP를 통해 DDR memory에 Write한 Data와 Read한 Data가 동일한지를 살펴보겠습니다.
Test를 위한 PC 사용환경은 다음과 같습니다.
- OS : Windows 10 pro ( version : 20H2 )
- Vivado version : 2020.2
Data_Gen code
1.
앞서 블로그에서 언급했던 MIG_CTRL code ( mig_ctrl.vhd )와 연결할 Data_Gen code ( data_gen.vhd )를 설명하겠습니다.
2.
아래 code는 Write Address & Data와 Read Address를 생성하며 앞서 블로그에서 설명하였던 "mig_ctrl.vhd" code의 User Interface Pin과 연결됩니다.
user interface pin과 signal 정의는 다음과 같습니다. |
entity data_gen is port ( state : in std_logic_vector( 3 downto 0) ; write_rdy : in std_logic ; write_en : out std_logic ; write_addr : out std_logic_vector( 27 downto 0) ; write_data : out std_logic_vector(127 downto 0) ; read_rdy : in std_logic ; read_en : out std_logic ; read_addr : out std_logic_vector( 27 downto 0) ; read_valid : in std_logic ; read_data : in std_logic_vector(127 downto 0) ; ui_clk : in std_logic ; reset : in std_logic ); end data_gen; architecture Behavioral of data_gen is constant st_initial : std_logic_vector( 3 downto 0):= "0001" ; constant st_idle : std_logic_vector( 3 downto 0):= "0010" ; constant st_write : std_logic_vector( 3 downto 0):= "0100" ; constant st_read : std_logic_vector( 3 downto 0):= "1000" ; signal write_addr_cnt : std_logic_vector( 27 downto 0) ; -- write address counter signal write_data_cnt : std_logic_vector(127 downto 0) ; -- write data counter signal read_addr_cnt : std_logic_vector( 27 downto 0) ; -- read address counter |
Write Operation을 위하여 사용할 address와 data는 counter를 사용하여 생성합니다. Address는 x"0000000" ~ x"0001000" 까지 증가하는 counter 입니다. (실제 적용되는 address의 max count value는 x"0000ff0" 입니다.) Data는 x"00000000000000000000000000000000" ~ x"00000000000000000000000000001000" 까지 증가하는 counter 입니다. (실제 적용되는 data의 max count value는 x"00000000000000000000000000000ff0" 입니다.) Write 동작의 경우, write_en을 '1'로 놓고 ( write_rdy = '1' )의 조건에서 write_addr와 write_data를 입력하면 됩니다. |
wr_data_addr_gen : process ( ui_clk, reset, state ) begin if ( reset = '1') then write_en <= '0'; write_addr <= x"0000000"; write_data <= x"00000000000000000000000000000000"; elsif ( ui_clk'event and ui_clk = '1' ) then if ( state = st_write ) then if ( write_rdy = '1' ) then if ( write_addr_cnt = x"0001000" ) then write_en <= '0'; write_addr <= x"0001000"; write_addr_cnt <= x"0001000"; write_data <= x"00000000000000000000000000001000"; write_data_cnt <= x"00000000000000000000000000001000"; else write_en <= '1'; write_addr <= write_addr_cnt; write_addr_cnt <= write_addr_cnt + x"0000010"; write_data <= write_data_cnt; write_data_cnt <= write_data_cnt + x"00000000000000000000000000000010"; end if; end if; else write_en <= '0'; write_addr <= x"0000000"; write_addr_cnt <= x"0000000"; write_data <= x"00000000000000000000000000000000"; write_data_cnt <= x"00000000000000000000000000000000"; end if; end if; end process; |
Read Operation을 위하여 사용할 address와 data는 counter를 사용하여 생성합니다. Address는 x"0000000" ~ x"0001000" 까지 증가하는 counter 입니다. (실제 적용되는 address의 max count value는 x"0000ff0" 입니다.) Read 동작의 경우, read_en을 '1'로 놓고 ( read_rdy = '1' )의 조건에서 read_addr를 입력하면 됩니다. |
rd_addr_gen : process ( ui_clk, reset, state ) begin if ( reset = '1') then read_en <= '0'; read_addr <= x"0000000"; read_addr_cnt <= x"0000000"; elsif ( ui_clk'event and ui_clk = '1' ) then if ( state = st_read ) then if ( read_rdy = '1' ) then if ( read_addr_cnt = x"0001000" ) then read_en <= '0'; read_addr <= x"0001000"; read_addr_cnt <= x"0001000"; else read_en <= '1'; read_addr <= read_addr_cnt; read_addr_cnt <= read_addr_cnt + x"0000010"; end if; end if; else read_en <= '0'; read_addr <= x"0000000"; read_addr_cnt <= x"0000000"; end if; end if; end process; |
3.
위 source code를 보면 Write / Read Operation 시에 Address counting이 매 클럭마다 HEX value인 0x10 만큼씩 증가하는 이유에 대하여 설명하겠습니다.
app__wdf_data는 128 bit 입니다.
Write Operation 시에 매 클럭 (ui_clk) 마다 One Address와 128 bits의 data를 MIG IP를 통하여 Write 합니다.
MIG IP와 DDR memory사이의 DQs는 16 bits 입니다.
따라서 Write Operation 시에 매 클럭 (ui_clk) 마다 DQs 16 bits가 8번 Write 됩니다.
DQs 16 bits X 8 = 128 bits
예를 들어 ....
app_addr = "0x0000000" 일 때에 app__wdf_data 128 bits의 data를 MIG IP를 통하여 Write하면
MIG IP와 DDR memory사이에는 다음과 같이 write 됩니다.
( "app_addr"은 28 bits이지만 쉬운 설명을 위하여 하위 8 bits만 표시하겠습니다. )
BIN value인 "0000 0000" ~ "0000 0001" 번지에 app__wdf_data(15:0)가 write 됩니다.
BIN value인 "0000 0010" ~ "0000 0011" 번지에 app__wdf_data(31:16)가 write 됩니다.
BIN value인 "0000 0100" ~ "0000 0101" 번지에 app__wdf_data(47:32)가 write 됩니다.
BIN value인 "0000 0110" ~ "0000 0111" 번지에 app__wdf_data(63:48)가 write 됩니다.
BIN value인 "0000 1000" ~ "0000 1001" 번지에 app__wdf_data(79:64)가 write 됩니다.
BIN value인 "0000 1010" ~ "0000 1011" 번지에 app__wdf_data(95:80)가 write 됩니다.
BIN value인 "0000 1100" ~ "0000 1101" 번지에 app__wdf_data(111:96)가 write 됩니다.
BIN value인 "0000 1110" ~ "0000 1111" 번지에 app__wdf_data(127:112)가 write 됩니다.
따라서 다음 Address는 BIN value인 "0001 0000" (Hex value "0x10")가 되는 것 입니다.
Write Operation 시에 매 클럭 (ui_clk) 마다 HEX value인 0x10 만큼씩 증가 |
write_addr_cnt <= write_addr_cnt + x"0000010"; |
Rrite Operation 시에 매 클럭 (ui_clk) 마다 HEX value인 0x10 만큼씩 증가 |
read_addr_cnt <= read_addr_cnt + x"0000010"; |
지금까지 Design Guide for MIG IP에 대하여 알아보았습니다.
여러분의 FPGA 설계에 조금이라도 도움이 되었으면 합니다.
오늘도 좋은 하루 되세요.
(공감, 구독, 댓글은 저에게 힘이 됩니다!)
Create Date: March 16, 2021
Posted By: Mouessee
Xilinx 본사는 한국 내에 Corporate and Sales Distributor로 MAKUS를 두고 있습니다.
Xilinx 국내 Corporate and Sales Distributor인 MAKUS는 XIlinx FPGA Device를 기술영업을 통해 판매하며 기술지원이 가능합니다.
MAKUS www.makus.co.kr
관련 BLOG
------------------------------
------------------------------
'Xilinx > IPs' 카테고리의 다른 글
How to create Xilinx MIG IP for Custom Part (0) | 2022.06.23 |
---|---|
MIG IP에서 사용되는 3 종류의 Clock에 대하여 (0) | 2022.05.18 |
DisplayPort에 대한 Xilinx Solution (0) | 2022.05.16 |
Design Guide for MIG IP (2/3) (0) | 2022.05.16 |
Design Guide for MIG IP (1/3) (0) | 2022.05.16 |