Программируемая логика - это не так уж и сложно. Разберемся вместе.
Ответить

Умножение многочленов конечного поля при помощи регистра сдв

Ср фев 08, 2023 18:47:26

Хочу реализовать схему для умножения полиномов на фиксированный полином по книге. Не уверен, что все делаю правильно. По методичке, нагугленной в интернете, пытался разобраться в регистрах сдвига и написал такой код:

Код:
module shift_reg(input logic clk,
                 input logic in,
                 input logic enable,
                 output logic out);
                 
     reg [2:0] data = 3'b000;
     always @(posedge clk) begin
        if (enable)
            data <= { in, data[2:1] };
     end
     
     assign out = in ^ data[2] ^ data[0];
endmodule


Я плохо понимаю, как в SystemVerilog происходит конкатенация шин:

Код:
data <= { in, data[2:1] };


Здесь получается шина, где in - старший разряд, а data[1] - самый младший? Что будет, если поменять переменные местами и написать:

Код:
data <= { data[2:1], in };


Теперь data[2] и data[1] будут старшие разряды, а in - самый младший?
Будет ли схема работать по-другому, если написать:

Код:
data <= { in, data[1:0],};


Здесь регистр сдвигает полученные биты влево, поэтому конкатенация должна быть соответствующая, при которой эти биты сдвигаются влево.

И еще вопрос. Есть ли возможность сразу на широкую шину (скажем, 8 бит) выставить коэффициенты многочлена единовременно, а не по одному биту? Как это сделать?

Добавлено after 8 hours 39 minutes 47 seconds:
И еще вопрос

Как задаются индексы шины при конкатенации шин? Вот например:

wire [1:0] dataIn;
assign dataIn = {d1,d0};

Тут dataIn[0] содержит сигнал d0 или d1? Или это не имеет значения?
Вложения
умножение полиномов.png
(111.95 KiB) Скачиваний: 41

Re: Умножение многочленов конечного поля при помощи регистра

Чт фев 09, 2023 18:05:18

Тут не совсем сдвиговый регистр, тут просто 3 триггера друг за другом.
Можете посмотреть на сгенерированный Матлабом код для такого модуля:
Изображение
Там, конечно, слишком много лишнего (куча ассигнов, ресет, це_аут)... Но если их аккуратно поубирать, можно приблизить код к вашему:

Re: Умножение многочленов конечного поля при помощи регистра

Чт фев 09, 2023 20:49:50

Получается, что можно сделать эту схему из трех д-триггеров вот так?

Код:
module flop(input logic clk, reset, in, output logic out);
    always @(posedge clk, posedge reset)
        if (reset) out <= 1'b0;
        else       out <= in;
endmodule


Код:
module multiplier(input logic clk, reset, in,
                  output logic out);
                 
    wire w0, w1, w2;
   
    flop f0(clk, reset, in, w0);
    flop f1(clk, reset, w0, w1);
    flop f2(clk, reset, w1, w2);
   
    assign out = in ^ w0 ^ w2;
endmodule


Код:
module shift_reg_tb();

    logic clk, in, enable, out;
   
    shift_reg r(clk, in, enable, out);
   
    initial begin
        clk = 0;
        forever #10 clk = ~clk;
    end
   
    initial begin
        clk = 1;
        enable = 1;
        in = 1; #10
        $display(out);
       
        in = 0; #10
        $display(out);
       
        in = 1; #10
        $display(out);
       
        in = 0; #10
        $display(out);
       
        in = 0; #10
        $display(out);
       
        in = 0; #10
        $display(out);
    end
endmodule


Добавлено after 1 minute 36 seconds:
Re: Умножение многочленов конечного поля при помощи регистра сдв
Что-то симулятор печатает странные результаты. Подаю на вход многочлен x^2 + 1 как бинарный вектор (1, 0, 1), результатом должен быть многочлен x^5 + x^4 + x^3 + 1 (бинарный вектор 111001), а симулятор печатает 010111. Похоже, если развернуть вектор, но не то.

Re: Умножение многочленов конечного поля при помощи регистра

Пн фев 13, 2023 18:14:45

Да, если вы подаёте на вход "101000", на выходе должно быть "111001".

Re: Умножение многочленов конечного поля при помощи регистра

Чт мар 30, 2023 19:05:55

У меня не получается умножать многочлены по этой схеме. Как ее реализовать и просимулировать?

Я вот так реализовал ее на верилоге:

Код:
module multiplier(
    input logic clk,
    input logic reset,
    input logic in,
    output logic out
);

    reg [2:0] s;
   
    always @(posedge clk)
        if (reset)
            s <= '0;
        else begin
            s[2] <= in;
            s[1] <= s[2];
            s[0] <= s[1];
        end
       
    assign out = in ^ s[2] ^ s[0];
endmodule


И написал такой тестбенч:

Код:
module multiplier_tb();

    logic clk;
    logic reset;
    logic in;
    logic out;
   
    initial begin
        clk = 0;
        forever #5 clk = ~clk;
    end
   
    multiplier m(clk, reset, in, out);
   
    initial begin
        #1 reset = 1; #10
        reset = 0;
/*       
        // data 11111
        in = 1; #10
        in = 1; #10
        in = 1; #10
        in = 1; #10
        in = 1; #10
        // tail
        in = 0; #10
        in = 0; #10
        in = 0; #10
        $stop;
*/

       // data 1000
       in = 1; #10
       in = 0; #10
       in = 0; #10
       in = 0; #10
       // tail
       in = 0; #10
       in = 0; #10
       in = 0; #10
       $stop;
    end
   
    always @(posedge clk)
        #2 $write(out);
endmodule


Но на последовательности f(x) = 1000 схема работает неправильно. По математический расчетам должно получиться 1101000 - результат умножения многочлена g(x) = x^3 + x^2 + 1 на x^3, представленный в виде вектора коэффициентов. В логе симулятора получается такое: x00010000$stop Тут непонятно откуда появился икс, а последовательность бит вообще другая какая-то. Скажите, пожалуйста, как правильно реализовать эту схему и симулировать ее, чтобы получился верный результат.
Ответить