【发布时间】:2017-07-12 13:16:19
【问题描述】:
我正在使用 SystemVerilog 进行综合。我反对这样一个事实,即接口数组在 SystemVerilog 中并不是真正的数组,索引必须是一个常量值,但是使用大量样板文件 generate for 和 assign 语句克服了它,以克服真正的语言限制(如果我可以使用更多代码来模拟效果,那么语言本身就可以做正确的事情(tm)。
对于以下伪代码,为了清楚起见,我省略了真实代码中的大部分内容(modport、任务等)。 我有一个界面:
interface i_triplex();
logic a; // input wire
logic b; // output wire
logic [127:0] data; // output wires
endinterface
我将这些接口的数组传递给一个看起来像
的模块module roundrobin_triplex#(
parameter int NUNITS = 8
)
(
input wire clk,
input wire rst,
i_triplex t[NUNITS]
);
always_ff @(posedge clk) begin
if (rst) begin
// insert code to initialize the "data" member
// in all interface instances in the array.
end
else begin
// ...
end
end
endmodule
无论NUNITS 的值如何,您希望以何种方式统一使用数组中的所有接口实例?我有一些建议,但我很想知道其他工程师能想出什么。
建议一: 使用 VHDL。
建议 2: 废弃界面并按照老式的 Verilog 风格进行操作,如
module roundrobin_triplex#(
parameter int NUNITS = 8
)
(
input wire clk,
input wire rst,
// This was once a proud i_triplex array
input wire i_triplex_a[NUNITS],
input wire i_triplex_b[NUNITS],
input wire [127:0] i_triplex_data[NUNITS],
);
always_ff @(posedge clk) begin
if (rst) begin
for (int i = 0; i < NUNITS; i++)
i_triplex_data[i] <= '1;
end
else begin
// ...
end
end
endmodule
建议 3:
输入线使用struct,输出线使用struct,而不是接口。
建议 4:
使用类似预处理器的系统,在进程内展开generate for 循环(无论如何语言应该做什么!),因此生成的代码看起来像(使用 NUNITS=4 预处理):
module roundrobin_triplex#(
parameter int NUNITS = 8
)
(
input wire clk,
input wire rst,
i_triplex t[NUNITS]
);
always_ff @(posedge clk) begin
if (rst) begin
i_triplex.data[0] <= '1;
i_triplex.data[1] <= '1;
i_triplex.data[2] <= '1;
i_triplex.data[3] <= '1;
end
else begin
// ...
end
end
endmodule
建议 5:
使用generate for/assign解决方案:
module roundrobin_triplex#(
parameter int NUNITS = 8
)
(
input wire clk,
input wire rst,
i_triplex t[NUNITS]
);
wire i_triplex_a[NUNITS];
wire i_triplex_b[NUNITS];
wire [127:0] i_triplex_data[NUNITS];
generate
genvar i;
// The wires of the interface which are to be driven
// from this module are assigned here.
for (i = 0; i < NUNITS; i++) begin
assign t[i].b = i_triplex_b[i];
assign t[i].data = i_triplex_data[i];
end
endgenerate
always_ff @(posedge clk) begin
if (rst) begin
for (int i = 0; i < NUNITS; i++)
i_triplex_data[i] <= '1;
end
else begin
// ...
end
end
endmodule
【问题讨论】:
标签: arrays interface verilog system-verilog