реклама на сайте
подробности

 
 
> uart verilog
sergey sva
сообщение Oct 22 2013, 21:04
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923



Нужен uart с двумя сигналами rx tx , понимаю что не сложно сделать, может есть готовый? дайте ссылочку пожалуйста.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 18)
aT-DeviLru
сообщение Oct 22 2013, 21:31
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 106
Регистрация: 11-11-10
Из: Санкт-Петербург
Пользователь №: 60 826



Может быть подойдёт Verilog UART с opencores? ссылка - http://opencores.org/project,osdvu, для скачивания без регистрации можно перейти по ссылке "SVN: Browse" и перейти в папку trunk.
Go to the top of the page
 
+Quote Post
count_enable
сообщение Oct 22 2013, 21:31
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 310
Регистрация: 28-01-13
Из: Лондон
Пользователь №: 75 384



На opencores.org их как грязи, если надо стандартный то Xilinx IPcore а для студента то здесь всё разжевано http://we.easyelectronics.ru/plis/ocheredn...ke-verilog.html .


Сообщение отредактировал count_enable - Oct 22 2013, 22:07
Go to the top of the page
 
+Quote Post
filo
сообщение Oct 23 2013, 04:38
Сообщение #4





Группа: Участник
Сообщений: 11
Регистрация: 28-01-13
Пользователь №: 75 381



как передавать по uart 18битные данные? Я так понимаю нужен какой-то буфер, который будет принимать три 8битных слова с uart и выдавать на выход по 18бит?
Go to the top of the page
 
+Quote Post
Swup
сообщение Oct 23 2013, 05:20
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 127
Регистрация: 2-09-11
Из: Москва
Пользователь №: 66 970



Я как-то использовал модули отсюда:
http://www.fpga4fun.com/SerialInterface.html
Вот еще ссылка прямая: http://www.fpga4fun.com/files/async.zip
Заработало с пол тычка.



А насчет второго: ну да, передавать 3 слова, еще даже по 2 бита на слово лишних останется, можно вставить флаг какое это слово, проверку ну или уплотнить данные.
Go to the top of the page
 
+Quote Post
filo
сообщение Oct 23 2013, 07:31
Сообщение #6





Группа: Участник
Сообщений: 11
Регистрация: 28-01-13
Пользователь №: 75 381



Цитата(Swup @ Oct 23 2013, 08:20) *
Я как-то использовал модули отсюда:
http://www.fpga4fun.com/SerialInterface.html
Вот еще ссылка прямая: http://www.fpga4fun.com/files/async.zip
Заработало с пол тычка.



А насчет второго: ну да, передавать 3 слова, еще даже по 2 бита на слово лишних останется, можно вставить флаг какое это слово, проверку ну или уплотнить данные.

а есть какие-нибудь примеры подобных решений? или как это вообще называется? для поиска
Go to the top of the page
 
+Quote Post
count_enable
сообщение Oct 23 2013, 10:00
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 310
Регистрация: 28-01-13
Из: Лондон
Пользователь №: 75 384



Сначала определитесь, хотите ли уарт, по которому будут ходить 18-битные данные, или просто последовательный интерфейс с 18-битным словом. В первом случае есть совместимость с любым уартом, данные жестко 8-битные со старт-стоп битами. Самый простой способ(но не самый эффективный): В каждом переданном байте первых 2 бита заголовок, который может быть 1,2 или 3. Остальные 6 бит данные.
Приёмник вынимает байт из буфера, заголовок идёт на мультиплексер, который запихивает 6 бит данных в начало, середину или конец длинного регистра. При каждом получении 3-ей части выставляем строб "Data ready".
Если же нужен просто последовательный интерфейс с 18-битным словом то модифицируем вышеприведенный код уарта так, чтобы отправлял 18-битные посылки вместо 8-битных. Несовместим с другими стандартами, но самый эффективный по скорости передачи и простоте интерфейса.
Go to the top of the page
 
