flammmable 0 5 октября, 2020 Опубликовано 5 октября, 2020 (изменено) · Жалоба Пытаюсь написать модуль, раcсчитывающий CRC. Для вычисления CRC применяется сдвиговый регистр с обратной связью (LFSR). Причем сам процесс вычисления может быть полностью последовательным, с двумя вложенными циклами (такое реализуется в микроконтроллерах), последовательно-параллельным (сам LFSR выполнен из логики, но его нужно последовательно сдвигать на количество бит шины данных) и полностью параллельным (CRC вычисляется за один такт). Для полностью параллельного вычислителя CRC есть некоторое количество генераторов типа этого, однако код жестко привязывается к параметрам CRC (например "CRC-16 modbus"). Я хотел бы написать на чистом Верилоге полностью параметризованный код вычислителя CRC. Для LFSR отлично подходит синтаксис цикла "for": module main #( parameter LFSR_SIZE = 16, parameter START_VALUE = 'hFFFF, parameter POLYNOME = 'h8005) ( input clk, input n_reset, output reg [LFSR_SIZE-1:0]lfsr); integer lfsr_index; always @(posedge clk) begin if(n_reset) begin lfsr[0] <= lfsr[LFSR_SIZE - 1]; for(lfsr_index = 1; lfsr_index < LFSR_SIZE; lfsr_index = lfsr_index + 1) begin if( ((1 << lfsr_index) & POLYNOME) == 0) begin lfsr[lfsr_index] <= lfsr[lfsr_index - 1]; end else begin lfsr[lfsr_index] <= lfsr[lfsr_index - 1] ^ lfsr[LFSR_SIZE - 1]; end end end else begin lfsr <= START_VALUE; end end endmodule Однако у меня не получается придумать, как при помощи дополнительного цикла внедрить сдвиг LFSR на какое-либо количество бит. Подойдет ли здесь вообще конструкция со вложенными циклами? Если нет, то применяются ли где-нибудь вложенные циклы в Verilog? P.S. Electronix.ru - приличное место, но всё же и здесь могут быть первонахи, которые расскажут, что "цикл в HDL - это не тоже самое, что в Си" вместо собственно ответа. Так вот. Я осознаю, что циклы в Verilog не выполняются последовательно, а создают нечто, имеющее регулярную, повторяющуюся структуру. Изменено 5 октября, 2020 пользователем flammmable Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба https://electronix.ru/forum/index.php?app=forums&module=forums&controller=topic&id=64560 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 0 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба 7 minutes ago, des00 said: https://electronix.ru/forum/index.php?app=forums&module=forums&controller=topic&id=64560 Это я безусловно прочитал. Но в ваших примерах: 1) полином задается не шестнадцатеричным числом, а несколькими строками кода. 2) используются функции. Хотелось бы: 1) задавать полином шестнадцатеричным числом. 2) не использовать функции. 2) использовать вложенные циклы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба 7 minutes ago, flammmable said: Хотелось бы: 1) задавать полином шестнадцатеричным числом. 2) не использовать функции. 2) использовать вложенные циклы. ну и в чем проблема тогда, если читали? 1. crc16x1[0] = d ^ msb; crc16x1[5] = d ^ msb ^ crc[4]; crc16x1[12] = d ^ msb ^ crc[11]; соберите в одну строку crc16x1 ^= {16{d ^ msb}} & poly[15 : 0]; 2,3 разверните функции, пару копипастов и все. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 0 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба 1 minute ago, des00 said: ну и в чем проблема тогда, если читали? 1. crc16x1[0] = d ^ msb; crc16x1[5] = d ^ msb ^ crc[4]; crc16x1[12] = d ^ msb ^ crc[11]; соберите в одну строку crc16x1 ^= {16{d ^ msb}} & poly[15 : 0]; 2,3 разверните функции, пару копипастов и все. Проблема в разворачивании функций. Я не могу сообразить, как их развернуть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба 13 minutes ago, flammmable said: Проблема в разворачивании функций. Я не могу сообразить, как их развернуть. эмм, ну начать можно с вариантa в лоб и простого копипаста always_ff @(posedge iclk) begin logic msb; logic [15 : 0] crc16xW; logic [15 : 0] crc16x1; if (iena) begin crc16xW = crc; for (int i = 0; i < 16; i++) begin msb = crc16xW [15]; crc16x1 = (crc16xW << 1); crc16x1 ^= {16{d[i] ^ msb}} & poly[15 : 0]; crc16xW = crc16x1; end crc <= crc16xW; end end только цикл тут один. т.к. запись в строку, хотите вложенный, разгребайте полином по битно. а дальше, оптимизируйте как хотите, вплоть до описания в одну строку тела цикла Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба 1 hour ago, flammmable said: always @(posedge clk) begin if(n_reset) begin lfsr[0] <= lfsr[LFSR_SIZE - 1]; for(lfsr_index = 1; lfsr_index < LFSR_SIZE; lfsr_index = lfsr_index + 1) begin if( ((1 << lfsr_index) & POLYNOME) == 0) begin lfsr[lfsr_index] <= lfsr[lfsr_index - 1]; end else begin lfsr[lfsr_index] <= lfsr[lfsr_index - 1] ^ lfsr[LFSR_SIZE - 1]; end end end За такое я бы уже пальцы в дверь зажимал. Вы вообще понимаете, что такое ресет и почему нельзя логику пихать в состояние ресета? Второй момент, если хочется что-то этакое замутить - вынесите в функцию. И читать проще и потом редактировать. 1 hour ago, flammmable said: Подойдет ли здесь вообще конструкция со вложенными циклами? Если нет, то применяются ли где-нибудь вложенные циклы в Verilog? И вложенные и циклы под generate, можно всё что угодно, только правильно. И как я сказал ранее - вынесите в функцию. Вы будете удивлены, но функции для HDL и функции в Си имеют намного больше общего, чем различий (за исключением статик-автоматик). На последок, что такое "Хочу задавать полином шеснадцетеричным числом"? Это типа я программист и мне впадло разбираться? Ну или код для оных. Если очень хочется оставить совместимость, можно накрутить через макросы. Непонятно что за зверёк получится, но вполне вероятно даже будет работать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба Приветствую! 17 minutes ago, Nick_K said: За такое я бы уже пальцы в дверь зажимал. Вы вообще понимаете, что такое ресет и почему нельзя логику пихать в состояние ресета? Чет то вы уж больно агрессивны категоричны. При чем тут состояние reset? С точки зрения языка никто не запрещает писать always @(posedge clk) begin if (reset) bgin // reset state end else begin // work state end if (~reset) bgin // work state end else begin // reset state end end Ну да - немного не по фэншую как у классиков, как и вариант always @(posedge clk) begin // work state ... if (reset) begin // reset state end end Но чтоб сразу пальцы в дверь ... Чем же потом код править? Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 0 5 октября, 2020 Опубликовано 5 октября, 2020 (изменено) · Жалоба 3 hours ago, des00 said: эмм, ну начать можно с вариантa в лоб и простого копипаста always_ff @(posedge iclk) begin logic msb; logic [15 : 0] crc16xW; logic [15 : 0] crc16x1; if (iena) begin crc16xW = crc; for (int i = 0; i < 16; i++) begin msb = crc16xW [15]; crc16x1 = (crc16xW << 1); crc16x1 ^= {16{d[i] ^ msb}} & poly[15 : 0]; crc16xW = crc16x1; end crc <= crc16xW; end end только цикл тут один. т.к. запись в строку, хотите вложенный, разгребайте полином по битно. а дальше, оптимизируйте как хотите, вплоть до описания в одну строку тела цикла crc16x1 ^= {16{d[i] ^ msb}} & poly[15 : 0]; Предположим, что d[] у нас всегда 0 или что его вообще нет. Тогда:crc16x1 = crc16x1 ^ (16{msb} & poly[15 : 0]); Предположим, что msb равен 1 Тогда:(16{msb} & poly[15 : 0]) равен poly[15 : 0] иcrc16x1 = crc16x1 ^ poly[15 : 0]; Предположим, что msb равен 0 Тогда:(16{msb} & poly[15 : 0]) равен 0 иcrc16x1 = crc16x1 ^ 0; Мммм. Не похоже на обратную связь LFSR. Кроме того, в чистом Верилоге нет logic-а. Если писать на чистом Верилоге, msb, crc16x1 и crc16xW будут reg или wire? 2 hours ago, RobFPGA said: Чет то вы уж больно агрессивны категоричны. При чем тут состояние reset? С точки зрения языка никто не запрещает писать Мне кажется, он не заметил инверсию ресета (n_reset). Зато возместил недостаток внимательности избытком пафоса )))) Изменено 5 октября, 2020 пользователем flammmable Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба Приветствую! 47 minutes ago, flammmable said: Предположим, что d[] у нас всегда 0 или что его вообще нет. Тогда: ... Мммм. Не похоже на LFSR, не? Если уж считаете в уме то считайте весь алгоритм а не только серединку - сдвиг в строке чуть выше : crc16x1 = (crc16xW << 1); Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 0 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба 19 minutes ago, RobFPGA said: Приветствую! Если уж считаете в уме то считайте весь алгоритм а не только серединку - сдвиг в строке чуть выше : crc16x1 = (crc16xW << 1); Удачи! Rob. Сдвиг-то есть, а вот обратная связь какая-то уж очень неизбирательная получается. В любом случае, спасибо des00, я разобрался, как сделать полностью параметризуемый параллельный CRC двумя циклами. Завтра причешу тестбенч и имена переменных (чтобы было не так стыдно) и выложу. В Моделсиме всё работает. По проверке в железе постараюсь также отписаться, если не забуду. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба 56 minutes ago, flammmable said: Сдвиг-то есть, а вот обратная связь какая-то уж очень неизбирательная получается. вообще такой стиль не рекомендуется. А именно смешивание в одном процессе блокирующего и неблокирующего присваивания, многие lint средства ругаются когда видят такой код, а так, разбиение на комбинационный и регистровый процесс и уже в комбинационном можно использовать обычный "программистский" стиль описания, переменные будут хранить свое состояние от итерации к итерации. Современные средства синтеза настолько хороши, что можно даже сложный код не разбивать на мелкие сущности, все зависит от алгоритма) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба 3 hours ago, flammmable said: Мне кажется, он не заметил инверсию ресета (n_reset). Зато возместил недостаток внимательности избытком пафоса )))) При чём тут пафос? Я говорю, что писать нужно по общепринятым правилам и стилистике. С Вашим инверсным ресетом, который не ресет, тулу будет сложно определить - это комбинационная схема на входе в ресет или это нормальное состояние. И хорошо, если он разберёт тут ибо логики не много. А когда смотришь иногда тысячестрочные коды и там меньшие ошибки, а синтезируется чёрт и что, за такое пристрелить хочется. Приучите себя писать правильно и, что не маловажно, понятно для других разработчиков. Это как минимум уважение, а как максимум может избавить от очень больших проблем в будущем. 4 hours ago, RobFPGA said: Ну да - немного не по фэншую как у классиков, как и вариант always @(posedge clk) begin // work state ... if (reset) begin // reset state end end Но чтоб сразу пальцы в дверь ... Чем же потом код править? Кстати у меня вот такие конструкции недавно и нагенерили латчей. Точнее там всего один латч был, но провозился я с ним знатно. Дня три наверное Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба Приветствую! 21 minutes ago, Nick_K said: С Вашим инверсным ресетом, который не ресет, тулу будет сложно определить - это комбинационная схема на входе в ресет или это нормальное состояние Синтезаторы уже дано на такое не обращают внимание. При синхронном ресете бывает надо еще и постараться (через атрибуты) чтобы синтезатор использовал выделенный reset регистра, а не комбинировал логику сброса в обычный LUT. 21 minutes ago, Nick_K said: Кстати у меня вот такие конструкции недавно и нагенерили латчей. Точнее там всего один латч был, но провозился я с ним знатно. Дня три наверное Такие!? или все же под каким-нибудь always(*) ? Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба 51 minutes ago, RobFPGA said: Такие!? или все же под каким-нибудь always(*) ? Именно такие. Там весь прикол ,что в одном из стейтов внутри if-а не был задействован объявленный сигнал. Вот и генерился латч. Где-то так: always @(clk) begin net1 <= '0; net2 <= '0; if (reset) begin net1 <= '0; net2 <= '0; end else begin case (net3) 2'b00: begin net1 <= '0; net2 <= '0; end 2'b01: begin net1 <= 2'b01; net2 <= 2'b10; end 2'b10: begin net1 <= 2'b10; end default: begin net1 <= 2'b00; net2 <= 2'b01; end end end Или без дефолта, я уже точно не помню. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться