Перейти к содержанию
    

Умножение многочленов на фиксированный многочлен для кодирования информации

Хочу написать умножение на полином, как описано схемой в этой книге. Я написал по схеме такой код:

 

module mult_poly(
    input logic clk,
    input logic in,
    output logic out
);

    logic [2:0] lfsr = '0;
    
    always @(posedge clk) begin
        lfsr[2] <= in;
        lfsr[1] <= lfsr[2];
        lfsr[0] <= lfsr[1];
    end
    
    assign out = in ^ lfsr[2] ^ lfsr[0];
endmodule

И тестбенч к нему:

 


module mult_poly_tb();

    logic clk;
    logic in;
    logic out;
    
    initial begin
        clk <= 0;
        forever #5 clk =!clk;
    end
    
    mult_poly dut(clk, in, out);
    
    initial begin
        in = 1; #10
        in = 0; #10
        in = 0; #10
        in = 1;
    end
    
    always @(posedge clk) begin
        $write("%b", out);
    end
endmodule

Почему код работает неправильно? Пример правильного вычисления:
\(f(x) = 1 + x^3=(1001)\)

\((1+x^3)(1+x^2+x^3)=x^6+x^5+x^2 + 1=(110011)\)

Многочлен f(x), представленный последовательностью коэффициентов, прогоняю через схему и получаю в результате (1100001). Это неправильно, потому что правильный результат получен выше и равен (110011). Что я сделал не так? Почему схема не работает?

16757877420360.png

 

photo_2023-03-28_14-07-36.jpg

Изменено пользователем AngelicQuasar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

выведите в симуляторе все ваши сигналы и посмотрите на каком именно шаге схема считает не так. У вас же все эталон расписан пошагово.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, AngelicQuasar said:

Почему код работает неправильно? Пример правильного вычисления:
f(x)=1+x3=(1001)

Всё-таки, где в позиционном коде числа какие степени расположены?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я новичок в ПЛИС, многого не знаю. Пришел в ПЛИС из системного программирования, а здесь по-другому все. Сложно разбираться.

Только что, _4afc_ сказал:

Всё-таки, где в позиционном коде числа какие степени расположены?

Я выписывал коэффициенты от старшего одночлена с младшему, как в книге написано - там сказано, что на вход схемы сначала подается коэффициент при старшей степени.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, AngelicQuasar said:

Я выписывал коэффициенты от старшего одночлена с младшему, как в книге написано - там сказано, что на вход схемы сначала подается коэффициент при старшей степени.

Непривычно, но допустим. Может пример взять не симметричный для наглядности?

 

А ваш симулятор знает что вы на SV пишете?

может по старинке:  lfsr сделать reg, сбросить его reset или нулями впереди и добавить регистр на out?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кажется у вас опечатка в книжке. Судя по схеме, там 1 + x^1 + x^3, и именно так вы и реализуете своё устройство. А формулу используете из книжки 1 + x^2 + x^3. Кстати, результат вдвигания 1001 в вашу схему несложно посчитать на бумажке, и у меня он получился отличным и от ваших вычислений и от вашей модели: 1100101

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, fingertouch сказал:

Кажется у вас опечатка в книжке. Судя по схеме, там 1 + x^1 + x^3, и именно так вы и реализуете своё устройство. А формулу используете из книжки 1 + x^2 + x^3. Кстати, результат вдвигания 1001 в вашу схему несложно посчитать на бумажке, и у меня он получился отличным и от ваших вычислений и от вашей модели: 1100101

Я выбрал для теста другой многочлен и посчитал в Maple, чему равно произведение: \(1+x+x^2+x^6+x^7=(11100011)\)

Выписываем последовательность коэффициентов от младшего к старшему. Пусть старший коэффициент будет последним, потому что он первый вдвигается в схему. А вот какой результат работы схемы. Тестбенч:

module mult_poly_tb();

    logic clk = 0;
    logic in  = 0;
    logic out = 0;
    
    initial begin
        forever #5 clk = !clk;
    end
    
    mult_poly dut(clk, in, out);
    
    initial begin
        in <= 1; #10
        in <= 0; #10
        in <= 0; #10
        in <= 1; #10
        in <= 1;
    end
    
    always @(posedge clk) begin
        $write("%b", out);
    end
endmodule

В консоль выводится такое: 110000101100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Отличается и от вашего результата, и от моего.

1.png

Кстати, а есть книга про такие схемы? Это либо теория кодирования, либо криптография. Что почитать о том, как самостоятельно рисовать такие схемы? Есть учебник?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

30 минут назад, _4afc_ сказал:

Непривычно, но допустим. Может пример взять не симметричный для наглядности?

 

А ваш симулятор знает что вы на SV пишете?

может по старинке:  lfsr сделать reg, сбросить его reset или нулями впереди и добавить регистр на out?

Я пишу в Vivado, он умеет SystemVerilog. Пишу в файлах .sv, так что вивадо сам понимает, на чем я пишу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

28 минут назад, AngelicQuasar сказал:

Я выбрал для теста другой многочлен и посчитал в Maple, чему равно произведение: 1+x+x2+x6+x7=(11100011)1+x+x2+x6+x7=(11100011)

Не стоит перескакивать с одной схемы на другую, давайте разберёмся с первой.

 

