레이블이 NIOS인 게시물을 표시합니다. 모든 게시물 표시
레이블이 NIOS인 게시물을 표시합니다. 모든 게시물 표시

2014/03/20

Nios II 시작해보자-5(PIO Interrupt)

이번엔 PIO 인터럽트를 사용해보자.

유저 인터페이스로 12분할 엔코더와 스위치를 달아놨는데 함 써먹어 봐야겠어.


엔코더는 A, B signal 외에 스위치 시그널도 있다. 푸쉬타입을 샀거등...

그 외 버튼이 두개가 있고 이걸 interface_Logic에 연결해서 입력신호 필터링을 한 후

인터럽트 신호와 무슨 신호인지 알려주는 데이터 신호가 출력된다.


library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity Interface_Logic_v001 is
port
(
clk_in : in std_logic;
EN0_S : in std_logic;
EN0_A, EN0_B : in std_logic;
Key_01, Key_02 : in std_logic;

data : out std_logic_vector(2 downto 0);
intr : out std_logic
);
end entity;

architecture rtl of Interface_Logic_v001 is
signal data_signal : std_logic_vector(2 downto 0);
signal ff_EN0_A, ff_EN0_S, ff_Key_01, ff_Key_02 : std_logic_vector(1 downto 0);
signal rotary_in : std_logic_vector(1 downto 0);
signal rotary_q1, rotary_q2 : std_logic;
begin
process(clk_in)
variable clk_cnt_ENR, clk_cnt_ENL, clk_cnt : integer := 0;
variable phase : integer := 0;
begin
if(clk_in 'event and clk_in = '1') then
if(phase = 0) then
ff_EN0_A(0) <= rotary_q1;
ff_EN0_A(1) <= ff_EN0_A(0);

ff_EN0_S(0) <= EN0_S;
ff_EN0_S(1) <= ff_EN0_S(0);

ff_Key_01(0) <= Key_01;
ff_Key_01(1) <= ff_Key_01(0);

ff_Key_02(0) <= Key_02;
ff_Key_02(1) <= ff_Key_02(0);

if(ff_EN0_A(1) = '0' and ff_EN0_A(0) = '1') then
if(rotary_q2 = '0') then
data <= "000";
else
data <= "001";
end if;
phase := 1;
end if;
elsif(phase = 1) then
intr <= '1';
clk_cnt := clk_cnt + 1;
if(clk_cnt = 100) then
clk_cnt := 0;
intr <= '0';
phase := 0;
end if;
end if;
end if;
end process;

process(clk_in)
begin
if(clk_in 'event and clk_in = '1') then
rotary_in <= (not EN0_B) & (not EN0_A);

case rotary_in is
when "00" => rotary_q1 <= '0';
rotary_q2 <= rotary_q2;
when "01" => rotary_q1 <= rotary_q1;
rotary_q2 <= '0';
when "10" => rotary_q1 <= rotary_q1;
rotary_q2 <= '1';
when "11" => rotary_q1 <= '1';
rotary_q2 <= rotary_q2;
when others => rotary_q1 <= rotary_q1;
rotary_q2 <= rotary_q2;
end case;
end if;
end process;
end rtl;

인터페이스 로직은 일단 이렇다. 엔코더만 구현해 놓은 상태...
Syntax Highlighting을 어떻게 하는지 몰라서 보기 좀 불편하네.

엔코더를 오른쪽으로 돌리면 data 핀으로 "000"가 출력되고, 왼쪽으로 돌리면 "001"이 출력된다. 그리고 인터럽트 핀에서 한 펄스 날라간다. Nios II 에서는 이 인터럽트 시그널을 받아서 인터럽트 처리를 해주면 된다는 시나리온데...잘 되려나...

Qsys 띄워서 시작해보자.






















현재 내 시스템은 이렇다. 인터럽트 입력용으로 사용할 PIO 하나 추가해보자.































이런식으로 설정했다. Rising Edge에 인터럽트가 발생하는 설정이라고 한건데...해봐야 알지 머






















추가했다. 저장하고 제너레이션 해보자.

하드웨어 설정하고 만드는건 별 문제가 없는데...
정작 C 프로그래밍은 어떻게 해야되는지 간단명료하게 설명된 문서를 찾기가 너무 힘드네...

결국 Nios II Software Developer's Handbook에서 PIO Interrupt 관련 예제를 찾았다.
인터넷 뒤진다고 눈깔 빠지는줄 알았다.

우선 ISR 함수 만들고, PIO 인터럽트로 등록해주는 소스다.

#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
static void handle_button_interrupts(void* context)
#else
static void handle_button_interrupts(void* context, alt_u32 id)
#endif
{
/* Cast context to edge_capture's type. It is important that this
be declared volatile to avoid unwanted compiler optimization. */
volatile int* edge_capture_ptr = (volatile int*) context;
/*
* Read the edge capture register on the button PIO.
* Store value.
*/
*edge_capture_ptr =
IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE);
/* Write to the edge capture register to reset it. */
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0);
/* Read the PIO to delay ISR exit. This is done to prevent a
spurious interrupt in systems with high processor -> pio
latency and fast interrupts. */
IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE);
}


