2

我遇到了一个综合问题,如果我在 if 语句中有两个变量,综合将失败(带有非常误导和无益的错误消息)。

鉴于下面的代码片段

case(state)
//other states here
GET_PAYLOAD_DATA:
        begin
                if (packet_size < payload_length) begin
                    packet_size <= packet_size + 1;
                    //Code to place byte into ram that only triggers with a toggle flag
                    next_state = GET_PAYLOAD_DATA;
                end else begin
                    next_state = GET_CHKSUM2;
                end
end

在综合过程中,我在Xilinx ISE中遇到错误:

 ERROR:Xst:2001 - Width mismatch detected on comparator next_state_cmp_lt0000/ALB. Operand     A and B do not have the same size.

该错误声称 next_state 不正确,但是如果我取出payload_length 并为其分配一个静态值,它就可以正常工作。由于 packet_size 和 payload_length 都是整数类型,它们的大小相同,这不是问题。因此,我认为它与无法在硬件中实现的 for 循环类似的问题,除非它是具有定义结束的静态循环。但是 If 语句应该可以工作,因为它只是 2 个二进制值之间的比较器。

我在这里尝试做的是,当我的模块接收到一个字节时,它将被添加到 RAM 中,直到达到整个有效负载(我从早期的数据包数据中获得)的大小,然后更改为不同的状态处理校验和。由于数据一次只输入 1 个字节,我多次回忆这个状态,直到计数器达到限制,然后我将下一个状态设置为其他状态。

那么我的问题是,如何实现调用状态的相同结果并重复直到计数器达到有效负载的长度而不出现错误?

编辑: 根据评论中的要求,如何声明 packet_size 和 payload_length 的片段

integer payload_length, packet_size;

initial begin
    //other stuff
    packet_size <= 0;
end

always @ (posedge clk) begin
    //case statements with various states
    GET_PAYLOAD_LEN:
        begin
            if (rx_toggle == 1) begin
                packet_size <= packet_size + 1;
                addr <= 3;
                din <= rx_byte_buffer;
                payload_length <= rx_byte_buffer;
                next_state = GET_PAYLOAD_DATA;
            end else begin
                next_state = GET_PAYLOAD_LEN;
            end
        end

rx_byte_buffer是我的模块接收的 8 位宽的输入数据的寄存器,同时packet_size在您在上面看到的机器的各种其他状态中递增。

我通过切换 if 语句条件来解决错误,但仍然想了解为什么这会改变任何事情。

4

1 回答 1

1

代码中有一些错误会立即出现,虽然它们可能无法解决这个问题,但需要纠正它们,因为它会导致模拟和硬件测试的差异。

nextstate 逻辑需要在一个不同的 always 块中,该块不会根据时钟的位姿而改变。敏感度列表需要包括“状态”和/或“*”之类的内容。如果您希望像现在一样注册 nextstate 逻辑(您不这样做),您应该使用非阻塞赋值,这在下面提供的 cummings 论文中有大量描述。

http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA_rev1_2.pdf

代码应如下所示:

always @ (*) begin
    //case statements with various states
    GET_PAYLOAD_LEN:
        begin
            if (rx_toggle == 1) begin
                packet_size_en = 1'b1;
    //these will need to be changed in a similar manner 
                addr <= 3;
                din <= rx_byte_buffer;
                payload_length <= rx_byte_buffer;
    /////////////////////////////////////////////////////
                next_state = GET_PAYLOAD_DATA;
            end else begin
                next_state = GET_PAYLOAD_LEN;
            end
        end

always@(posedge clk) begin 
   if(pcket_size_en)
       packet_size <= packet_size +1 ;
end 

另外,我要尝试的第一件事是通过将它们设为 reg 类型来使它们成为定义的长度(我假设您不需要带符号的数字,因此它在模拟上应该没有区别),在生成块之外,您应该尽量不要让综合与整数一起玩。

于 2013-06-05T22:44:07.233 回答