You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SystemVerilog中用移位运算符实现部分选择?含替代方案

一、使用移位运算符实现

1. 先计算关键参数

首先确定目标位段的宽度:

int width = abs(i - j) + 1; // 位段的总位数

2. 分场景处理

场景1:i ≥ j(正向选择,左到右高位到低位)

此时memword[i:j]取索引i到j的连续位(i在左,位权更高),用右移+掩码实现:

mem2 = (memword >> j) & ((1 << width) - 1);

原理:

  • memword >> j:将memword逻辑右移j位,把目标位段的最低位(memword[j])对齐到结果的第0位;
  • ((1 << width) - 1):生成width位的全1掩码,与移位结果做与运算,截断出目标width位的位段,完全等价于memword[i:j]的数值。

场景2:i < j(反向选择,左到右低位到高位)

此时memword[i:j]取索引i到j的连续位(i在左,j在右,位权逐渐降低),需先反转位序再处理:

logic [8:0] memword_rev;
logic [width-1:0] temp;

memword_rev = {<<{memword}}; // 反转memword位序,变为[8:0](原memword[0]对应新索引8)
temp = (memword_rev >> (8 - j)) & ((1 << width) - 1);
mem2 = {<<{temp}}; // 反转temp还原原位序

原理:

  • 反转后,原memword[i:j]对应反转向量的memword_rev[8-j : 8-i],此时满足8-j ≤8-i,可复用场景1的移位逻辑;
  • 最后反转temp,还原原memword[i:j]的位序和数值。

二、更通用的替代实现(适合编译器优化)

如果移位实现过于繁琐,推荐逐位循环赋值,逻辑直观且支持所有索引组合,编译器可直接展开优化:

logic [width-1:0] mem2;
int k;

always_comb begin
    for(k = 0; k < width; k++) begin
        if(i >= j) begin
            mem2[k] = memword[i - k]; // 正向选择:从i到j依次赋值给mem2高位到低位
        end else begin
            mem2[k] = memword[i + k]; // 反向选择:从i到j依次赋值给mem2高位到低位
        end
    end
end

三、替换示例代码

将原示例中的部分选择语句替换后,完整代码如下:

logic [0:8] memword;
logic [width-1:0] mem2;
int width, i, j;

always @(posedge clk) begin
    width = abs(i - j) + 1;
    // 生成等价于memword[i:j]的临时值
    logic [width-1:0] temp_val;
    int k;
    for(k=0; k<width; k++) begin
        if(i >=j) temp_val[k] = memword[i -k];
        else temp_val[k] = memword[i +k];
    end

    if(temp_val) begin
        mem2 = temp_val;
    end
end

内容的提问来源于stack exchange,提问作者Subramanya Krishna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 04:20:01