#include "sys/alt_irq.h"
#include "system.h"
...
/* Declare a global variable to hold the edge capture value. */
volatile int edge_capture;
...
/* Initialize the button_pio. */
static void init_button_pio()
{
/* Recast the edge_capture pointer to match the
alt_irq_register() function prototype. */
void* edge_capture_ptr = (void*) &edge_capture;
/* Enable all 4 button interrupts. */
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE, 0xf);
/* Reset the edge capture register. */
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0x0);
/* Register the ISR. */
#ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT
alt_ic_isr_register(BUTTON_PIO_IRQ_INTERRUPT_CONTROLLER_ID,
BUTTON_PIO_IRQ,
handle_button_interrupts,
edge_capture_ptr, 0x0);
#else
alt_irq_register( BUTTON_PIO_IRQ,
edge_capture_ptr,
handle_button_interrupts );
#endif
}

소스 찾기 드럽게 힘드네...


이걸 베이스로 해서 일단 인터럽트가 발생하면 '.'을 찍어서 제대로 돌아가는지 확인해보자.

static void handle_UI_interrupts(void* context){
volatile int* edge_capture_ptr = (volatile int*) context;

*edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_3_BASE);

alt_putchar('.');

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_3_BASE, 0);
IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_3_BASE);
}

이렇게 해서 돌려봤다.
























엔코더를 좌우로 돌리면 화면상에 ......이 출력된다.

흠,,, 되는거 같다.

여기에 좀 더 살을 붙여서 유저 인터페이스를 완성해야겠다.


PIO 인터럽트 하는김에 UART도 인터럽트 형태로 바꿀려고 했는데...
도저히 샘플 소스를 찾을 수가 없다...ㅠㅠ
나중에 한가해지면 핸드북 꼼꼼하게 읽어보면서 바꿀 생각이다.

오늘은 여기까지.

2014/02/18

Nios II 시작해보자-4(SPI-Software)

NIOS II EDS 실행해서 프로젝트 만들고

아래와 같이 만들어봤다.
#include "sys/alt_stdio.h"
#include "system.h"
#include <stdlib .h>
#include "altera_avalon_spi_regs.h"

#define _NOP() asm ("nop")

unsigned char RxBuffer1[32];
unsigned char RxCounter1 = 0;

int UART1_get_Number(void){
unsigned char key_value, i;
int KeyIn;

do{
key_value = alt_getchar();
alt_putchar(key_value);
if(key_value == '\r'){
RxBuffer1[RxCounter1]='\0';
alt_putstr("\r\n");
KeyIn = atoi(RxBuffer1);

RxCounter1 = 0;
for(i = 0; i < 32; i++)
RxBuffer1[i] = 0;

return KeyIn;
}
else
RxBuffer1[RxCounter1++] = key_value;
}while((key_value != '\r')&&(RxCounter1 != 32));

}

