jenya7 0 14 марта, 2022 Опубликовано 14 марта, 2022 · Жалоба 12 minutes ago, fguy said: алгоритм вроде как один - разные только полиномы не знаю. если взять сгенерированный код architecture behavior of CRC16 is signal lfsr_q: std_logic_vector (15 downto 0) := (others => '1'); signal lfsr_c: std_logic_vector (15 downto 0); begin crc_out <= lfsr_q; lfsr_c(0) <= lfsr_q(8) xor lfsr_q(9) xor lfsr_q(10) xor lfsr_q(11) xor lfsr_q(12) xor lfsr_q(13) xor lfsr_q(14) xor lfsr_q(15) xor data_in(0) xor data_in(1) xor data_in(2) xor data_in(3) xor data_in(4) xor data_in(5) xor data_in(6) xor data_in(7); lfsr_c(1) <= lfsr_q(9) xor lfsr_q(10) xor lfsr_q(11) xor lfsr_q(12) xor lfsr_q(13) xor lfsr_q(14) xor lfsr_q(15) xor data_in(1) xor data_in(2) xor data_in(3) xor data_in(4) xor data_in(5) xor data_in(6) xor data_in(7); lfsr_c(2) <= lfsr_q(8) xor lfsr_q(9) xor data_in(0) xor data_in(1); lfsr_c(3) <= lfsr_q(9) xor lfsr_q(10) xor data_in(1) xor data_in(2); lfsr_c(4) <= lfsr_q(10) xor lfsr_q(11) xor data_in(2) xor data_in(3); lfsr_c(5) <= lfsr_q(11) xor lfsr_q(12) xor data_in(3) xor data_in(4); lfsr_c(6) <= lfsr_q(12) xor lfsr_q(13) xor data_in(4) xor data_in(5); lfsr_c(7) <= lfsr_q(13) xor lfsr_q(14) xor data_in(5) xor data_in(6); lfsr_c(8) <= lfsr_q(0) xor lfsr_q(14) xor lfsr_q(15) xor data_in(6) xor data_in(7); lfsr_c(9) <= lfsr_q(1) xor lfsr_q(15) xor 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) xor lfsr_q(8) xor lfsr_q(9) xor lfsr_q(10) xor lfsr_q(11) xor lfsr_q(12) xor lfsr_q(13) xor lfsr_q(14) xor lfsr_q(15) xor data_in(0) xor data_in(1) xor data_in(2) xor data_in(3) xor data_in(4) xor data_in(5) xor data_in(6) xor data_in(7); process (CLK, RST) begin if RST = '1' then lfsr_q <= (others => '1'); elsif rising_edge(CLK) then if CRC_EN = '1' then lfsr_q <= lfsr_c; end if; end if; end process; то ближайший что я нашел unsigned short crc16(const unsigned char* data_p, unsigned char length) { unsigned char x; unsigned short crc = 0xFFFF; while (length--) { x = crc >> 8 ^ *data_p++; x ^= x>>4; crc = (crc << 8) ^ ((unsigned short)(x << 12)) ^ ((unsigned short)(x <<5)) ^ ((unsigned short)x); } return crc; } как то не особо похож. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 14 марта, 2022 Опубликовано 14 марта, 2022 (изменено) · Жалоба Исполнение вашего crc16 usb в двух видах: табличное и прямое вычисление https://programmersought.com/article/84488802461/ ps. Если вы чисто для само проверки самого себя, то лучше конечно заюзать online вычислялки. Но если вам на лету надо, то да, лучше си Изменено 14 марта, 2022 пользователем new123 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 14 марта, 2022 Опубликовано 14 марта, 2022 · Жалоба 4 minutes ago, new123 said: Исполнение вашего crc16 usb в двух видах: табличное и прямое вычисление https://programmersought.com/article/84488802461/ ps. Если вы чисто для само проверки самого себя, то лучше конечно заюзать online вычислялки. Но если вам на лету надо, то да, лучше си спасибо. мне конечно без таблицы так как VHDL модуль без таблицы. мне си код нужен потому как посылка пакетов между FPGA и CPU. На стороне CPU нужен си аналог вычисления CRC. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 14 марта, 2022 Опубликовано 14 марта, 2022 · Жалоба если вы вдруг делаете из под своего драйвера в linux kernel, то там готовая функция есть crc16. Но это на всякий случай Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 14 марта, 2022 Опубликовано 14 марта, 2022 · Жалоба 22 minutes ago, jenya7 said: не знаю. если взять сгенерированный код Потому что это развернутый, чужой код. А вы могли бы сделать свой свернутый код для одного бита и применить его к байту. вот первое что попалось по руку // // G(x) = x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x1 + 1 // function bit [31:0] crc_32x1 (input bit [31:0] crc, input bit d); bit msb; begin msb = crc[31]; crc_32x1 = crc << 1; crc_32x1[ 0] = d ^ msb; crc_32x1[ 1] = d ^ msb ^ crc[ 0]; crc_32x1[ 2] = d ^ msb ^ crc[ 1]; crc_32x1[ 4] = d ^ msb ^ crc[ 3]; crc_32x1[ 5] = d ^ msb ^ crc[ 4]; crc_32x1[ 7] = d ^ msb ^ crc[ 6]; crc_32x1[ 8] = d ^ msb ^ crc[ 7]; crc_32x1[10] = d ^ msb ^ crc[ 9]; crc_32x1[11] = d ^ msb ^ crc[10]; crc_32x1[12] = d ^ msb ^ crc[11]; crc_32x1[16] = d ^ msb ^ crc[15]; crc_32x1[22] = d ^ msb ^ crc[21]; crc_32x1[23] = d ^ msb ^ crc[22]; crc_32x1[26] = d ^ msb ^ crc[25]; end endfunction // // // function bit [31:0] crc_32x8(input bit [31:0] crc, input bit [7:0] data); int i; begin crc_32x8 = crc; for (i = 8; i > 0; i--) begin crc_32x8 = crc_32x1 (crc_32x8, data[i-1]); end end endfunction Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 14 марта, 2022 Опубликовано 14 марта, 2022 (изменено) · Жалоба vhdl версия результат 0х5А82 Си версия unsigned short crc(unsigned char *ptr, int len) { unsigned int i; unsigned short crc = 0xffff; while(len--) { crc ^= *ptr++; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0xA001; else crc = (crc >> 1); } } return ~crc; } unsigned short crc_res; unsigned char crc_data[3] = {1,2,3}; crc_res = crc(crc_data, 3); результат 0х9Е9Е несостыковочка однако эта строка меняет результат crc = (crc >> 1) ^ 0xA001; откуда взялось 0xA001? ошибся. каждый клок переписывает значение. надо так но всё равно результаты разные. Изменено 14 марта, 2022 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 3 14 марта, 2022 Опубликовано 14 марта, 2022 · Жалоба 7 часов назад, jenya7 сказал: в смысле подходящий? алгоритмы передающего и принимающего должны совпадать. А каком алгоритме идет речь? Чтоб всем понятно было. Например: пример спецификации популярного варианта алгоритма "CRC 16" CRC16 стандартный: 1-1000-0000-0000-0101 Name : "CRC 16" Width : 16 Poly : 8005 x^16 + x^15 + x^2 + 1 Init : 0000 RefIn : True RefOut : True XorOut : 0000 Check : BB3D ASCII строки "123456789" (шестнадцатеричные значение "31_32_… 39"). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esokol 0 14 марта, 2022 Опубликовано 14 марта, 2022 · Жалоба 12 hours ago, jenya7 said: Начал делать Си аналог модуля - выходит как то монструозно. Сделайте сначала "в лоб", а потом уже оптимизируйте. Код выглядит примерно так (в соответствии с модулем из первого сообщения): crc16_test.c Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 15 марта, 2022 Опубликовано 15 марта, 2022 (изменено) · Жалоба 13 hours ago, sazh said: А каком алгоритме идет речь? Чтоб всем понятно было. Например: пример спецификации популярного варианта алгоритма "CRC 16" CRC16 стандартный: 1-1000-0000-0000-0101 Name : "CRC 16" Width : 16 Poly : 8005 x^16 + x^15 + x^2 + 1 Init : 0000 RefIn : True RefOut : True XorOut : 0000 Check : BB3D ASCII строки "123456789" (шестнадцатеричные значение "31_32_… 39"). Си вариант именно такой CRC algorithm name CRC-16/USB Polynomial formula x16 + x15 + x2 + 1 width 16 Polynomial 8005 Initial value FFFF Results are different or values FFFF Input reverse true Output reverse true Изменено 15 марта, 2022 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 15 марта, 2022 Опубликовано 15 марта, 2022 (изменено) · Жалоба 11 hours ago, esokol said: Сделайте сначала "в лоб", а потом уже оптимизируйте. Код выглядит примерно так (в соответствии с модулем из первого сообщения): crc16_test.c 2.63 kB · 3 downloads спасибо. так, "в лоб" результаты совпадают. unsigned short crc_res; unsigned char crc_data[3] = {1,2,3}; int main() { crc16_8(1, crc_data[0]); for (int i = 0; i < 3; i++) { crc_res = crc16_8(0, crc_data[i]); } //crc_res = 0x821D } надеюсь меня тапками не закидают на Си стороне. )) Изменено 15 марта, 2022 пользователем jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 3 16 марта, 2022 Опубликовано 16 марта, 2022 · Жалоба 15.03.2022 в 09:49, jenya7 сказал: спасибо. так, "в лоб" результаты совпадают. unsigned short crc_res; unsigned char crc_data[3] = {1,2,3}; int main() { crc16_8(1, crc_data[0]); for (int i = 0; i < 3; i++) { crc_res = crc16_8(0, crc_data[i]); } //crc_res = 0x821D } надеюсь меня тапками не закидают на Си стороне. )) Можно конечный вариант посмотреть. С тестбенчем на посылку c 8'h31 по 8'h39. ( не силен я в VHDL) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 17 марта, 2022 Опубликовано 17 марта, 2022 · Жалоба 12 hours ago, sazh said: Можно конечный вариант посмотреть. С тестбенчем на посылку c 8'h31 по 8'h39. ( не силен я в VHDL) конечный вариант Си или VHDL? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sazh 3 17 марта, 2022 Опубликовано 17 марта, 2022 · Жалоба Причем тут Си. Пошлите его по углу и по азимуту. Вам предложили инженерный подход. Без всяких калькуляторов. На базе полинома сваять сдвигающий регистр с нужными отводами по xor и отдать на откуп синтезатору байтовую реализацию входных данных. При этом ваш crc16 проект должен удовлетворять как передатчик (налету прогонять массив данных и подставлять в конце массива два байта crc), так и приемник (налету прогонять массив данных с двумя байтами crc, получая сигнатуру (которая известна и всегда одна и та же для конкретной реализации полинома). При этом после вычислений crc16 регистр должен устанавливаться за два такта в состояние ffff, чтоб не дергать его входным сигналом инициализации). //////////////////////////////////////////////////////////////////////////////////////// //G(x) = x16 + x15 + x2 + 1 //////////////////////////////////////////////////////////////////////////////////////// // Module Name = crc_16_8_usb // CRC Width = 16 // Data Width = 8 // CRC Init = ffff // RefIn = true // RefOut = true // Polynomial = 8005 // Check = B4C8 (8'h31, 8'h32....8'h39) // Check with magic world = B001 module crc_16_8_usb ( input [7:0] ibyte, input calc, input init, input clk, output [15:0] crc_rg, output [7:0] crc_check_rg, output [15:0] crc_check16 ); reg [15:0] crc_reg = 16'hffff; reg [7:0] crc_check_reg = 8'hff; wire [15:0] next_crc; ////////////////////////////////////////////////////////////////////////////// // CRC XOR equations ////////////////////////////////////////////////////////////////////////////// function [15:0] crc_16x1 (input [15:0] crc, input d); reg msb; begin msb = crc[15]; crc_16x1 = crc << 1; crc_16x1[0] = d ^ msb; crc_16x1[2] = d ^ msb ^ crc[1]; crc_16x1[15] = d ^ msb ^ crc[14]; end endfunction function [15:0] crc_16_8 (input [15:0] crc, input [7:0] data); integer i; begin crc_16_8 = crc; for (i = 0; i < 8; i= i + 1) // RefIn = true begin crc_16_8 = crc_16x1(crc_16_8, data); end end endfunction /////////////////////////////////////////////////////////////////////////////////// assign next_crc = crc_16_8(crc_reg, ibyte); always @ (posedge clk) begin if (init) begin crc_reg <= 16'hffff; crc_check_reg <= 8'hff; end else if (calc) begin crc_reg <= crc_16_8(crc_reg, ibyte); crc_check_reg <= ~{next_crc[8], next_crc[9], next_crc[10], next_crc[11], // RefOut = true next_crc[12], next_crc[13], next_crc[14], next_crc[15]}; end else begin crc_reg <= {crc_reg[7:0], 8'hff}; crc_check_reg <= ~{crc_reg[0], crc_reg[1], crc_reg[2], crc_reg[3], // RefOut = true crc_reg[4], crc_reg[5], crc_reg[6], crc_reg[7]}; end end assign crc_check_rg = crc_check_reg; ////////////////////////// genvar i; generate for (i = 0; i < 16; i = i + 1) begin : block assign crc_check16 = ~crc_reg[15-i]; // RefOut = true assign crc_rg = crc_reg[15-i]; end endgenerate /////////////////////// endmodule `timescale 1 ns / 1 ps module crc_16_8_usb_tb; parameter halfperiod_100 = 5.0; // 100 MHz reg [7:0] ibyte = 8'h00; reg calc = 1'b0; reg init = 1'b0; reg clk; wire [15:0] crc_rg; wire [7:0] crc_check_rg; wire [15:0] crc_check16; initial begin : clock_generator_100 clk = 1'b0; forever #(halfperiod_100) clk = ~clk; end initial begin repeat (4) @(posedge clk); init = 1'b1; repeat (4) @(posedge clk); init = 1'b0; repeat (4) @(posedge clk); {ibyte, calc} = {8'h31, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h32, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h33, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h34, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h35, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h36, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h37, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h38, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h39, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h00, 1'b0}; repeat (6) @(posedge clk);// Check : B4C8 {ibyte, calc} = {8'h31, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h32, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h33, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h34, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h35, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h36, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h37, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h38, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h39, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'hc8, 1'b1}; repeat (1) @(posedge clk);// Check : B4C8 {ibyte, calc} = {8'hb4, 1'b1}; repeat (1) @(posedge clk);// {ibyte, calc} = {8'h00, 1'b0}; repeat (6) @(posedge clk);// Check : 4FFE //magic world : B001 {ibyte, calc} = {8'h31, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h32, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h33, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h34, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h35, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h36, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h37, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h38, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'h39, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'hc8, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'hb4, 1'b1}; repeat (1) @(posedge clk); {ibyte, calc} = {8'hfe, 1'b1}; repeat (1) @(posedge clk);// Check : 4FFE {ibyte, calc} = {8'h4f, 1'b1}; repeat (1) @(posedge clk);// {ibyte, calc} = {8'h00, 1'b0}; repeat (6) @(posedge clk); // magic world : B001 #5 $display ("End"); $stop; end crc_16_8_usb crc_16_8_usb_inst ( .ibyte (ibyte), .calc (calc), .init (init), .clk (clk), .crc_rg (crc_rg), .crc_check_rg (crc_check_rg), .crc_check16 (crc_check16) ); endmodule Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться