在verilog中重建可变大小的数据包

时间:2013-05-24 16:00:28

标签: verilog cpu-registers packets

我正在尝试重建通过UART RS232连接发送的数据包,但我不确定如何完整地重建数据包,以便可以拆分数据包,并且可以使用它完成任务。

问题在于,当我一次接收1个字节时,我将该字节存储到8位宽的寄存器中,当我收到下一个字节时,我希望能够将第一个字节移位8位,然后将新字节添加到结尾。这成为一个问题,因为寄存器现在太小(8位对16位保持下一个字节)。另外,我无法看到在运行时根据数据包的大小来改变寄存器大小的方法,因为所有寄存器必须是静态的,并且我还必须知道数据包的确切大小才能处理它。

有可能设置一个疯狂的大寄存器来保存数据包,并计算有多少有效字节被复制到寄存器中,但我相信有更好的方法可以做到这一点,我没有看到。

所有这些都是使用Xilinx ISE完成的。

1 个答案:

答案 0 :(得分:0)

Verilog模仿物理设计是静态的。您需要知道可以支持的最大字节数。要知道输入的大小,只要数据字节移位就不能胜任计数器。获得动态大小的唯一方法是,如果这是用于非可合成行为建模,那么您可以使用C代码链接到您的设计(PLI / VPI / DPI)或SystemVerilog队列(IEEE Std 1800-2012第7.10节)。如果您有兴趣,请阅读有关SystemVerilog的信息。

以下是大型移位寄存器的Verilog示例:

parameter SIZE = 2**10;
reg [SIZE*8-1:0] store;
always @(posedge clk or negedge rst_n) begin
  if ( !rst_n ) begin
     counter <= 0;
     store <= {(SIZE*8){1'b0}};
  end
  else if ( push_in ) begin
     counter <= first_byte ? 0 : (counter+1);
     store <= {store[SIZE*8-1-8:0], data_in[7:0]};
  end
end

使用“疯狂的大寄存器”,您可能需要将store拆分成块,以便模拟器可以处理它;一些模拟器无法处理reg [2**32-1:0] store;。 Sudo代码示例:

// ...
storeN <= {store3[SIZE*8-1-8:0], storeM[7:0]};
// ...
store1 <= {store1[SIZE*8-1-8:0], store0[7:0]};
store0 <= {store0[SIZE*8-1-8:0], data_in[7:0]};
// ...