【问题标题】:Best way to instantiate grid of processing elements in Verilog / SystemVerilog?在 Verilog / SystemVerilog 中实例化处理元素网格的最佳方法?
【发布时间】:2020-11-22 15:34:27
【问题描述】:

我有一个 ProcessingElement.sv 模块,我想实例化它们的可配置数组,所以我想像这样创建一个生成块:

module ProcessingArray #(parameter Y=14, X=14, W=16) (  
    input                   GlobalClk,
    input           [3:0]   OpCode,
    input           [W-1:0] DataIn,
    output logic    [W-1:0] DataOut 
    );

    

    genvar x, y;
    generate
        for (y=0; y<=Y; y++) begin 
            for (x=0; x<X; x++) begin
                ProcessingElement #(.W(16)) PE(
                    .Clk(GlobalClk),
                    .OpCode(OpCode),
                    .Input(DataIn),
                    .Output(DataOut)
                );
            end
        end
    endgenerate


endmodule

这似乎使用 Modelsim 编译得很好,但我在寻找一种将数组元素相互连接的平滑方法时遇到了问题。一般来说,连接是如果x > y,元素将水平连接;如果 y > x,垂直;如果 x == y,则两者都对角线。 以下是左上角 3x3 网格如何连接的示例:

[连接][1]

有没有办法引用(例如,通过命名实例)循环中生成的每个实例?如果有的话,也许我可以创建另一个执行所有分配的生成语句。

我对 Verilog / SV 比较陌生,所以如果有更好的方法可以做到这一点,我很高兴得到启发

编辑: 这是一个展开的示例

module ProcessingArray #(parameter Y=14, X=14, W=16) (  
    input                   GlobalClk,
    input           [3:0]   OpCode,
    input           [W-1:0] DataIn,
    output logic    [W-1:0] DataOut 
    );

ProcessingElement #(.W(16)) PE_00(
    .Clk(GlobalClk),
    .OpCode(OpCode),
    .Input(DataIn),
    .Output(DataOut_00)
);

// For readability
wire wire00_01 = DataOut_00;
wire wire00_10 = DataOut_00;
wire wire00_11 = DataOut_00;

ProcessingElement #(.W(16)) PE_01(
    .Clk(GlobalClk),
    .OpCode(OpCode),
    .Input(wire00_01),
    .Output(DataOut_01)
);

wire wire01_02 = DataOut_01;

ProcessingElement #(.W(16)) PE_02(
    .Clk(GlobalClk),
    .OpCode(OpCode),
    .Input(wire01_02),
    .Output(wire02_elsewhere)
);

ProcessingElement #(.W(16)) PE_10(
    .Clk(GlobalClk),
    .OpCode(OpCode),
    .Input(wire00_10),
    .Output(DataOut_10)
);

wire wire10_20 = DataOut_10;

ProcessingElement #(.W(16)) PE_11(
    .Clk(GlobalClk),
    .OpCode(OpCode),
    .Input(wire00_11),
    .Output(DataOut_11)
);

wire wire11_12 = DataOut_11;
wire wire11_21 = DataOut_11;
wire wire11_22 = DataOut_11;

ProcessingElement #(.W(16)) PE_12(
    .Clk(GlobalClk),
    .OpCode(OpCode),
    .Input(wire11_12), 
    .Output(DataOut_12)
);

ProcessingElement #(.W(16)) PE_20(
    .Clk(GlobalClk),
    .OpCode(OpCode),
    .Input(DataIn), 
    .Output(DataOut_20)
);

ProcessingElement #(.W(16)) PE_21(
    .Clk(GlobalClk),
    .OpCode(OpCode),
    .Input(wire11_21), 
    .Output(DataOut_21)
);

ProcessingElement #(.W(16)) PE_22(
    .Clk(GlobalClk),
    .OpCode(OpCode),
    .Input(wire11_22), 
    .Output(DataOut)
);

endmodule

【问题讨论】:

  • 您可以使用begin:myname命名循环实例;但这对你没有帮助。您可能需要声明可以索引的内部信号数组。但是,您的连接图显示了具有不同连接数的 PE。你需要用一个循环展开的例子来解释发生了什么。
  • 如果可能的话,我想单独引用任何生成的 ProcessingElements(即,在我选择的任何一条线上分配 .Input)

标签: verilog system-verilog fpga


【解决方案1】:

您可以做的是创建一个二维线阵列,并在生成循环内进行条件连接。下面是一个完整的示例:

module ProcessingArray #(parameter Y=14, X=14, W=16) (  
    input                   GlobalClk,
    input           [3:0]   OpCode,
    input           [W-1:0] DataIn,
    output logic    [W-1:0] DataOut 
    );
  // internal connections
  wire [W-1:0] ConnIn[Y][X];
  wire [W-1:0] ConnOut[Y][X];
  // entry and exit connections
  assign ConnIn[0][0] = DataIn;
  assign DataOut = ConnOut[Y-1][X-1];

  for (genvar y=0; y<Y; y++) begin : row
    for (genvar x=0; x<X; x++) begin  :col
      ProcessingElement #(.W(16)) PE(
        .Clk(GlobalClk),
        .OpCode(OpCode),
        .Input(ConnIn[y][x]),
        .Output(ConnOut[y][x])
      );
      if (y<=x && x>0) assign ConnIn[y][x] = ConnOut[y][x-1]; // horizontal 
      if (x<=y && y>0) assign ConnIn[y][x] = ConnOut[y-1][x]; // vertical 
    end
  end

endmodule

module ProcessingElement #(int W) (
  input Clk,
  input           [3:0]   OpCode,
  input           [W-1:0] Input,
  output logic    [W-1:0] Output
);
  assign Output=Input+1;  // trace connectivity
  initial #1 $display("PE %m %d",Input);
endmodule

module tb;
  logic [15:0] in,out;
  logic [3:0] op;
  
  ProcessingArray PE(clk,op,in,out);
  
  initial begin
    in = 1;
    #1 $display(out);
  end
endmodule

【讨论】:

    猜你喜欢
    • 2015-10-28
    • 2015-05-31
    • 2016-01-25
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    • 2010-09-29
    • 1970-01-01
    相关资源
    最近更新 更多