Проблема с написанием логики RTL

Предположим, что у меня есть шина B. Я хочу создать новую шину C, сигналы которой задерживаются на величину, пропорциональную их индексу, если соответствующий индекс B равен 1. Позвольте мне объяснить это на примере, допустим, моя исходная шина B (ширины 5) имеет значение 10111, и B остается на этом значении навсегда. Теперь я хочу, чтобы C был таким:

clk 0: 00001
clk 1: 00011
clk 2: 00111
clk 3: 10111

(Обратите внимание, что 3-й бит равен 0 на шине B, следовательно, после позиции бита 2 это старший бит C (позиция бита 4), который должен быть высоким в самом следующем такте).

Ниже показана соответствующая форма волны.


B[0] ,,,|'''''''''''''''''''''''''''''''''
B[1] ,,,|'''''''''''''''''''''''''''''''''
B[2] ,,,|'''''''''''''''''''''''''''''''''
B[3] ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
B[4] ,,,|'''''''''''''''''''''''''''''''''

clk   ,,|''|,,|''|,,|''|,,|''|,,|''|,,|''|

C[0] ,,,|'''''''''''''''''''''''''''''''''
C[1] ,,,,,,,,,|'''''''''''''''''''''''''''
C[2] ,,,,,,,,,,,,,,,|'''''''''''''''''''''
C[3] ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
C[4] ,,,,,,,,,,,,,,,,,,,,,,|''''''''''''''

Как я могу смоделировать это в синтезируемой логике RTL с помощью systemverilog и всегда блокировать. Я ищу что-то похожее на это (это просто псевдокод):

Logic[width-1:0][width-1:0] temp;
logic hit_zero; //This is a variable seen and modified by all the generated always blocks(I am not sure if that's allowed)
generate
   for (genvar i = 0; i < width; i++) begin
        always @(posedge clk) begin
              if (B[i] == 1) begin
                 temp[i] <= temp[i] << i;
                 if (hit_zero) begin
                   temp[i] <= temp[i] << (pos+1);
                   hit_zero <= 0;
                 end
                 pos <= i;
              end else begin
                 temp[i] <= temp[i] << i;
                 hit_zero <= 1;  
              end
              temp[i][0] <= B[i];
        end
   end
  endgenerate
  generate 
   for (genvar i = 0; i < width; i++) begin 
    assign C[i] = temp[i][i];
   end
  endgenerate


person the freethinker    schedule 23.04.2020    source источник
comment
Вы действительно хотите, чтобы C изменялось на обоих краях часов?   -  person Matthew Taylor    schedule 23.04.2020
comment
Нижняя диаграмма включает в себя нарастающие и спадающие фронты. Это то, что вы хотите?   -  person Oldfart    schedule 23.04.2020
comment
Извините, я имел в виду только положительные края. Поправил волны :)   -  person the freethinker    schedule 23.04.2020
comment
что именно не так с вашим псевдокодом? пробовали?   -  person Serge    schedule 23.04.2020
comment
Переменные hit_zero и pos видны и изменяются из всего сгенерированного блока always (в чем-то похоже на глобальные переменные в C). Я хочу сделать логику, не используя их, и я не могу придумать другого потенциального решения, кроме этого. Кроме того, какие-либо мысли о том, может ли этот код (как он есть) соответствовать спецификации дизайна, о которой я упоминал?   -  person the freethinker    schedule 23.04.2020


Ответы (1)


Я придумал пример одного блока always, который, кажется, выполняет ту часть, которую вы хотите, по крайней мере, в симуляции. Это должно быть синтезируемо, хотя я не пробовал. Он ожидает сигнала сброса для установки начальных значений. Таким образом, вы можете попробовать использовать его в качестве базы для вашего исследования.

Ему нужно pos, чтобы указать на текущую битовую позицию, которая увеличивается на основе битового состояния B (incr).

done необходим, чтобы сделать цикл синтезируемым.

  logic clk, reset;
  logic [4:0] B,C;

  reg[4:0]creg;
  int pos;
  int incr;
  bit done;

  always @(posedge clk) begin
    if (reset) begin
      pos <= 0;
      creg <= 0;
    end
    else begin
      incr = 0;
      done = 0;
      for (int i = 0; i < 5; i++) begin
        if (!done && i >= pos) begin
          incr++;
          creg[i] <= B[i];
          if (B[i])
            done = 1;
        end
      end
      pos <= pos + incr;
    end
  end

  assign C = creg;
person Serge    schedule 23.04.2020