+Quote Post
iosifk
сообщение Oct 23 2013, 10:57
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(count_enable @ Oct 23 2013, 14:00) *
Если же нужен просто последовательный интерфейс с 18-битным словом то модифицируем вышеприведенный код уарта так, чтобы отправлял 18-битные посылки вместо 8-битных. Несовместим с другими стандартами, но самый эффективный по скорости передачи и простоте интерфейса.


Но при этом надо делать точное согласование по частоте. А стандартный СОМ может этого не понять...
Вообще лучше не изобретать кривые протоколы, когда есть Wake...


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
filo
сообщение Oct 23 2013, 11:59
Сообщение #9





Группа: Участник
Сообщений: 11
Регистрация: 28-01-13
Пользователь №: 75 381



Цитата(count_enable @ Oct 23 2013, 13:00) *
Сначала определитесь, хотите ли уарт, по которому будут ходить 18-битные данные, или просто последовательный интерфейс с 18-битным словом. В первом случае есть совместимость с любым уартом, данные жестко 8-битные со старт-стоп битами. Самый простой способ(но не самый эффективный): В каждом переданном байте первых 2 бита заголовок, который может быть 1,2 или 3. Остальные 6 бит данные.
Приёмник вынимает байт из буфера, заголовок идёт на мультиплексер, который запихивает 6 бит данных в начало, середину или конец длинного регистра. При каждом получении 3-ей части выставляем строб "Data ready".
Если же нужен просто последовательный интерфейс с 18-битным словом то модифицируем вышеприведенный код уарта так, чтобы отправлял 18-битные посылки вместо 8-битных. Несовместим с другими стандартами, но самый эффективный по скорости передачи и простоте интерфейса.

спасибо за ответ.
вообще планировалось использовать стандартный RS-232.

Сообщение отредактировал filo - Oct 23 2013, 12:00
Go to the top of the page
 
+Quote Post
sergey sva
сообщение Oct 23 2013, 15:47
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923



Спасибо и правда сразу заработало sm.gif
Нужен генератор црц 16 который в модбус рту используется, набрел на такой сайт он позволяет генерировать код, но как написано не очень нравиться, может есть более оптимальные, желательно что бы не много занимал ресурсов.
Go to the top of the page
 
+Quote Post
Andrew Su
сообщение Oct 23 2013, 17:22
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 301
Регистрация: 18-09-07
Из: Украина
Пользователь №: 30 647



Добрый день.
Посмотрите, может понравится.
Удачи.
Прикрепленные файлы
Прикрепленный файл  ultimate_crc_latest.tar.gz ( 226.91 килобайт ) Кол-во скачиваний: 28
 
Go to the top of the page
 
+Quote Post
sergey sva
сообщение Oct 31 2013, 10:16
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923



Столкнулся с проблемой, никак не разберусь почему CRC код не совпадает. Взял пример сгенерированный http://outputlogic.com/ пробовал с разными полиномами 1+x^2+x^15+x^16; и 1+x^13+x^15+x^16;
Получается не такой результат какой должен быть.
Думал что ошибся в направлении прохода сделал все сигналы 00,00,00,00,00,00,00,00. Подумал что ошибся с количеством, вывел переменную countbytes, все правильно в ней 8.
CRC Должно получиться при проходе по шине из 8 байт с значением 00 = 0x0B40. А получается 0x02d0

Код
// Copyright (C) 2009 OutputLogic.com
// This source file may be used and distributed without restriction
// provided that this copyright statement is not removed from the file
// and that any derivative work contains the original copyright notice
// and the associated disclaimer.
//
// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED    
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//-----------------------------------------------------------------------------
// CRC module for data[7:0] ,   crc[15:0]=1+x^2+x^15+x^16;
//-----------------------------------------------------------------------------

module CRC( data_in, crc_en, crc_out,rst, clk, countbytes);
//---------------------------------------------------------------------//
//---------------------------------------------------------------------//
input [7:0] data_in;
input crc_en,rst, clk;
output [15:0] crc_out;
output[7:0] countbytes;
//---------------------------------------------------------------------//
//---------------------------------------------------------------------//
  reg [15:0] lfsr_q,lfsr_c;
  reg [7:0] countbytes_reg;
