Verilog合成在包含两个变量的if语句上失败

Verilog合成在包含两个变量的if语句上失败,verilog,xilinx,synthesis,Verilog,Xilinx,Synthesis,我在合成中遇到了一个问题,如果在if语句中有两个变量,合成就会失败(产生一条非常误导和无用的错误消息) 给出下面的代码片段 case(state) //other states here GET_PAYLOAD_DATA: begin if (packet_size < payload_length) begin packet_size <= packet_size + 1;

我在合成中遇到了一个问题,如果在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
该错误声称下一个状态不正确,但如果我取出
有效负载长度
并为其指定一个静态值,它就可以正常工作。由于数据包大小和有效负载长度都是整数类型,因此它们的大小相同,这不是问题所在。因此,我假设这是一个与for循环类似的问题,for循环不可在硬件中实现,除非它是一个具有定义端的静态循环。但是If语句应该工作,因为它只是两个二进制值之间的一个比较器

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

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

编辑: 按照注释中的要求,说明如何声明数据包大小和有效负载长度的片段

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
整数有效负载长度、数据包大小;
初始开始
//其他东西

packet_size代码中存在一些错误,这些错误可能无法解决此问题,但需要进行纠正,因为这将导致模拟和硬件测试的差异

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

代码应该如下所示:

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 
始终@(*)开始
//与各国的案例陈述
获取有效载荷:
开始
如果(rx_切换==1)开始
数据包大小=1'b1;
//这些将需要以类似的方式进行更改

添加
状态
下一状态
的位范围是多少?
GET_PAYLOAD_DATA
GET_CHKSUM2
的值是什么?state和next_state是4位(reg[3:0]state,next_state),GET_PAYLOAD_DATA和GET_CHKSUM2是分别指定为4'd5和4'd7的参数。假设您使用一个组合块和一个单独的块来分配触发器,然后
packet\u size@Greg这很奇怪,但是我通过将条件语句的顺序从
if(packet\u size
切换到
if(payload\u length>packet\u size)begin
来避开这个错误。对于我来说,合成器为什么会在切换状态下工作,而不是在原始状态下工作,这真的没有多大意义。你能说明数据包大小和有效负载长度的声明吗?组合块应该只使用块分配。参见参考文件第11节。一个好的做法是使用“next”作为网络名称的前缀(或后缀)分配一个flop。e、 g.
addr
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