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

Строковый парсер на VHDL

Хотел узнать насколько реально реализовать строковый парсер на FPGA. Команды от пользователя приходят из терминала по UART модулю. Их надо парсить, проверять аргументы (количество, макс/мин значения). Команд довольно много. Мне кажеться что такой парсер сожрет все ресурсы FPGA.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хотел узнать насколько реально реализовать строковый парсер на FPGA. Команды от пользователя приходят из терминала по UART модулю. Их надо парсить, проверять аргументы (количество, макс/мин значения). Команд довольно много. Мне кажеться что такой парсер сожрет все ресурсы FPGA.

Такие вещи выгоднее делать на микроконтроллере, дешиво и сердито. FPGA в принципе можно. Ресурсы в зависимости от объема парсинга. Если FPGA имеет возможность встроить Nios (или др.) в минимальном варианте, тогда все решаемо.

Изменено пользователем Acvarif

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Такие вещи выгоднее делать на микроконтроллере, дешиво и сердито. FPGA в принципе можно. Ресурсы в зависимости от объема парсинга. Если FPGA имеет возможность встроить Nios (или др.) в минимальном варианте, тогда все решаемо.

Я хотел избежать связки микроконтроллер + FPGA. Nios не расматривается. Хочу попробовать поднять на голом FPGA. А как мне подойти к этому вопросу? Я со строками в FPGA дело не имел.

Хочу начать и посмотреть как ресурсы расходуются.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я хотел избежать связки микроконтроллер + FPGA. Nios не расматривается. Хочу попробовать поднять на голом FPGA. А как мне подойти к этому вопросу? Я со строками в FPGA дело не имел.

Хочу начать и посмотреть как ресурсы расходуются.

У меня стояла такая задача - обмен по RS485 с датчиком давления "Сапфир". От использовать FPGA отказался сразу. Большой объем вычислений и преобразований. У Вас может быть по другому. Для того, чтобы понять, можно попробовать для теста распарсить чего нибудь. По результату можно будет судить что будет дальше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня стояла такая задача - обмен по RS485 с датчиком давления "Сапфир". От использовать FPGA отказался сразу. Большой объем вычислений и преобразований. У Вас может быть по другому. Для того, чтобы понять, можно попробовать для теста распарсить чего нибудь. По результату можно будет судить что будет дальше.

Это я и хочу. Попробовать парсить. Но я не знаю как подойти к этому вопросу на VHDL.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это я и хочу. Попробовать парсить. Но я не знаю как подойти к этому вопросу на VHDL.

Если не охота связываться с софт-процессором внутри FPGA (а есть очень компактные, например, MCPU на сайте opencores.org) - придется делать машину состояний и разбирать поток побайтно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если не охота связываться с софт-процессором внутри FPGA (а есть очень компактные, например, MCPU на сайте opencores.org) - придется делать машину состояний и разбирать поток побайтно.

а как мне определить строку? как массив байтов?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а как мне определить строку? как массив байтов?

Я бы разбирал непосредственно поток байтов на входе парсера. А шаблоны - константы и переходы в машине состояний.

Попробуйте написать парсер на Си в виде функции, принимающей входной поток побайтно и разбирающей его с использованием статических переменных предыдущего состояния. А потом переписать это на VHDL.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы разбирал непосредственно поток байтов на входе парсера. А шаблоны - константы и переходы в машине состояний.

Попробуйте написать парсер на Си в виде функции, принимающей входной поток побайтно и разбирающей его с использованием статических переменных предыдущего состояния. А потом переписать это на VHDL.

шутите? с С на VHDL?

 

это прием строки по UART

void USART1_IRQHandler(void)
{
  /* RXNE handler */
  if ((USART1->SR & USART_IT_RXNE) != RESET) // Received character?
  {
    /* Copy data into RX Buffer */
    uint8_t chr = (USART1->DR & (uint16_t)0x01FF);
    if (chr=='\r')  //0xD,0xA
    {
      usart1_rx_buf[usart1_rx_idx] = '\0';
      usart1_rx_idx = 0;
      usart1_rx_ready = 1;
    }
    else
    {
        if(chr=='\b')
        {
            if (usart1_rx_idx > 0)
                usart1_rx_idx--;
            return;
        }
        if(usart1_rx_idx < RX1_BUFFERSIZE)  //no overflow
        {
                usart1_rx_buf[usart1_rx_idx] = chr;
                usart1_rx_idx++;
        }
        else
            usart1_rx_overflow = 1;
    }
        /* Clear RXDATAV interrupt */
        //USART_IntClear(UART0, UART_IF_RXDATAV);
        USART1->SR = (uint16_t)~USART_FLAG_RXNE;
  }
}

 

а это парсер строки

