如何在 verilog 中使用 case 语句而不是 for 循环

How to use case statement instead of for-loop in verilog

下面是verilog中描述的七人投票程序,但是由于for循环的效率问题,我想把for循环改成案例陈述.

module voter7(pass, vote);

output pass;
input[6:0] vote;
reg[2:0] sum;

integer i;
reg pass;

always @(vote) 
    begin
        sum = 0;
        for(i=0; i<=6; i=i+1)
            if(vote[i]) sum = sum+1;
        if(sum[2]) pass = 1;
        else pass = 0;
    end

endmodule

这是教授给我的作业。正好,我想用case语句重写下面的代码。

for(i=0; i<=6; i=i+1)
  if(vote[i]) sum = sum+1;

Unlike different high-level programming languages like 'C', the Verilog case statement includes implicit break statements. verilog-case-statement in Verilog Tutorial

根据我的经验,您的教授可能犯了一个错误,他认为 Verilog 可以顺序执行多个 case 语句,但实际上它不能这样做。 所以,你可能会用一个尴尬的方法来回应你的教授。

module voter7(pass, vote);

output pass;
input[6:0] vote;
reg[2:0] sum;

integer i;
reg pass;

always @(vote) 
    begin
        sum = 0;

        casez(vote)
            7'b??????1: sum = sum + 1;
        endcase
        casez(vote)
            7'b?????1?: sum = sum + 1;
        endcase
        casez(vote)
            7'b????1??: sum = sum + 1;
        endcase
        casez(vote)
            7'b???1???: sum = sum + 1;
        endcase
        casez(vote)
            7'b??1????: sum = sum + 1;
        endcase
        casez(vote)
            7'b?1?????: sum = sum + 1;
        endcase
        casez(vote)
            7'b1??????: sum = sum + 1;
        endcase
        
        if(sum[2]) pass = 1;
        else pass = 0;
    end

endmodule

for 循环不一定比 case 语句效率低。问题是“+”运算符。综合可以尝试在您的情况下生成 7 个顺序加法器,影响门数和时序。

其中一个想法是创建一个巨大的 case 语句,其中列出所有可能的 4+ 位组合。这将改善时序,不一定是门的数量。

casez(vote)
7'b???1111,
7'b??1?111,
7'b??11?11,
.... : pass = 1;

defalut: pass = 0;

唯一的问题是列出 7 位系统中 4 位的所有可能组合。我会把它留给你。建议是创建一个测试台并比较循环和 case 语句的结果。

顺便说一句,使用 always @* 而不是 总是@(投票)。养成习惯,以后会避免很多错误。

我看到在 for 循环中你只有一个赋值 (sum = sum + 1)。您可以在没有 case 语句的情况下编写此逻辑。

always@(*)
begin
 sum = |vote ? sum + 1 : 'd0;
 pass = sum[2];
end

但是,如果您只希望有一个 case 语句,请参阅下文

always@(*)
begin
  case(1'd1)
   vote[0] : sum = sum + 1;
   vote[1] : sum = sum + 1;
   vote[2] : sum = sum + 1;
   vote[3] : sum = sum + 1;
   vote[4] : sum = sum + 1;
   vote[5] : sum = sum + 1;
   vote[6] : sum = sum + 1;
   default : sum = 'd0;
 endcase
end