|
uart verilog |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 18)
|
Oct 22 2013, 21:31
|
Частый гость
 
Группа: Свой
Сообщений: 106
Регистрация: 11-11-10
Из: Санкт-Петербург
Пользователь №: 60 826

|
Может быть подойдёт Verilog UART с opencores? ссылка - http://opencores.org/project,osdvu, для скачивания без регистрации можно перейти по ссылке "SVN: Browse" и перейти в папку trunk.
|
|
|
|
|
Oct 23 2013, 04:38
|
Группа: Участник
Сообщений: 11
Регистрация: 28-01-13
Пользователь №: 75 381

|
как передавать по uart 18битные данные? Я так понимаю нужен какой-то буфер, который будет принимать три 8битных слова с uart и выдавать на выход по 18бит?
|
|
|
|
|
Oct 23 2013, 05:20
|
Частый гость
 
Группа: Свой
Сообщений: 127
Регистрация: 2-09-11
Из: Москва
Пользователь №: 66 970

|
Я как-то использовал модули отсюда: http://www.fpga4fun.com/SerialInterface.htmlВот еще ссылка прямая: http://www.fpga4fun.com/files/async.zipЗаработало с пол тычка. А насчет второго: ну да, передавать 3 слова, еще даже по 2 бита на слово лишних останется, можно вставить флаг какое это слово, проверку ну или уплотнить данные.
|
|
|
|
|
Oct 23 2013, 07:31
|
Группа: Участник
Сообщений: 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 бита на слово лишних останется, можно вставить флаг какое это слово, проверку ну или уплотнить данные. а есть какие-нибудь примеры подобных решений? или как это вообще называется? для поиска
|
|
|
|
|
Oct 23 2013, 10:00
|
Местный
  
Группа: Свой
Сообщений: 310
Регистрация: 28-01-13
Из: Лондон
Пользователь №: 75 384

|
Сначала определитесь, хотите ли уарт, по которому будут ходить 18-битные данные, или просто последовательный интерфейс с 18-битным словом. В первом случае есть совместимость с любым уартом, данные жестко 8-битные со старт-стоп битами. Самый простой способ(но не самый эффективный): В каждом переданном байте первых 2 бита заголовок, который может быть 1,2 или 3. Остальные 6 бит данные. Приёмник вынимает байт из буфера, заголовок идёт на мультиплексер, который запихивает 6 бит данных в начало, середину или конец длинного регистра. При каждом получении 3-ей части выставляем строб "Data ready". Если же нужен просто последовательный интерфейс с 18-битным словом то модифицируем вышеприведенный код уарта так, чтобы отправлял 18-битные посылки вместо 8-битных. Несовместим с другими стандартами, но самый эффективный по скорости передачи и простоте интерфейса.
|
|
|
|
|
Oct 23 2013, 11:59
|
Группа: Участник
Сообщений: 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
|
|
|
|
|
Oct 23 2013, 17:22
|
Местный
  
Группа: Свой
Сообщений: 301
Регистрация: 18-09-07
Из: Украина
Пользователь №: 30 647

|
Добрый день. Посмотрите, может понравится. Удачи.
|
|
|
|
|
Oct 31 2013, 10:16
|
Гуру
     
Группа: Свой
Сообщений: 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 //---------------------------------------------------------------------// //---------------------------------------------------------------------//
|
|
|
|
|
Oct 31 2013, 16:56
|
Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 30-12-04
Пользователь №: 1 761

|
Цитата(sergey sva @ Oct 31 2013, 14:16)  CRC Должно получиться при проходе по шине из 8 байт с значением 00 = 0x0B40. А получается 0x02d0 Код не смотрел, заметил, что если прочитать 0x0B40 задом на перед, то получается 0x02D0...
|
|
|
|
|
Nov 4 2013, 16:20
|
Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
|
Nov 5 2013, 06:30
|
Местный
  
Группа: Свой
Сообщений: 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 И старайтесь указывать везде разрядности. Полезная привычка..
|
|
|
|
|
Nov 8 2013, 11:58
|
Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|