uint32_t PARSER_ParseInputString(char* str, char** args)
{
    uint32_t argc=0;

    args[argc] = strtok(str, ARGS_DELIM);

    while (args[argc] != NULL)
    {
        if(argc >= ARGS_MAX)
           return (ARGS_MAX+1);
        args[++argc] = strtok (NULL, ARGS_DELIM);
    }

    return argc;
}

uint32_t PARSER_ParseCommand(char *str)
{
     uint32_t len = strlen(str);
     char temp_str[len];
     strcpy (temp_str, str);
     uint32_t argc = PARSER_ParseInputString(temp_str, args);
     
    if (!argc)
      return ST_PARSE_NO_ARGS;
    
    uint32_t arg_count = (argc - 1); 
    uint32_t i;
    uint32_t result;
    
    char *com = ToLower(args[0]);
    
    for (i = 0; i < sizeof(commands); i++)
    {
        //command found
        if (com_found)
            break;
        
        if (strcmp(commands[i].name,com)==0)
        {
            com_found = 1;
            
            if (arg_count < commands[i].minargs)
                return ST_PARSE_WRONG_ARGS;
            if (arg_count > commands[i].maxargs)
                return ST_PARSE_WRONG_ARGS;
            
            result = commands[i].fp(arg_count, args); 
            
            switch (result)
            {
                case MSG_OK:
                    Parser_SendString(USART2, msg_ok, print_out);
                break;
                case MSG_INV_INP:
                    Parser_SendString(USART2, msg_invinp, print_out);
                break;
                case MSG_INV_ARG:
                    Parser_SendString(USART2, msg_invarg, print_out); 
                break;
                case MSG_MIS_ARG:
                    Parser_SendString(USART2, msg_misarg, print_out); 
                break;
            }
        }
    }
    
    if (com_found)
        com_found = 0;
    else
    {
        Parser_SendString(USART2, msg_wrncom, print_out); 
        return ST_PARSE_WRONG_COM; 
    }
    
    return ST_PARSE_OK;     
}

и как это переписать на VHDL?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и как это переписать на VHDL?

Прием строки - совсем не в тему, надо читать байты из порта на аппаратном уровне, а парсер переписать без использования библиотечных функций, с побайтовым анализом.

Т.е. считан байт из порта, по его значению переходим на соответствующую ветку состояний (все команды, начинающиеся на этот байт), по следующему байту - уточняем состояние и т.д. Вот если команды не имеют явных разделителей - будет тоскливо: придется буферизировать входной поток и искать в нем требуемые последовательности, что гораздо затратнее. Почитайте про машины состояний.

И еще, после изучения и попыток написать на VHDL, возможно, придет понимание, что с встраиванием микропроцессоров в ПЛИС люди заморачиваются не от нечего делать, а для облегчения таких действий = громоздких и не требующих большого быстродействия.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прием строки - совсем не в тему, надо читать байты из порта на аппаратном уровне, а парсер переписать без использования библиотечных функций, с побайтовым анализом.

Т.е. считан байт из порта, по его значению переходим на соответствующую ветку состояний (все команды, начинающиеся на этот байт), по следующему байту - уточняем состояние и т.д. Вот если команды не имеют явных разделителей - будет тоскливо: придется буферизировать входной поток и искать в нем требуемые последовательности, что гораздо затратнее. Почитайте про машины состояний.

И еще, после изучения и попыток написать на VHDL, возможно, придет понимание, что с встраиванием микропроцессоров в ПЛИС люди заморачиваются не от нечего делать, а для облегчения таких действий = громоздких и не требующих большого быстродействия.

не всегда, иногда наоборот берут N микропроцессоров от не знания технологий FPGA

Потом мучаются с синхронизацией процессов приема/обработки/передачи данных

 

Это я и хочу. Попробовать парсить. Но я не знаю как подойти к этому вопросу на VHDL.

Для этого делают програмный протокол обмена.

Например

1 байт - синхробайт

2 байт - адрес получателя

3 байт - команда (0-255 команд в один байт можно запихнуть)

4 байт - количество данных

5-N байт - данные

N+1 байт - CRC

 

по такому Вы уже делаете автомат...

Который принимает/отправляет данные.

Для простоты желательно чтобы длина пакета была фиксированной

 

Не забываем про взаимную синхронизацию приемника и передатчка в UART.

Мое мнение лучше FTDI - SPI (не надо думать про синхронизацию)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и как это переписать на VHDL?

Это не надо переписывать на VHDL. Во-первых на Verilog :)

Во-вторых, не надо переписывать, а лучше сделать абсолютно новую реализацию.

Судя по коду, протокол простой текстовый, не вижу сложностей.

 

Только вот, можно ли взглянуть на команды и пакеты в их первозданном виде?

Еще рекомендация: для подобного парсера идеально использовать симулятор и отлаживать при помощи соответствующего тестбенча.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще рекомендация: для подобного парсера идеально использовать симулятор и отлаживать при помощи соответствующего тестбенча.

это я думаю уже понятно :)

Язык описания это всего лишь средство.... :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...