int main()
{
int tmp, sum, avg, i, j, k, l;
alt_u16 write_data[1], read_data[1], adcs[15];
alt_u16 adc_ch, adc_cmd;

alt_putstr("20131118_1\r\n");
alt_putstr("1. HELP : Show menu explanation\r\n");
alt_putstr("2. Read ADS7961S\r\n");
alt_putstr("anonymous>");

/* Event loop never exits. */
while (1){
tmp = UART1_get_Number();

switch(tmp){
case 1:
alt_putstr("1. HELP : Show menu explanation\r\n");
alt_putstr("2. Read ADS7961S\r\n");
break;
case 2:
alt_putstr("2. Read ADS7961S\r\n");

//0010 01xx x000 0000
write_data[0] = 0x2400;
alt_avalon_spi_command(SPI_0_BASE, 0,
1, write_data,
0, read_data,
0);

for(i=0;i<16;i++){
alt_avalon_spi_command(SPI_0_BASE, 0,
0, write_data,
1, read_data,
0);
adcs[read_data[0]>>12] = read_data[0];
}

for(i=0;i<16;i++)
alt_printf("adc_ch %x : %x\r\n",i, (adcs[i]>>4) & 0xff);

break;
default :
alt_putstr("Invalid input value\r\n");
break;
}
alt_putstr("anonymous>");
}
return 0;
}



ADS7961S는 Manual, Auto-1, Auto-2 라는 세가지 채널 시퀀싱 모드를 제공한다.
난 Auto-1 모드를 선택해서 써볼란다.

write_data[0] =  0x2400;
alt_avalon_spi_command(SPI_0_BASE, 0,
1, write_data,
0, read_data,
0);
0x2400을 write해서 Auto-1 모드를 선택한다.

for(i=0;i<16;i++){
alt_avalon_spi_command(SPI_0_BASE, 0,
0, write_data,
1, read_data,
0);
adcs[read_data[0]>>12] = read_data[0];
}
16번 read해서 16채널의 adc 값을 읽어온다.

이게 다지 머



제대로 돌아가는지 함 돌려보자.

시발 좆같은 오실로를 쓰고있어서 파형 저장도 안돼고 나 썅.




























CH1 : MISO
CH2 : SCLK
CH3 : MOSI

인데 클럭말곤 안나오네. 0x2400 시그널이 왜 안나오지??

SPI read 부분은 빼고 0x1234를 write해서 시그널을 다시 확인해보자.
    //0010 01xx x000 0000
//write_data[0] = 0x2400;
write_data[0] = 0x1234;
alt_avalon_spi_command(SPI_0_BASE, 0,
1, write_data,
0, read_data,
0);
#if 0
for(i=0;i<16;i++){
alt_avalon_spi_command(SPI_0_BASE, 0,
0, write_data,
1, read_data,
0);
adcs[read_data[0]>>12] = read_data[0];
}

for(i=0;i<16;i++)
alt_printf("adc_ch %x : %x\r\n",i, (adcs[i]>>4) & 0xff);
#endif





























응??
0x0034??
앞에 12는 어디간겨??

int alt_avalon_spi_command(alt_u32 base, alt_u32 slave,
alt_u32 write_length, const alt_u8 * write_data,
alt_u32 read_length, alt_u8 * read_data,
alt_u32 flags)
Nios의 SPI 관련 함수의 선언부다...만 먼가 좀 이상하군 난 분명히 16bit width로 설정했는데 왜 write_data, read_data가 8bit지?? 하위 8bit만 write되고, 하위 8bit만 read되는 상황인디...

내가 머리가 나빠서 왜 저렇게 만든건진 모르것고 변수 선언부를 alt_u16으로 수정했다.

