【发布时间】:2013-06-05 18:29:34
【问题描述】:
我遇到了一个综合问题,如果我在 if 语句中有两个变量,综合将失败(带有非常误导和无益的错误消息)。
给定下面的代码sn-p
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 个字节,我多次回忆这个状态,直到计数器达到限制,然后我将下一个状态设置为其他状态。
然后我的问题是,如何在调用我的状态并重复直到计数器达到有效负载的长度而不出现错误的情况下获得相同的结果?
编辑: 根据 cmets 的要求,如何声明 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 语句条件来绕过错误,但仍然想了解为什么这会改变任何事情。
【问题讨论】:
-
state和next_state的位范围是多少?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_size <= packet_size + 1;应该是next_packet_size = packet_size + 1;保持阻塞(=) 和非在单独的始终块中阻塞(<=)分配。清理它,让我们知道这是否有帮助。 -
@Greg 这很奇怪,但是我通过将条件语句的顺序从
if (packet_size < payload_length) begin切换到if (payload_length > packet_size) begin来解决这个错误。对我来说,为什么合成器会在它切换时工作,而不是在原始时工作,这对我来说真的没有多大意义。 -
能否展示packet_size和payload_length的声明