//---------------------------------------------------------------------//
//---------------------------------------------------------------------//
  assign crc_out = lfsr_q;
  assign countbytes = countbytes_reg;
//---------------------------------------------------------------------//
//---------------------------------------------------------------------//

  assign crc_out = lfsr_q;

  always @(posedge clk, posedge rst) begin
    if(rst) begin
      lfsr_q = {16{1'b1}};
        countbytes_reg = 0;
    end
    else begin
    
        if(crc_en)
        begin        
            lfsr_c[0] = lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[12] ^ lfsr_q[13] ^ lfsr_q[14] ^ lfsr_q[15] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7];
            lfsr_c[1] = lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[12] ^ lfsr_q[13] ^ lfsr_q[14] ^ lfsr_q[15] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7];
            lfsr_c[2] = lfsr_q[8] ^ lfsr_q[9] ^ data_in[0] ^ data_in[1];
            lfsr_c[3] = lfsr_q[9] ^ lfsr_q[10] ^ data_in[1] ^ data_in[2];
            lfsr_c[4] = lfsr_q[10] ^ lfsr_q[11] ^ data_in[2] ^ data_in[3];
            lfsr_c[5] = lfsr_q[11] ^ lfsr_q[12] ^ data_in[3] ^ data_in[4];
            lfsr_c[6] = lfsr_q[12] ^ lfsr_q[13] ^ data_in[4] ^ data_in[5];
            lfsr_c[7] = lfsr_q[13] ^ lfsr_q[14] ^ data_in[5] ^ data_in[6];
            lfsr_c[8] = lfsr_q[0] ^ lfsr_q[14] ^ lfsr_q[15] ^ data_in[6] ^ data_in[7];
            lfsr_c[9] = lfsr_q[1] ^ lfsr_q[15] ^ data_in[7];
            lfsr_c[10] = lfsr_q[2];
            lfsr_c[11] = lfsr_q[3];
            lfsr_c[12] = lfsr_q[4];
            lfsr_c[13] = lfsr_q[5];
            lfsr_c[14] = lfsr_q[6];
            lfsr_c[15] = lfsr_q[7] ^ lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[12] ^ lfsr_q[13] ^ lfsr_q[14] ^ lfsr_q[15] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7];

            countbytes_reg = countbytes_reg +1;    
            lfsr_q  = lfsr_c;
        end
        else begin
        
            lfsr_q  = lfsr_q;
        end    
            
      
    end
  end // always



endmodule // crc
//---------------------------------------------------------------------//
//---------------------------------------------------------------------//
Go to the top of the page
 
+Quote Post
Zig
сообщение Oct 31 2013, 16:56
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 185
Регистрация: 30-12-04
Пользователь №: 1 761



Цитата(sergey sva @ Oct 31 2013, 14:16) *
CRC Должно получиться при проходе по шине из 8 байт с значением 00 = 0x0B40. А получается 0x02d0

Код не смотрел, заметил, что если прочитать 0x0B40 задом на перед, то получается 0x02D0...
Go to the top of the page
 
+Quote Post
sergey sva
сообщение Oct 31 2013, 19:23
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923



Сейчас проверю может в направлениях сигналов ошибся. Еще такой вопрос уарт должен принимать пакет из 64 байт как правильнее отследить конец начала пакета? Думаю сделать так устройство которое посылает пакет помещает в 0 байт символ $ и передает весь пакет в плис(64 байта).
Плис получает сигнал от модуля уарта, о том что пришел байт. каждый раз как приходит байт обнуляется счетчик, как только какое то время байты не поступают счетчик переполняется, проверяется 0 байт если там есть "$" , устанавливается сигнал пакет получен. У модуля уарт есть еще сигнал is_receive можно еще по нему отслеживать конец. Как правильнее реализовать такое может есть примеры. или просто на словах.
Go to the top of the page
 
+Quote Post
sergey sva
сообщение Nov 4 2013, 16:20
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923