int alt_avalon_spi_command(alt_u32 base, alt_u32 slave,
alt_u32 write_length, const alt_u16 * write_data,//changed 16bit
alt_u32 read_length, alt_u16 * read_data, //changed 16bit
alt_u32 flags)
{
const alt_u16 * write_end = write_data + write_length; //changed 16bit
alt_u16 * read_end = read_data + read_length; //changed 16bit

alt_u32 write_zeros = read_length;
alt_u32 read_ignore = write_length;
alt_u32 status;

/* We must not send more than two bytes to the target before it has
* returned any as otherwise it will overflow. */
/* Unfortunately the hardware does not seem to work with credits > 1,
* leave it at 1 for now. */
alt_32 credits = 1;

/* Warning: this function is not currently safe if called in a multi-threaded
* environment, something above must perform locking to make it safe if more
* than one thread intends to use it.
*/

IOWR_ALTERA_AVALON_SPI_SLAVE_SEL(base, 1 << slave);

/* Set the SSO bit (force chipselect) only if the toggle flag is not set */
if ((flags & ALT_AVALON_SPI_COMMAND_TOGGLE_SS_N) == 0) {
IOWR_ALTERA_AVALON_SPI_CONTROL(base, ALTERA_AVALON_SPI_CONTROL_SSO_MSK);
}

/*
* Discard any stale data present in the RXDATA register, in case
* previous communication was interrupted and stale data was left
* behind.
*/
IORD_ALTERA_AVALON_SPI_RXDATA(base);

/* Keep clocking until all the data has been processed. */
for ( ; ; )
{

do
{
status = IORD_ALTERA_AVALON_SPI_STATUS(base);
}
while (((status & ALTERA_AVALON_SPI_STATUS_TRDY_MSK) == 0 || credits == 0) &&
(status & ALTERA_AVALON_SPI_STATUS_RRDY_MSK) == 0);

if ((status & ALTERA_AVALON_SPI_STATUS_TRDY_MSK) != 0 && credits > 0)
{
credits--;

if (write_data < write_end)
IOWR_ALTERA_AVALON_SPI_TXDATA(base, *write_data++);
else if (write_zeros > 0)
{
write_zeros--;
IOWR_ALTERA_AVALON_SPI_TXDATA(base, 0);
}
else
credits = -1024;
};

if ((status & ALTERA_AVALON_SPI_STATUS_RRDY_MSK) != 0)
{
alt_u32 rxdata = IORD_ALTERA_AVALON_SPI_RXDATA(base);

if (read_ignore > 0)
read_ignore--;
else
*read_data++ = (alt_u16)rxdata; //changed 16bit
credits++;

if (read_ignore == 0 && read_data == read_end)
break;
}

}

/* Wait until the interface has finished transmitting */
do
{
status = IORD_ALTERA_AVALON_SPI_STATUS(base);
}
while ((status & ALTERA_AVALON_SPI_STATUS_TMT_MSK) == 0);

/* Clear SSO (release chipselect) unless the caller is going to
* keep using this chip
*/
if ((flags & ALT_AVALON_SPI_COMMAND_MERGE) == 0)
IOWR_ALTERA_AVALON_SPI_CONTROL(base, 0);

return read_length;
}



자 다시 돌려보자.





























좀 흔들렸네...어쨌든 0x1234 나왔다.

SPI write는 확인했고, 다음은 read를 확인해보자.
0x1234를 0x2400으로 바꾸고 주석처리한 부분도 해제해서 돌려보자.





























오케이 ADC값이 나온다.
10번 채널에 33이 출력된다. 16비트 데이터 중 상위 4비트는 채널값이고 그 다음 8비트가 ADC 값이다. 하위 4비트는 Don't care.















시리얼로 출력은 이렇게 나온다. 0x21 = 33























ADS7961S의 10번 채널에 센싱 저항을 연결해서 LED 듀티를 변경하면서 adc 값을 읽어봤다.

잘 되네.








2014/02/17

Nios II 시작해보자-4(SPI-Hardware)

기존 NIOS 코어에는 onchip_memory와 uart만 붙어있다.

여기에 SPI를 추가해서 써먹어 보자.

SPI 마스터는 NIOS, SPI 슬레이브는 ADS7961S ADC.

16채널, 8비트, 1MSPS ADC이고 당연히도 SPI 인터페이스다.


흠... 일단 qsys로 기존 시스템을 열어보자.

쪼기 SPI 보이네. 떠블 클릭


다음 메뉴들을 선택해서 SPI를 설정해야된다.

Type : Master/Slave
Num of select(SS_n) : [32:1]
SPI clock : 128000Hz
Width : [32:8]bits
Shift direction : MSB/LSB first
Clock polarity : 0/1
Clock phase : 0/1


난 이렇게 설정했다.

Type : Master                    <-- p="">Num of select(SS_n) : 1     <-- p="">
SPI clock : 128000Hz          <-- p="">
Width : 16bits                     <-- 16bit="" adc="" p="" spi="">
Shift direction : MSB first    <-- adc="" first="" msb="" p="" spi="">
Clock polarity : 0                <-- p="">
Clock phase : 0                  <-- p="">

클락 설정 설명 그림
이 중 맞는걸 쓰면 된다.

그리고 finish 눌러서 추가해주자.



System Contents 화면 상에서 clk, reset, spi_control_port 연결하고 Export 클릭해주고 IRQ도 연결해준다.
그다음 System 메뉴의 Assign Base Addresses와 Assign Interrupt Numbers를 클릭해주면 SPI 관련 설정은 끝난다.