28 минут назад, AngelicQuasar сказал:

 

В консоль выводится такое: 110000101100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Отличается и от вашего результата, и от моего.

Кажется, я понял, в чём проблема. Вы в модели забываете обнулить входную последовательность. У вас в тестбенче для входной величины зависает единица. Добавьте ещё одну строчку в инишиале  #10 in <= 0после присвоения последней единицы.

 

28 минут назад, AngelicQuasar сказал:

Кстати, а есть книга про такие схемы? Это либо теория кодирования, либо криптография. Что почитать о том, как самостоятельно рисовать такие схемы? Есть учебник?

Это не совсем криптография. То, что вы сейчас делаете - это М-последовательности. С той разницей, что вам нужно подать на вход произвольный входной сигнал, а для М-последовательности выход на вход закольцовывается. Поищите по данному названию + verilog или system verilog. Ну или алгоритмы CRC и их реализация.

Изменено пользователем fingertouch

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня в тестбенче происходит что-то странное. Не знаю, как объяснить, но с сигналами in и out и с содержимым регистра lfsr происходит какой-то хаос.

Эта схема из книги "Коды и математика", там про реализацию циклического кода.

М-последовательность это случайный генератор, а тут схема умножения на полином.

В симуляторе в Out выводится единица, когда в регистре lfsr ничего нет. Видимо, тестбенч кривой, а не схема.

Изменено пользователем AngelicQuasar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я изменил код:

 

module mult_poly(
    input logic clk,
    input logic reset,
    input logic in,
    output logic out,
    output logic done
);

    logic [2:0] lfsr = '0;
    
    always @(posedge clk)
        if (reset)
            lfsr <= '0;
        else begin
            lfsr[2] <= in;
            lfsr[1] <= lfsr[2];
            lfsr[0] <= lfsr[1];
        end
        
    assign out = in ^ lfsr[2] ^ lfsr[0];
    assign done = lfsr == 0;
    
endmodule
module mult_poly_tb();

    logic clk = 0;
    logic reset = 0;
    logic in  = 0;
    logic out = 0;
    logic done = 0;
    
    initial begin
        forever #10 clk = !clk;
    end
    
    mult_poly dut(
        .clk(clk),
        .reset(reset),
        .in(in),
        .out(out),
        .done(done)
    );
    
    initial begin
        #10 reset <= 1;
        #10 reset <= 0;
        #10 in <= 1;
        #10 in <= 0;
        #10 in <= 0;
        #10 in <= 1;
        #10 in <= 1;
        #10 in <= 0;
    end
    
    always @(posedge clk) begin
        $display("out = %b, done = %b", out, done);
    end
endmodule

При симуляции видно, что сигнал done, показывающий, что вычисление закончено (когда регистр lfsr снова обнулился) равен 0 только три раза. Значит, умножение сработало неправильно.

# run 1000ns
out = 0, done = 1
out = 0, done = 1
out = 0, done = 1
out = 1, done = 1
out = 1, done = 0
out = 0, done = 0
out = 1, done = 0
out = 0, done = 1
out = 0, done = 1
out = 0, done = 1

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 hours ago, fingertouch said:

Не стоит перескакивать с одной схемы на другую, давайте разберёмся с первой.

Да что тут разбираться то, если сразу видно что тестбенч криво написан. Где вы видели такие синхронные воздействия)

 

tb.png

12 hours ago, AngelicQuasar said:

Я изменил код:

вот руки надо вырвать тому автору, который первый в учебниках предложил моделировать синхронные воздействия, задержками. я же вам сразу написал "выведите в симуляторе все ваши сигналы и посмотрите на каком именно шаге схема считает не так"

Вот такой у вас результат должен быть для правильного синхронного тестбенча и код его

    initial begin
        reset <= 1'b1;
        @(posedge clk);
        reset <= 1'b0;
    end

    initial begin
        in <= '0;
        @(posedge clk iff !reset);
/*
        // data 1001
        in <= 1; @(posedge clk);
        in <= 0; @(posedge clk);
        in <= 0; @(posedge clk);
        in <= 1; @(posedge clk);
        // tail
        in <= 0; @(posedge clk);
        in <= 0; @(posedge clk);
*/
        // data 100110
        in <= 1; @(posedge clk);
        in <= 0; @(posedge clk);
        in <= 0; @(posedge clk);
        in <= 1; @(posedge clk);
        in <= 1; @(posedge clk);
        in <= 0; @(posedge clk);
        // tail
        in <= 0; @(posedge clk);
        in <= 0; @(posedge clk);
    end

можете вручную посчитать выражение

in ^ lfsr[2] ^ lfsr[0];

и убедиться что out на рисунке соответствует этому выражению)

tb2.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо! Вроде так работает. Да, я по учебнику изучаю верилог. А какой учебник лучший?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, AngelicQuasar said:

Спасибо! Вроде так работает. Да, я по учебнику изучаю верилог. А какой учебник лучший?

да в большинстве учебников одно и тоже написано (перепечатывают наверное друг у друга)). Если у вас перспективы пойти в ПЛИС, то рекомендую вам начать с: стандарт на SV, SV for Design, SV for Verification. Книги простые, легко читаются.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...