Пробовал реверс бит результат не совпадает (. С разными полиномами пробовал a001 8005.
Проверяю значения 0x24 0x08 0x00 0x00 0x00 0x00 CRC должно получиться 0x3EE7 а у меня 0x24d6, где ошибка ума нет. проверял на калькуляторе http://www.lammertbies.nl/comm/info/crc-calculation.html подскажите что нибудь?
Код
//-----------------------------------------------------------------------------
// Copyright (C) 2009 OutputLogic.com
// This source file may be used and distributed without restriction
// provided that this copyright statement is not removed from the file
// and that any derivative work contains the original copyright notice
// and the associated disclaimer.
//
// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED    
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//-----------------------------------------------------------------------------
// CRC module for data[7:0] ,   crc[15:0]=1+x^13+x^15+x^16;
//-----------------------------------------------------------------------------
module crc_modbus(
  input [7:0] data_in,
  input crc_en,
  output [15:0] crc_out,
  input rst,
  input clk);

  reg [15:0] lfsr_q,lfsr_c;

  assign crc_out = lfsr_q;

  always @(*) begin
    lfsr_c[0] = lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[12] ^ lfsr_q[15] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[7];
    lfsr_c[1] = lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[13] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5];
    lfsr_c[2] = lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[12] ^ lfsr_q[14] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6];
    lfsr_c[3] = lfsr_q[11] ^ lfsr_q[12] ^ lfsr_q[13] ^ lfsr_q[15] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7];
    lfsr_c[4] = lfsr_q[12] ^ lfsr_q[13] ^ lfsr_q[14] ^ data_in[4] ^ data_in[5] ^ data_in[6];
    lfsr_c[5] = lfsr_q[13] ^ lfsr_q[14] ^ lfsr_q[15] ^ data_in[5] ^ data_in[6] ^ data_in[7];
    lfsr_c[6] = lfsr_q[14] ^ lfsr_q[15] ^ data_in[6] ^ data_in[7];
    lfsr_c[7] = lfsr_q[15] ^ data_in[7];
    lfsr_c[8] = lfsr_q[0];
    lfsr_c[9] = lfsr_q[1];
    lfsr_c[10] = lfsr_q[2];
    lfsr_c[11] = lfsr_q[3];
    lfsr_c[12] = lfsr_q[4];
    lfsr_c[13] = lfsr_q[5] ^ lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[12] ^ lfsr_q[15] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[7];
    lfsr_c[14] = lfsr_q[6] ^ lfsr_q[9] ^ lfsr_q[10] ^ lfsr_q[11] ^ lfsr_q[13] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5];
    lfsr_c[15] = lfsr_q[7] ^ lfsr_q[8] ^ lfsr_q[9] ^ lfsr_q[11] ^ lfsr_q[14] ^ lfsr_q[15] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[6] ^ data_in[7];

  end // always

  always @(posedge clk, posedge rst) begin
    if(rst) begin
      lfsr_q <= {16{1'b1}};
    end
    else begin
      lfsr_q <= crc_en ? lfsr_c : lfsr_q;
    end
  end // always
endmodule // crc
Go to the top of the page
 
+Quote Post
Джеймс
сообщение Nov 5 2013, 06:30
Сообщение #16


Местный
***

Группа: Свой
Сообщений: 462
Регистрация: 20-01-06
Пользователь №: 13 399



Код
always @(posedge clk, posedge rst) begin
    if(rst) begin
      lfsr_q <= {16{1'b1}};
    end
    else begin
      lfsr_q <= crc_en ? lfsr_c : lfsr_q;
    end
  end // always


А сброс (rst) подается?
И здесь вообще говоря должен быть не только сброс при включении питания, поскольку так модуль отработает только один раз.

always @(posedge clk or posedge rst)
begin
if(rst) // power-up reset
lfsr_q[15:0] <= 16'hFFFF;
else
if (NEW_CRC)
lfsr_q[15:0] <= 16'hFFFF; // start new crc calculation
else
if (crc_en)
lfsr_q[15:0] <= lfsr_c[15:0];
end

И старайтесь указывать везде разрядности. Полезная привычка..
Go to the top of the page
 
+Quote Post
sergey sva
сообщение Nov 7 2013, 11:02
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923



Может я что то не правильно понимаю для подсчета crc для Modbus RTU используется полином 0xA001 ? Для генерации кода если использовать сервисе http://outputlogic.com/?page_id=321 нужно выбрать
Прикрепленное изображение

После его использовать по такому алгоритму: Модуль uart ждет получения байта и держит crc в сбросе, как байт получен он поступает на datain снимаеться сигнал reset и устанавливает сигнал crccloc.
Следующей такт снимает crcclok. как следующий байт поступает опять ставиться crcclok и так пока весь пакет не будет получен. когда количество полученных байт соответствует, результат crc готов.
Go to the top of the page
 
+Quote Post
sergey sva
сообщение Nov 7 2013, 15:54
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923



...
Go to the top of the page
 
+Quote Post
sergey sva
сообщение Nov 8 2013, 11:58
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923



Блин ничего не понимаю, в чем я ошибся, или что то совсем ничего не понимаю, вроде такая простая вещь а не работает как нужно (.
Весь подсчет разбил что бы было удобнее искать проблему, но ничего так и не нашел. Взял проверенный алгоритм на C#
Код
        {
            int crc = 0xFFFF;
            byte[] msg = new byte[6];
            msg[0] = 0x24;
            msg[1] = 0x08;
            msg[2] = 0x00;
            msg[3] = 0x00;
            msg[4] = 0x00;
            msg[5] = 0x00;

            for (int j = 0; j < 6; j++)
            {
              

                crc = crc ^ msg[j];

                for (int i = 0; i < 8; i++)
                {

                    bool ff =  (crc & 1)==1;
                    crc = crc >> 1;

                    if (ff)
                    {
                        crc = crc ^ 0xA001;
                    }                    

                }
              
            }
        }

Результат получается правильный 0X3EE7.
Переписал практически один в один под Verilog, обмен с модулем crc_mobus проверил 10 раз все работает.
Результат правильный но сдвинут 0X003E. Почему так получается куда смотреть уже мыслей нет.
Код
//---------------------------------------------------------------------//
//---------------------------------------------------------------------//
module crc_mobus(input clck, input datacrcini,input datacrcnew, input[7:0]datain, output[15:0] crcout, output crcrd);
//---------------------------------------------------------------------//
//---------------------------------------------------------------------//
reg[15:0] countcrc      = 0;
reg[3:0] counterbytes   = 0;
reg[3:0] statucountcrc  = 0;

reg crcrdy     = 0;
reg loaddata   = 0;
reg bitlsb     = 0;
//---------------------------------------------------------------------//
//---------------------------------------------------------------------//
always @(posedge clck)
begin
    if(datacrcini)
    begin
        
        crcrdy          = 0;
        loaddata        = 0;
        statucountcrc   = 0;
        counterbytes    = 0;    
        countcrc[15:0]  = 16'b1111111111111111;
    end
    else if(datacrcnew) begin    
        if(loaddata == 0)
        begin
            loaddata      = 1;    
            crcrdy        = 0;
            counterbytes  = 0;                        
            countcrc[15:0] = {8'b00000000,datain[7:0]} ^countcrc[15:0];
            statucountcrc = 0;
        end
    end
    else begin        
        
        if(counterbytes < 8)
        begin
        
            case(statucountcrc)
            0:
            begin
                bitlsb = countcrc[0];
                statucountcrc = 1;
            end
            
            1:
            begin    
                countcrc  = countcrc>>1;                
                statucountcrc = 2;
            end
            
            2:
            begin
                if(bitlsb)
                begin
                    countcrc = countcrc ^ 16'b 1010000000000001;
                end                
                counterbytes  = counterbytes +1;
                statucountcrc = 0;                
            end
            
            default:
            begin
                statucountcrc = 0;
            end
            endcase    
            
        end
        else begin                
            crcrdy = 1;
            loaddata = 0;
        end
        
    end
    
end
//---------------------------------------------------------------------//
//---------------------------------------------------------------------//

assign crcout = countcrc;
assign crcrd  = crcrdy;
    
endmodule
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th June 2025 - 15:36
Рейтинг@Mail.ru


Страница сгенерированна за 0.01594 секунд с 7
ELECTRONIX ©2004-2016