그리고 Save As에서 nios_v003으로 저장한다. 기존 시스템은 건들지 말고 새로 저장해서 하자. 나중에 눈물 흘리지 말고

그다음 할 일은 Generation이지.

좀 시간이 걸린다만 에러없이 생성되면 아주 땡큐...난 에러 없이 생성되었다.


자...그럼 쿼터스에서 새로운 프로젝트를 만들어서 bdf 파일을 생성하고 방금 만든 nios_v003 블럭을 꽂아보자.

필요한거 다 연결하면 아마도 이런 모양이것지.

다음은 nios_v003의 qip 파일을 추가할 차례.
Assignments 탭의 Settings를 클릭해서 Files 카테고리로 가면 된다.
File name 항목의 ...을 클릭해서 nios_v003 폴더 내의 synthesis 폴더로 들어가면 nios_v003.qip 파일이 있다. 이거 선택하고 Add.

핀할당만 해주면 되것군.
Save 해주고 Synthesis 한 다음에 핀 할당 해줍시다.
저장한 다음 Start Compilation.

오케. 하드웨어는 만들었다. 다음은 프로그램 함 짜보자.

2013/11/25

하드코어 MCU여 안녕




간단한 LED 조명 시스템...인데

소프트코어로 NIOS를 써서 FPGA로만 구현해봤다. LED 드라이버는 예전에 만들어둔 MSL2100 보드.

PCB는 간단해져서 좋은데 MCU가 없으니 왜이리 불안하냐...

주요 기능들(LCD, 키 스캔, I2C, GPIO, etc)은 로직으로 구현하고 MCU는 외부 호스트 인터페이스에 집중한다는 컨셉으로 가는중인데, MCU와 로직의 인터페이스가 쉽지가 않네...
I2C나 GPIO는 늘 쓰던거라 별 걱정 없지만 LCD도 쉽지않아...

이게 잘되면 오픈코어 MCU로 가봐야것다.
"FPGA 벤더 인디펜던트 데이 프로젝트"

간만에 오픈코어 홈페이지나 가봐야지

2013/03/18

Nios II 시작해보자-3


PIO를 추가해서 컨트롤 로직의 인터페이스로 사용해봤다.

이런 형태도 가능하구만...

늘 VHDL 파일 하나로만 설계를 해서 이런식으로 설계하는 방식이 있는줄도 몰랐다.

역시 많이 해봐야되...난 아직 멀었나봐...



기존에는 MCU로 UART 통신을 하고 FPGA로 대부분의 신호 처리를 하도록 설계했었는데...

더이상 그럴 필요가 없네.

Nios를 처음 시작한 목표는 달성했다. 움푸홧홧홧



다음엔 Qsys의 새로운 컴포넌트로 생성해서 써먹어봐야것다.

2012/12/26

Nios II 시작해보자-2

Nios II EDS를 실행해보자.

윈도우 메뉴의 Open Perspective에서 Other...를 클릭


여기서 Nios II를 선택한다.

File 메뉴의 New를 클릭해서 Nios II Application and BSP from Template를 선택


위 창이 뜬다.
SOPC Information File name은 프로젝트 폴더에 생성되어 있으니 걱정마라.
프로젝트 이름은 아무거나 써도 된다. 프로젝트 이름은 sopcinfo 파일명과 동일해야한다.
템플릿은 Hello World Small을 선택하고 Finish.




일단 이렇게 짜보자.

빌드를 하면 별 문제없이 컴파일된다.

프로젝트 익스플로러에서 NIOSIIf_UART를 오른쪽 클릭해서 Make Targets의 Build를 실행해라.


여기서 mem_init_generate를 선택하고 Build.

이제 hex 파일이 생성되었다. 프로젝트 폴더내의 software/NIOSIIf_UART/mem_init/ 폴더에 NIOSIIf_UART_onchip_memory2_0.hex 를 확인할 수 있을거다.

그럼 이걸 어떻게 FPGA에 다운로드 할 것이냐....

다시 Quartus II로 돌아가야 한다.

Quartus II의 Project 메뉴에 Add/Remove Files in Project를 선택해라. hex 파일이 생성된 폴더로 가면 meminit.qip라는 파일이 있는데 그걸 추가하면 된다.

그리고 Start Compilation.

