Перейти к содержанию
    

acvarif

Участник
  • Постов

    998
  • Зарегистрирован

  • Посещение

Весь контент acvarif


  1. Имеется проект на двух отдельных ПЛИС Max 2 EPM1270T144C5. По отдельности каждый кусок проекта не влазит ни в одну ПЛИС. Есть-ли возможность каскадирования ПЛИС так, чтобы сделать один проект на две плисыны сразу? Есть надежда, что таким образом все влезет. Подскажите пожалуйста где про это можно почитатать. Как в Quartus начать проект на каскадированных ПЛИС? Да.. Поторопился. Очевидно вспомнился старый проект на нескольких FPGA с одним загрузочным ПЗУ. В этом смысле тогда и использовалось каскадирование. Виноват. Вопрос снят.
  2. По прерываниям производится выдача данных по Tx Uart Nios из некоторого буфера char Buff[4800]. Период повторения 1 сек. Все данные из буфера выдаются на скорости 115200 примерно за 0.4 сек. В програме для Nios есть острая необходимость определить момент когда будет выдан по Tx последний байт из буфера. Для этого использую бит TMT регистра статуса. unsigned char EmptyTxUart1() { int sr; sr = IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE); if(sr & ALTERA_AVALON_UART_STATUS_TMT_MSK) return 1; else return 0; } Далее в теле программы if(!EmptyTxUart1() && !BeginReadContr) BeginReadContr = 1; else BeginReadContr = 0; Вроде работает. Бит TMT устанавливается. Но устанавливается намнго раньше (~ 0.1 сек) чем будет выдан последний бит по Tx (~0.4 сек). Контроль установки BeginReadContr и сигнала Tx веду по осциллографу. В чем тут хитрость? Как можно правильно пределить момент выдачи последнего бита из буфера Tx Nios Uart?
  3. Да. Прояснилось. Ошибка в обработчике. В обработчике начинать счет прерываний нужно после того как пойманы синхросимволы по чтению двухпортовой RAM, а не до того. По поводу скорости выполнения операций в main по каждому прерыванию. Время между двумя соседними прерываниями 2 мс. За это время нужно из 16 байт данных сформировать некий протокол и пр. требуха. Как максимально ускорить выполнение операций в main? В смысле какая предпочтительнее конфигурация Nios и что желательно настроить в BSP?
  4. Контроль веду по осциллографу. Паразитных всплесков нет. Собственно сама RAM -- карта соединений памяти меток -- принимает (запись) метки от uuartrx_mt -- отправляет (чтение) метки в Nios в кажд. эл. дист -- enable памяти меток s_mtwe <= s_canceler; -- сигнал записи данных в пам. меток s_wrmt <= s_tx_done_tick; -- данные s_datarx на память меток s_d_mtdata_one <= s_datarx; -- адреса чтения 16 байт s_mtraddr <= avs_s0_address(3 downto 0); umtdata : ramdata generic map (8, 4) port map ( rclk => s_rdmt, wclk => s_wrmt, raddr => s_mtraddr, waddr => s_mtwaddr, data => s_d_mtdata_one, we => s_mtwe, q => s_q_mtdata_one ); -- данные на Avalon MM Slave из памяти меток avs_s0_readdata <= s_q_mtdata_one; -- сигнал чтения из Avalon MM Slave на RAM s_rdmt <= (not clk and not avs_s0_read_n and avs_s0_byteenable(0)); Наверное лишним прицеплено avs_s0_byteenable(0) для сигнала чтения Ram. Да и без него все то же самое. Чудес не бывает, но обработчик таки действительно только по второму прерыванию читает реальные данные из двухпортовой RAM. Не связано-ли это с какими-то кешами?...
  5. Спасибо. Понятно. В тему появилась еще непонятка. При чтении по прерывании (из Nios) данных которые заранее записаны в двухпортовую RAM первое прерывание читает все 0 и только по второму прерыванию читаются верные данные. Ниже обработчик. void Irq0Isr(void* context, alt_u32 id) { alt_u8 i; // сброс сигнала прерывания IORD_8DIRECT(AMULET_0_BASE, 255); // чтение двухпортовой RAM for (i = 0; i < 16; i++) { RamData[i] = IORD_8DIRECT(AMULET_0_BASE, i); } // флаг прерывания FlIrq0 = 1; // счетчик прерываний AllIrq0Count++; // синхро поймано if (RamData[0] == 0x55 && RamData[1] == 0xaa && !BeginTrns) { // начало передачи протокола BeginTrns = 1; // общее количество байт информации о метках AllNbData = (RamData[6] << 8) | RamData[7]; // переключатель банков памяти протокола if(NbTx) NbTx = 0; else NbTx = 1; // флаг для светодиода BeginPr = 1; // фиксация номера прерывания printf("Номер прерывания синхросимволов Irq0: N %d \n", AllIrq0Count); } } Дело в том, что синхросимволы уже имеются в памяти и должны появиться в RamData по первому прерыванию, тоесть когда AllIrq0Count = 1. Но printf принтует в окне терминала N 2. На самом деле так оно и есть. Почему по первому прерыванию из двухпортовой RAM читаются нули, а не реальные данные ?
  6. Спасибо. Смысл понятен. Не соображу как эти регистры создать. По типу .h фала? #ifndef __ALTERA_AVALON_AMULET_REGS_H__ #define __ALTERA_AVALON_AMULET_REGS_H__ #include <io.h> #define ALTERA_AVALON_AMULET_STATUS_REG 2 #define IOADDR_ALTERA_AVALON_AMULET_STATUS(base) \ __IO_CALC_ADDRESS_NATIVE(base, ALTERA_AVALON_AMULET_STATUS_REG) #define IORD_ALTERA_AVALON_AMULET_STATUS(base) \ IORD(base, ALTERA_AVALON_AMULET_STATUS_REG) #define IOWR_ALTERA_AVALON_AMULET_STATUS(base, data) \ IOWR(base, ALTERA_AVALON_AMULET_STATUS_REG, data) #define ALTERA_AVALON_AMULET_STATUS_IRQ0_MSK (0x1) #define ALTERA_AVALON_AMULET_STATUS_IRQ0_OFST (0) #define ALTERA_AVALON_AMULET_STATUS_IRQ1_MSK (0x2) #define ALTERA_AVALON_AMULET_STATUS_IRQ1_OFST (1) #define ALTERA_AVALON_AMULET_CONTROL_REG 3 #define IOADDR_ALTERA_AVALON_AMULET_CONTROL(base) \ __IO_CALC_ADDRESS_NATIVE(base, ALTERA_AVALON_AMULET_CONTROL_REG) #define IORD_ALTERA_AVALON_AMULET_CONTROL(base) \ IORD(base, ALTERA_AVALON_AMULET_CONTROL_REG) #define IOWR_ALTERA_AVALON_AMULET_CONTROL(base, data) \ IOWR(base, ALTERA_AVALON_AMULET_CONTROL_REG, data) #define ALTERA_AVALON_AMULET_CONTROL_IRQ0_MSK (0x1) #define ALTERA_AVALON_AMULET_CONTROL_IRQ0_OFST (0) #define ALTERA_AVALON_AMULET_CONTROL_IRQ1_MSK (0x2) #define ALTERA_AVALON_AMULET_CONTROL_IRQ1_OFST (1) #endif /* __ALTERA_AVALON_AMULET_REGS_H__ */ Не врубаюсь как в регистрах будут устанавливаться и сбрасываться биты. Очевидно эти регистры (ALTERA_AVALON_AMULET_CONTROL_REG, ALTERA_AVALON_AMULET_STATUS_REG) нужно создать и в самом модуле Amulet? Или нет.. Если не сложно, поясните пожалуйста коротко механизм.
  7. Попутно возник еще вопрос связанный с прерыванием. Почему невозможно добавить к Avalon Slave еще одно прерывание типа ins_irq1_irq? Sopc пишет что позволено только одно. ... avs_s0_byteenable : in std_logic_vector(0 downto 0) := (others => '0'); avs_s0_readdata : out std_logic_vector(7 downto 0); -- .readdata ins_irq0_irq : out std_logic; ins_irq1_irq : out std_logic; ...
  8. Понятно. Спасибо. bytenable имеет один разряд. Доступ должен быть побайтовый. Так оно и получилось. Нулевой байт читается по смещению на 0, первый на 1 IORD_8DIRECT(AMULET_0_BASE, 1); и т. д.
  9. Имеется модуль с Avalon Slave присоединенный в систему с Nios Port ( -- Avalon Slave clk : in std_logic := '0'; -- clock.clk reset_n : in std_logic := '0'; -- .reset_n avs_s0_address : in std_logic_vector(7 downto 0) := (others => '0'); -- s0.address avs_s0_read_n : in std_logic := '0'; -- .read_n avs_s0_write_n : in std_logic := '0'; -- .write_n avs_s0_writedata : in std_logic_vector(7 downto 0) := (others => '0'); -- .writedata avs_s0_byteenable : in std_logic_vector(0 downto 0) := (others => '0'); avs_s0_readdata : out std_logic_vector(7 downto 0); -- .readdata ins_irq0_irq : out std_logic; В модуле имеется двухпортовая RAM (16 байт) которую необходимо читать по прерыванию ins_irq0_irq В программе обработчика первым делом сбрасываю импульс прерывания чтением по крайнему адресу .... void Irq0Isr(void* context, alt_u32 id) { // сброс сигнала прерывания IORD_8DIRECT(AMULET_0_BASE, 255); Isr0Occur = 1; AllIrq0Count++; } .... В майн читаю память. Данные в памяти заранее известны. 0x55, 0xaa, ... ... if (AllIrq0Count) { RamData = IORD_8DIRECT(AMULET_0_BASE, 0); printf("Прерывание Irq0: N %d \n", AllIrq0Count); printf("Данные: %x \n", RamData[0]); AllIrq0Count = 0; } .... Все работает нормально пока (AMULET_0_BASE, 0) Вопрос как считать данные по следующему адресу RAM? Какое должно быть смещение. Поскольку Nios оперирует байтами, а Avalon имеет ширину 32 бита, то смещение для чтения следующего байта из двухпортовой RAM должно быть 4. Прочитанный байт должет быть 0хaa. На практике читается все то же 0х55. Подскажите пожалуйста в чем загвоздка?
  10. Понятно. Так и делаю. Uart не работает. Работает только при #define UART_0_FIXED_BAUD 1 И вообще странности. Вот прием по прерыванию // Чтение регистра статуса для определения причины прерываний status = IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE); // Очистка всех флагов ошибок IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0); // Процесс чтения irq (если байт получен бит RRDY = 1) if (status & ALTERA_AVALON_UART_STATUS_RRDY_MSK) { // Чтение данных если нет ошибок приема (PE-ошибка бита паритета FE-некоректный стоп бит) // if (!(status & (ALTERA_AVALON_UART_STATUS_PE_MSK | ALTERA_AVALON_UART_STATUS_FE_MSK))) if (!(status & (ALTERA_AVALON_UART_STATUS_FE_MSK))) { BufRxUart[UartRxCount] = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE); UartRxCount++; } } То работает то нет при разной длине входного пакета. Может действительно в Quartus11.0 проблема с Uart компонентом?
  11. Спасибо. Про прием понятно. Софт установка скорости не работает. Уже не знаю что и думать. Вывел UART_TXD на осциллограф. При #define UART_0_FIXED_BAUD 1 все работает. При #define UART_0_FIXED_BAUD 0 на выходе логическая 1. Ошибка компонента SOPC UART?
  12. Если DE0Nano+Nios2+Ethernet то тут http://acvarif.info/prvhdl/prvhdl20.html С rtl8201cl по ходу можно разобраться по аналогии.
  13. Да, есть такая функция /* * altera_avalon_uart_rxirq() is called by altera_avalon_uart_irq() to * process a receive interrupt. It transfers the incoming character into * the receive circular buffer, and sets the apropriate flags to indicate * that there is data ready to be processed. */ static void altera_avalon_uart_rxirq(altera_avalon_uart_state* sp, alt_u32 status) { alt_u32 next; /* If there was an error, discard the data */ if (status & (ALTERA_AVALON_UART_STATUS_PE_MSK | ALTERA_AVALON_UART_STATUS_FE_MSK)) { return; } /* * In a multi-threaded environment, set the read event flag to indicate * that there is data ready. This is only done if the circular buffer was * previously empty. */ if (sp->rx_end == sp->rx_start) { ALT_FLAG_POST (sp->events, ALT_UART_READ_RDY, OS_FLAG_SET); } /* Determine which slot to use next in the circular buffer */ next = (sp->rx_end + 1) & ALT_AVALON_UART_BUF_MSK; /* Transfer data from the device to the circular buffer */ sp->rx_buf[sp->rx_end] = IORD_ALTERA_AVALON_UART_RXDATA(sp->base); sp->rx_end = next; next = (sp->rx_end + 1) & ALT_AVALON_UART_BUF_MSK; /* * If the cicular buffer was full, disable interrupts. Interrupts will be * re-enabled when data is removed from the buffer. */ if (next == sp->rx_start) { sp->ctrl &= ~ALTERA_AVALON_UART_CONTROL_RRDY_MSK; IOWR_ALTERA_AVALON_UART_CONTROL(sp->base, sp->ctrl); } } Находится в файле altera_avalon_uart_init.c Как она связана с тем, что uart не работает при софт установке скорости бод #define UART_0_FIXED_BAUD 0
  14. С флагами вроде все нормально. Хотя еще проверю... А вот с установкой скорости все тоже. Не работает. Код: alt_u16 context_uart; alt_u16 divisor; divisor = (ALT_CPU_FREQ/BaudRate) + 1; IOWR_ALTERA_AVALON_UART_DIVISOR(UART_0_BASE, divisor); IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, ALTERA_AVALON_UART_CONTROL_RRDY_MSK); Работатает только при #define UART_0_FIXED_BAUD 1 Странно. Думал имеется возможность немного корректировать скорость... модуль UART Quartus 11.0 Sp1. Может кто тоже сталкивался с таким казусом?
  15. Немного переделал код. Заработало. #include "system.h" #include "altera_avalon_pio_regs.h" #include "alt_types.h" #include "stdio.h" #include "sys/alt_irq.h" #include "altera_avalon_uart_regs.h" #include <unistd.h> #include <io.h> //--------------------------------------------------------------------------------------------- // Константы #define BAUD_RATE 115200 //--------------------------------------------------------------------------------------------- // Объявления функций void UartIsr(void* context, alt_u16 id); void InitUart(alt_u32 BaudRate); //--------------------------------------------------------------------------------------------- // Глобальные переменные alt_u8 Start = 0; alt_u8 Buf_uart[256]; alt_u16 Uart_count = 0; //--------------------------------------------------------------------------------------------- // Функции //--------------------------------------------------------------------------------------------- // прерывания по UART void UartIsr(void* context, alt_u16 id) { alt_u16 status; // Чтение регистра статуса для определения причины прерываний status = IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE); // Процесс чтения irq if (status & ALTERA_AVALON_UART_STATUS_RRDY_MSK) { Buf_uart[uart_count] = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE); Uart_count++; // Очистка всех флагов ошибок IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0); } if(Uart_count >= 72 && Buf_uart[0] == 0x55) { Start = 1; Uart_count = 0; } } //--------------------------------------------------------------------------------------------- // инициализация Uart void InitUart(alt_u32 BaudRate) { alt_u16 context_uart; alt_u16 divisor; divisor = (ALT_CPU_FREQ/BaudRate) + 1; IOWR_ALTERA_AVALON_UART_DIVISOR(UART_0_BASE, divisor); IOWR_ALTERA_AVALON_UART_CONTROL(UART_0_BASE, ALTERA_AVALON_UART_CONTROL_RRDY_MSK); // регистрация прерываний UART_0_IRQ alt_irq_register(UART_0_IRQ, &context_uart, UartIsr); // alt_irq_enable (UART_0_IRQ); } //--------------------------------------------------------------------------------------------- int main (void) { alt_u8 led = 0x2; alt_u8 dir = 0; InitUart(BAUD_RATE); alt_irq_enabled(); // main while while(1) { if(Start == 1) { Start = 0; // running led if(led & 0x81) dir = (dir ^ 0x1); if(dir) led = led >> 1; else led = led << 1; // write in PIO_0_BASE led IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, led); } } return 0; } Далее в SOPC в модуле UART убраз птичку с "Fixed baud rate" для возможности программного назначения частоты бод. Код (или SOPC система) не работает. Можно-ли программно корректировать частоту бод в модуле UART Nios?
  16. Организованы в системе на Nios II прерыывания Uart по приему одного байта на скорости 115200 Байты приходят короткими пакетами по 72 байта с периодом 0.5 сек. Если количество принятых байт равно 72 и первый байт равен 0х55 то Start = 1; В основном цикле main все сбрасывается (uart_count, Start). ... alt_u8 Start = 0; alt_u8 buf_uart[256]; alt_u16 uart_count = 0; ... // Инициализация прерываний по UART void Uart_irq_init() { // Регистрация обработчика прерываний alt_irq_register(UART_0_IRQ, (void*)UART_0_IRQ, uart_isr); } ... // прерывания по UART static void uart_isr(void* context, alt_u32 id) { alt_u32 status; // Чтение регистра статуса для определения причины прерываний status = IORD_ALTERA_AVALON_UART_STATUS(UART_0_BASE); // Очистка всех флагов ошибок IOWR_ALTERA_AVALON_UART_STATUS(UART_0_BASE, 0); // Процесс чтения irq if (status&ALTERA_AVALON_UART_STATUS_RRDY_MSK) { buf_uart[uart_count] = IORD_ALTERA_AVALON_UART_RXDATA(UART_0_BASE); uart_count++; } if(uart_count == 72 && buf_uart[0] == 0x55) { Start = 1; uart_count = 0; } } Main int main (void) { alt_u8 led = 0x2; alt_u8 dir = 0; Uart_irq_init(); alt_irq_enabled(); // главный цикл while(1) { if(Start == 1) { Start = 0; // бегущий светодиод if(led & 0x81) dir = (dir ^ 0x1); if(dir) led = led >> 1; else led = led << 1; // запись в PIO_0_BASE (0x00000000) led IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, led); } } return 0; } Данный тест проводится на Циклоне 4 (DE0Nano Terasic). Проблема в том, что если количество байт в пакете небольшое (~40) то все работает нормально. С увеличением количества байт в пекете очевидно сбивается счетчик uart_count и первый синхробайт 0x55 уже не определяется. Код простейший. Подскажите пожалуйста что в нем не так?
  17. Да. Спасибо. После редактирования top файл пришлось отредактировать еще и ..hw.tcl. В любом случае это быстрее чем полня переделка ..hw.tcl
  18. Имеется SOPC компонент выполненый как подключаемый модуль к системе с NIOS. Компонент имеет параметры типа (на картинке) Изменение и компиляция верхнеуровневого файла с измененными параметрами не влияет на параметры в компоненте. Полная переделка файла ..._hw.tcl займет много времени. Как можно отредактировать параметры компонента не создавая компонент заново?
  19. Неплохо. Векторный это как? Дополнительный модуль из библиотеки компонентов для Nios?
  20. Да нет. Немного. Применяем операционник с навесными. Думал может есть готовый ампл. детектор, несколько штук в корпусе. Но... Детектор нужен для банального детектирования радиоимпульса 500 мкс с заполнением 50 кгц.
  21. Скажите пожалуйста существует-ли микросхема двухполупериодного амплитудного детектора? Имеется ввиду чип без внешних навесных компонентов или с минимумом внешних компонентов.
  22. Имеется внешний модуль подключеный по шине Avalon к Nios. Модуль формирует прерывания в виде короткого импульса. Прерывания формируются с периодом в 212 кГц. Nios работает на частоте 100 мГц. Успеет-ли процессор за один период между двумя соседними прерываниями сформировать двухбайтный код присвоенный одному прерыванию поступающий по шине Avalon, записать его в память в нужное место? Место каждый раз разное. Место формирует небольшая короткая подпрограмма примерно в сотню операций.
  23. По поводу потребления 74vhc541 непонятно https://www.fairchildsemi.com/datasheets/74/74VHC541.pdf Неужели 75 ma? Если на той стороне стоит 485 с питанием 5В Не будет ли в этом случае проблем? В документации не совсем понятно
  24. Схемка неплохая. Кроме 485 появились еще требования по размещению на плате буферов 3.3 -> 5В. А места маловато. 74vhc541 в корпусе TSSOP подходит. Только получается если его запитать 5В он от Cyclone 3 не будет работать. Появились еще требования к буферам кроме 485. Спасибо. SN74LVC2T45DCUT устроит. Направление одно.
×
×
  • Создать...