Сначала о модуле:
Два порта, мастер и слейв. У слейва три регистра: CNTRL, STATUS и ADR. CNTRL: 0-ой бит – go. NIOSII выставляет этот бит, модуль начинает работать, на следующий такт бит автоматически сбрасываетя. STATUS: 2-ой бит – error, этот бит выставляется, если произошла ошибка. 1-ый бит – busy, выставлен пока модуль работает. 0-ой бит – done, выставлется когда работа модуля закончена. ADR – в этот регистр NIOSII записывает адрес. Работает модуль (по моей задумке, по крайней мере) так: выставляется бит go, логика модуля по этому биту считывает данные извне (свитчи на плате) и передает их мастер-порту. Мастерпорт, получив эти данные, записывает их по адресу из регистра ADR слейва, потом читает данные оттуда же. Если данные совпадают, то работа модуля заканчивается, если не совпадают, то выставляется бит error.
Код программы для NIOSII:
Код
#include <stdlib.h>
#include "alt_types.h"
#include <stdio.h>
#include <unistd.h>
#include "system.h"
#include "sys/alt_irq.h"
#include "altera_avalon_pio_regs.h"
#include "TestM_regs.h"
int ButFlag=0;
static void handle_button_interrupts(void* context, alt_u32 id)
{
*((alt_u8*)context)=1;
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUT_BASE, 0);
}
static void init_button_pio()
{
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUT_BASE, 0x1);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUT_BASE, 0x0);
alt_irq_register( BUT_IRQ, (void*) &ButFlag, handle_button_interrupts );
}
int main()
{
alt_u32 led=0xAAAA;
init_button_pio();
while(1)
{
if (ButFlag){
IOWR_TESTM_ADR(TESTM_0_BASE,(int)&led);
IOWR_TESTM_CTRL(TESTM_0_BASE,0x1); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
while (IORD_TESTM_STATUS(TESTM_0_BASE) & 0x1);
IOWR_ALTERA_AVALON_PIO_DATA(LEDR_BASE,led);
ButFlag=0;
}
}
return 0;
}
#include "alt_types.h"
#include <stdio.h>
#include <unistd.h>
#include "system.h"
#include "sys/alt_irq.h"
#include "altera_avalon_pio_regs.h"
#include "TestM_regs.h"
int ButFlag=0;
static void handle_button_interrupts(void* context, alt_u32 id)
{
*((alt_u8*)context)=1;
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUT_BASE, 0);
}
static void init_button_pio()
{
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUT_BASE, 0x1);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUT_BASE, 0x0);
alt_irq_register( BUT_IRQ, (void*) &ButFlag, handle_button_interrupts );
}
int main()
{
alt_u32 led=0xAAAA;
init_button_pio();
while(1)
{
if (ButFlag){
IOWR_TESTM_ADR(TESTM_0_BASE,(int)&led);
IOWR_TESTM_CTRL(TESTM_0_BASE,0x1); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
while (IORD_TESTM_STATUS(TESTM_0_BASE) & 0x1);
IOWR_ALTERA_AVALON_PIO_DATA(LEDR_BASE,led);
ButFlag=0;
}
}
return 0;
}
Суть глюка: если прогу запустить как Run As, то LEDR (лампочки на плате) выводят 0xAAAA, а не то, что выставлено свичами. При этом бит ошибки не выставляется. Если запустить как Debug as NIOSII Hardware, то начинаются странности. Если на любой строчке до помеченной восклицательными знаками включительно сделать step (F5 или F6), то все прекрасно работает, выводится именно то, что на свичах. Если же с самого начала дебагинга сделать resume (F8) или же поставить брейкпоинт за помеченной строчкой, то прога ведет себя как при Run As. В чем суть глюка я понять не могу решительно. Адрес в ADR пишется, бит done выставляется, error – нет. Грешил на SDRAM, но проект делал на основе альтеровского примера ниоса для этой самой платы (Starter kit - cyclon 2). Попробовал снизить частоту со 100 до 50 – не помогло. На всякий случай прикладываю файлы головного модуля, модуля pll и reset.
Подскажите, в чем может быть дело и где вообще искать решение?
PS: Я еще только начинаю. Если кому-то вдруг будет не лень просмотреть мои верилоговские файлы и указать всякие ошибки перехода от C к Verilog? поправить стиль и т.п., то я буду очень благодарен!!!
Прикладываю файлы:
TESTM.v, TESTM_L.v, TESTM_M.v, TESTM_S.v - верилоговские файлы, описывающие сам модль.
TestM_regs.h -файл с макросами для работы с модулем.
sdram_pll.v и reset_delay.v - соответственно названию.
NT.v - головной модуль проекта.
Кстати, пытался добавить квартовский архив проекта, но "не имеете прав на добавление файла с разрешением" qar. Почему?