如何在 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
下面是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