我遇到了综合问题,如果我在if语句中有两个变量,则Synthesis将失败(带有非常误导和无用的错误消息)。
给出下面的代码片段
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循环不能在硬件中实现,除非它是一个定义结束的静态循环。但是如果语句应该起作用,因为它只是两个二进制值之间的比较器。
我在这里尝试做的是,当我的模块接收到一个字节时,它将被添加到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语句条件来解决错误,但仍然想了解为什么会改变任何内容。
答案 0 :(得分:1)
有一些错误会立即出现在代码中,虽然它们可能无法解决这个问题,但它们需要更正,因为它会导致模拟和硬件测试的差异。
nextstate逻辑需要位于不同的always块中,该块不会根据时钟的位置而改变。敏感度列表需要包括“状态”和/或“*”之类的内容。如果你想让nextstate逻辑像现在一样注册(你没有注册),你应该使用非阻塞赋值,这在下面提供的卡片文章中有很多描述。
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类型(我假设您不需要有符号数,因此它在模拟上没有差别),使得这些定义长度,在生成块之外,你应该尽量不让综合玩整数。