HDLBITS-Popcount255 for循环中非阻塞赋值的自加问题

官方答案:

module top_module (
	input [254:0] in,
	output reg [7:0] out
);

	always @(*) begin	// Combinational always block
		out = 0;
		for (int i=0;i<255;i++)
			out = out + in[i];
	end
	
endmodule

我的正确答案:

module top_module( 
    input [254:0] in,
    output [7:0] out );

    reg [7:0] i,j;
    always//@(in)
        begin
            //j <= 0;
            for (i=0;i<=254;i=i+1)
                begin
                    if (i==0) j=0;
                    if(in[i]==1) j = j+1;
                   else j = j+0;
                end
            out = j;
        end
    //assign out= j;
endmodule

遇到的错误:

module top_module( 
    input [254:0] in,
    output [7:0] out );

    reg [7:0] i,j;
    always//@(in)
        begin
            //j <= 0;
            for (i=0;i<=254;i=i+1)
                begin
                    if (i==0) j<=0;
                   if(in[i]==1) j <= j+1;
                   else j <= j;
                end
            out <= j;
        end
    //assign out= j;
endmodule

 在for循环中使用非阻塞赋值时,发现out并没有被赋值。

但整段代码和前面我的正确答案只差for循环中的阻塞与非阻塞赋值,因此猜测时always中非阻塞赋值的特性决定了,所有非阻塞的算式右边的值时等到always结束后赋值给左边的,而对于for循环中自加的过程,j最终会被赋予等于循环数个值(比如此例中256个值在always执行完毕后被赋给j),这种同时给j赋予多个不同的值的过程导致了错误,因此j最终值不确定。

而对于阻塞赋值,等号右边的值立马被赋给左边,因此不会导致问题,每一次循环后j的值都会更新,而不是最终一次更新。

但并不代表for循环中不能用非阻塞赋值,猜测只是这种涉及在for循环中多次更新变量值的运算需要小心。当然另一个更重要的是,用(*)的时候就是组合逻辑 严格是要用阻塞赋值,虽然用非阻塞赋值也可以进行仿真 但是在一定条件下 会有赋值错误的bug(群友原话)。

不过我猜测在时序逻辑中应该也不能在for循环中写非阻塞,毕竟能预料到也会出现赋多个值的问题。

顺便补充一下,always(*)和always直接写(无括号内的敏感条件)的本质区别在于,后者是不可综合的。

这是我遇到阻塞与非阻塞赋值差异最大的一次,主要是由于对硬件理解不够。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值