请看以下声明。 c_r
被指定为所有c[k]
的xor版本。
always_ff @ (posedge clk_i)
begin
for(k = 0; k < 16; k++)
c_r[k*8 +: 8] <= c[k][0] ^ c[k][1] ^ c[k][2] ^ c[k][3] ^ c[k][4] ^ c[k][5] ^ c[k][6] ^ c[k][7] ^ c[k][8] ^ c[k][9] ^ c[k][10] ^ c[k][11] ^ c[k][12] ^ c[k][13] ^ c[k][14] ^ c[k][15];
end
然而,设计是否有可能重构声明以便于维护和可读性?
注意:c
定义为logic [7:0] c[16][16];
我建议如下:
logic [16*8-1:0] c_r, next_c_r;
logic [7:0] c[16][16];
always_comb begin
next_c_r = '0;
foreach(c[idx0,idx1]) begin
next_c_r[idx0*8 +: 8] ^= c[idx0][idx1];
end
end
always_ff @ (posedge clk_i)
begin
c_r <= next_c_r;
end
foreach
将遍历所有选定的索引。请参阅IEEE Std 1800-2012§12.7.3foreach-loop以获取完整的语法用法和功能。 ^=
是一个二进制位运算符,参考IEEE Std 1800-2012§11.4运算符描述。整个foreach
有^=
和LRM的各种代码示例。
您可以尝试在里面使用for
循环来计算XOR结果并将其分配给c_r
切片:
always_ff @ (posedge clk_i)
begin
for(int k = 0; k < 16; k++) begin
logic [7:0] xor_result;
for (int i = 0; i < 16; i++)
xor_result ^= c[k][i];
c_r[k*8 +: 8] <= xor_result;
end
end
我不确定这将如何与你的工具合成,但我看到我的同事一直使用这些技巧(用VHDL)。
减少运算符对此很有用,一个简短的例子:
wire result;
wire [3:0] bus;
//assign result = bus[0] ^ bus[1] ^ bus[2] ^ bus[3];
assign result = ^bus;
因此,一元^
将公共汽车折叠到一个位,这也适用于&
和|
。
在你的情况下,我相信这应该工作:
always_ff @ (posedge clk_i)
begin
for(k = 0; k < 16; k++)
c_r[k*8 +: 8] <= ^c[k];
end
如果无法嵌入第二个循环(将其提取到组合部分):
logic [15:0] parity_bus;
always_comb begin
for(k = 0; k < 16; k++) begin
parity_bus[k] = 1'b0;
for(int i = 0; i < 16; i++) begin
parity_bus[k] = parity_bus[k] ^c[k][i];
end
end
end
always_ff @ (posedge clk_i) begin
for(k = 0; k < 16; k++) begin
c_r[k*8 +: 8] <= parity_bus[k];
end
end
您有效地并行描述了16组XOR逻辑。