2015-08-21 26 views
3

请看下面的语句。 c_r被分配了全部c[k]的xor版本。重写long 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];

回答

2

我想提出以下几点建议:

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.3 foreach-loop了解完整的语法用法和功能。 ^=是一个二进制按位赋值运算符,参见IEEE Std 1800-2012 § 11.4 运算符说明。在整个LRM中有foreach^=的各种代码示例。

+1

与问题无关,所以我会留下这个评论:我更喜欢将我的顺序逻辑作为简单的作业。这样所有的计算代码都是组合在一起的。我发现这有助于代码可读性,因为我不必跳转到另一个总是阻止查看最终计算。有一个'next_ *'是一个更好的打字,但在调试时非常值得。 – Greg

0

减少运营商对这项有益的,一个简单的例子:

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组异或逻辑。

+0

谢谢你。不幸的是,这还不行。 'c'被定义为逻辑[7:0] c [16] [16];'。在提出的解决方案中,我收到以下错误消息:错误 - [IMEMCT]无效的内存使用 design.sv,17 内存或内存片不允许在以下上下文中使用: \t 1. if/case/while语句等 \t 2.赋值语句的源或目标表达式 \t 3.等于运算符的操作数 表达式:(^ c [k])' – Razer

+0

这样的循环是怎么样的?我很困惑,因为它会像'c_xor [k] = c_xor [k]^c [k] [l]'对吗? – Razer

+0

我们不是为了简单的事情而来;-)。我不明白内在循环。这不是一个组合循环吗? – Razer

1

你可以尝试使用内循环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)。

+0

由于c [k] [0]至c [k] [15]没有手动列出,因此如果需要,将来可以更容易地更改数字“16”,因此此解决方案实现了易于维护的目标。但是,我认为一些综合工具不知道如何最佳重新排列xors链来减少逻辑深度,而使用reduction-xor操作符时,该工具在选择xor拓扑结构时具有更大的灵活性。在过去的这些类型的场景中,我使用了一个循环来重新排列数组索引,使得可以使用缩减操作符。 – mattgately

+2

@Morgan它在第11.3节IEEE 1800-2012标准的运营商。 –

+0

干杯都铎,很好学习一个新的运营商。 – Morgan