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

Программируемая логика - это не так уж и сложно. Разберемся вместе.
Ответить
AngelicQuasar
Родился
Сообщения: 11
Зарегистрирован: Ср фев 08, 2023 01:13:37

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

Сообщение AngelicQuasar »

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

Код: Выделить всё

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 КБ) 174 скачивания
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

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

Код: Выделить всё

// -------------------------------------------------------------
// Created: 2023-02-09 17:55:39
// Generated by MATLAB 9.1 and HDL Coder 3.9
// -------------------------------------------------------------
// Module: shift_reg
// Source Path: untitled/shift_reg
// Hierarchy Level: 0
// -------------------------------------------------------------

`timescale 1 ns / 1 ns

module shift_reg
          (
           clk,
           reset,
           clk_enable,
           In,
           ce_out,
           Out
          );



  input   clk;
  input   reset;
  input   clk_enable;
  input   In;
  output  ce_out;
  output  Out;

  wire enb;
  reg  data_2_out1;
  reg  [0:1] data_0_reg;  // ufix1 [2]
  wire [0:1] data_0_reg_next;  // ufix1 [2]
  wire data_0_out1;
  wire XOR1_out1;
  wire XOR2_out1;


  assign enb = clk_enable;

  always @(posedge clk or posedge reset)
    begin : data_2_process
      if (reset == 1'b1) begin
        data_2_out1 <= 1'b0;
      end
      else begin
        if (enb) begin
          data_2_out1 <= In;
        end
      end
    end



  always @(posedge clk or posedge reset)
    begin : data_0_process
      if (reset == 1'b1) begin
        data_0_reg[0] <= 1'b0;
        data_0_reg[1] <= 1'b0;
      end
      else begin
        if (enb) begin
          data_0_reg[0] <= data_0_reg_next[0];
          data_0_reg[1] <= data_0_reg_next[1];
        end
      end
    end

  assign data_0_out1 = data_0_reg[1];
  assign data_0_reg_next[0] = data_2_out1;
  assign data_0_reg_next[1] = data_0_reg[0];



  assign XOR1_out1 = data_2_out1 ^ In;



  assign XOR2_out1 = data_0_out1 ^ XOR1_out1;



  assign Out = XOR2_out1;

  assign ce_out = clk_enable;

endmodule  // shift_reg

[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
AngelicQuasar
Родился
Сообщения: 11
Зарегистрирован: Ср фев 08, 2023 01:13:37

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

Сообщение AngelicQuasar »

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

Код: Выделить всё

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. Похоже, если развернуть вектор, но не то.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Сообщение Gudd-Head »

Да, если вы подаёте на вход "101000", на выходе должно быть "111001".
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
AngelicQuasar
Родился
Сообщения: 11
Зарегистрирован: Ср фев 08, 2023 01:13:37

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

Сообщение AngelicQuasar »

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

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

Код: Выделить всё

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 Тут непонятно откуда появился икс, а последовательность бит вообще другая какая-то. Скажите, пожалуйста, как правильно реализовать эту схему и симулировать ее, чтобы получился верный результат.
Ответить

Вернуться в «ПЛИС»