컴파일이 끝나면 .sof를 .jic로 변경해서 다운로드하면 된다.


이런식으로 돌아간다.

타이머랑 PIO도 추가해서 함 돌려봐야것다.

Nios II 시작해보자-1

일단 간단하게 가보자.


예전에 만들었던 EP4CE22E22 모듈을 쓸 예정이니까 FPGA 스펙부터 확인하자.

- Logic elements(LEs) : 22,320
- Embedded memory(Kbits) : 594
- Embedded 18 x 18 multipliers : 66
- General-purpose PLLs : 4
- Global Clock Networks : 20
- User I/O Banks : 8
- Maximum user I/O : 153

하드웨어 구성은
- Nios II/s processor core
- On-chip memory
- UART
요 세가지로 하자.

1. SW version
   - Quartus II 64-Bit version 12.0 Build 178 05/31/2012 SJ Full Version
   - NIOS II EDS 12.0
   *. NIOS II를 오픈코어 플러스 평가판 라이센스로 돌려도 된다.
      제한이 무지 많으니까 명심하도록.

2. Quartus II 프로젝트 생성

   - NIOSII_Start 폴더를 만들고 프로젝트 이름도 똑같이 만들었다. Next

   - 추가할 파일 없으니까 그냥 Next

   - EP4CE22E22C8N 이니까 해당하는 디바이스 선택 후 Next

   - 여긴 걍 통과. Next

   - 다 만들었다. Finish

   - 자 준비는 끝났고, 시작해 봅시다.

3. Block Diagram File 생성
  - Quartus II 의 File -> New

    - Block Diagram/Schematic File 선택 후 OK
    - Save Project 해주자.

4. Create a New Qsys System
    - Quartus의 Tool메뉴에서 Qsys를 클릭해라. 아래 창이 뜰거다

    - 일단 Nios II 프로세서부터 붙여보자.

    - 저걸 더블클릭해라.


    - Nios II 코어는 3종류다. 난 일단 Nios II/f을 선택했다. 다른설정 건드릴거 없이 Finish


    - On-Chip 메모리 붙일 차례. 저거 더블클릭.


    - Total memory size만 32768로 변경하고 Finish.
      디바이스의 메모리 용량이 크면 이거보다 크게해도 상관없다.
      EP4CE22E22의 메모리 절반 정도의 사이즈다.


    - 마지막으로 UART 붙일 차례. 저거 더블클릭


    - 보레잇 115200으로 Fixed baud rate 설정해준다. Finish


   - 여기까지 사용할 컴포넌트는 다 추가했다.


   - 다음은 모듈간 연결을 해줄 차례다. 위 그림과 같이 연결하면 된다.
      외부로 빠질 시그널은 CLK, RST, UART Rx/Tx 다. Export 창을 클릭하면 된다.


   - System의 Assign Base Addresses를 클릭해봐라.
      Base 컬럼의 16진수값이 변경될거다.


   - System의 Assign Interrupt Numbers를 클릭해봐라.
      IRQ 컬럼의 값이 생성된다.


   - Nios2_qsys_0를  더블클릭해서 윗 그림처럼 변경해라.


   - Generation 탭에서 Generate를 클릭하면 그토록 염원하던 니오스 코어가 생성된다.
     중간중간 워닝이 뜨지만 일단 무시하자.

5. Quartus II에 Nios II 붙이기
   - Quartus II의 bdf 창을 더블클릭 해보시라.


   - 이런 창이 뜬다.


   - Libraries에 Project를 열어보면 방금 만든 Nios 코어가 보인다. OK


   - 여기에 클럭, 리셋, UART Rx/Tx만 연결하면 된다.


   - 이렇게 연결하고 Save Project. 다음은 qip 파일을 추가한다.


   - Asignments의 Setting로 가자.
     Nios 코어 폴더내의 synthesis 폴더내에 NIOSIIf_UART.qip 파일이 있다.
     add 하고 OK.


   - DEV_CLRn에 스위치를 연결해서 써먹을란다. 저거 Enable.

   - 핀 할당 해줘야 하니까 Analysis & Synthesis 실행하자.


   - 회로 설계한대로 핀 할당 해준다. 그 다음은 Start Compilation.
     담배한대 피고...


일단 여기까지 Hardware는 만들었다.

다음은 NIOS II EDS로 간단한 디버깅 프로그램을 만들어보자.