Проблема в написании логики RTL - PullRequest
0 голосов
/ 23 апреля 2020

Предположим, что у меня есть шина 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 logi c использую 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

1 Ответ

2 голосов
/ 23 апреля 2020

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

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

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

  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;
...