RobFPGA 27 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба Приветствую! 1 minute ago, Nick_K said: always @(clk) begin ??? Удивительно что только один латч Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба 1 hour ago, RobFPGA said: Удивительно что только один латч А сори, опечатка. Там нормально всё было кроме одного состояния кейса. Это я когда писал под вечер уже невнимательный стал) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 27 5 октября, 2020 Опубликовано 5 октября, 2020 · Жалоба Приветствую! 24 minutes ago, Nick_K said: А сори, опечатка. Там нормально всё было кроме одного состояния кейса. Это я когда писал под вечер уже невнимательный стал) Тогда тем более непонятно как при чисто синхронном always @(posedge clk) можно сгенерить латч? Удачи! Rob. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nick_K 0 6 октября, 2020 Опубликовано 6 октября, 2020 · Жалоба 8 hours ago, RobFPGA said: Тогда тем более непонятно как при чисто синхронном always @(posedge clk) можно сгенерить латч? Наличие дефолтного состояния подсказало синтезатору. Не забывайте, что синтезатор не Ква/Хилых и целевай борда не плис. В прототипе на Альтере всё было ок, кстати. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 0 6 октября, 2020 Опубликовано 6 октября, 2020 · Жалоба 13 hours ago, des00 said: вообще такой стиль не рекомендуется. А именно смешивание в одном процессе блокирующего и неблокирующего присваивания, многие lint средства ругаются когда видят такой код, а так, разбиение на комбинационный и регистровый процесс и уже в комбинационном можно использовать обычный "программистский" стиль описания, переменные будут хранить свое состояние от итерации к итерации. Современные средства синтеза настолько хороши, что можно даже сложный код не разбивать на мелкие сущности, все зависит от алгоритма) Стиль, lint, разбиение - это всё понятно. Непонятно другое. Чтобы сдвиговый регистр с обратной связью работал надо: 1) Запомнить его старший бит 2) Сдвинуть сдвиговый регистр на один бит 3.1) Если запомненный бит равен 1, то сделать XOR некоторых бит (например 15-ого и 2-ого для CRC-16 modbus) с единицей. 3.2) Если запомненный бит равен 0, то сделать XOR некоторых бит (например 15-ого и 2-ого для CRC-16 modbus) с нулем. В вашем варианте: 1) "запоминание" старшего бита - есть 2) сдвиг - есть 3.1) Если старший бит - 1, то производится XOR некоторых бит с единицей (согласно полиному) и XOR всех остальных с нулем. 3.2) Если старший бит - 0, то производится XOR всех бит с нулем. Это вообще законно? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 6 октября, 2020 Опубликовано 6 октября, 2020 · Жалоба Just now, flammmable said: Это вообще законно? :) таблица истиности 0 ^ 0 = 0 1 ^ 0 = 1 0 ^ 1 = 1 1 ^ 1 = 0 т.е. ксор с нулем не дает ничего, с единицей инверсию. более того, ксор с нулем синтезатор даже не реализовывает, на этапе оптимизации это убирается) ЗЫ. Для тренировки, вот вам классическая задача, времен когда МК были маленькие и мелкие: Нужно обменять значения между двумя переменными, без использования третьей ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 0 6 октября, 2020 Опубликовано 6 октября, 2020 · Жалоба 7 minutes ago, des00 said: таблица истиности 0 ^ 0 = 0 1 ^ 0 = 1 0 ^ 1 = 1 1 ^ 1 = 0 т.е. ксор с нулем не дает ничего, с единицей инверсию. более того, ксор с нулем синтезатор даже не реализовывает, на этапе оптимизации это убирается) ЗЫ. Для тренировки, вот вам классическая задача, времен когда МК были маленькие и мелкие: Нужно обменять значения между двумя переменными, без использования третьей ;) А и правда! Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 0 6 октября, 2020 Опубликовано 6 октября, 2020 (изменено) · Жалоба Модуль вычисления CRC: module main #( parameter IS_CRC_REVERSED = 1, parameter IS_DATA_REVERSED = 1, parameter DATA_SIZE = 8, parameter CRC_SIZE = 16, parameter START_VALUE = 'hFFFF, parameter POLYNOME = 'h8005) ( input clk, input n_reset, input [DATA_SIZE-1:0]data_in, output reg [CRC_SIZE-1 :0]crc_out); reg [CRC_SIZE-1 :0]crc_internal; reg [DATA_SIZE-1:0]data_internal; reg msb; reg [CRC_SIZE-1 :0]crc_shift; reg [CRC_SIZE-1 :0]crc_lfsr; always @(posedge clk) begin if(n_reset) begin // data reverse if(IS_DATA_REVERSED) begin for(int i = 0; i < DATA_SIZE; i++) begin data_internal[i] = data_in[DATA_SIZE - 1 - i]; end end else begin data_internal = data_in; end // CRC calculating crc_shift = crc_internal ^ (data_internal << (CRC_SIZE - DATA_SIZE)); for(int data_index = 0; data_index < DATA_SIZE; data_index++) begin msb = crc_shift[CRC_SIZE-1]; crc_lfsr = (crc_shift << 1); crc_lfsr = crc_lfsr ^ ({CRC_SIZE{msb}} & POLYNOME); crc_lfsr[0] = msb; crc_shift = crc_lfsr; end crc_internal = crc_shift; // CRC reverse if(IS_CRC_REVERSED) begin for(int i = 0; i < CRC_SIZE; i++) begin crc_out[i] = crc_shift[CRC_SIZE - 1 - i]; end end else begin crc_out = crc_shift; end end else begin crc_internal = START_VALUE; end end endmodule Тестбенч к нему: `timescale 1ns/1ns module main_tb(); reg clk; reg n_reset; reg [7:0]data; wire [15:0]crc; main crc16( .clk (clk), .n_reset (n_reset), .data_in (data), .crc_out (crc)); initial begin #10; clk <= 0; while(1) begin #5 clk <= ~clk; end end initial begin #18; n_reset <= 0; #14 n_reset <= 1; #87 n_reset <= 0; end initial begin #31; data <= 'h12; #10 data <= 'h34; #10 data <= 'h56; #10 data <= 'h78; #10 data <= 'h90; #10 data <= 'hAB; #10 data <= 'hCD; #10 data <= 'hEF; #10 data <= 'hAA; #10 data <= 'h55; end endmodule Контрольная сумма из этого калькулятора для CRC-16 MODBUS и данных hex-1234567890ABCDEFAA совпадает с контрольной суммой, выдаваемой модулем. Изменено 6 октября, 2020 пользователем flammmable Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться