Verilog:从动态输入对齐有效和无效字节

Verilog:从动态输入对齐有效和无效字节,verilog,fpga,Verilog,Fpga,我试图设计一个系统,每个时钟周期接收8字节数据输入和8位有效输入,其中有效输入上的每一位要么验证数据字节,要么使数据字节无效 input wire [63:0] d_in; input wire [7:0] v_in; 程序应按如下方式处理d_,以对齐所有有效字节 (其中B为有效字节,X为无效字节) 实例1: d_in = B1 B2 X X B3 X B4 B5 d_out = B1 B2 B3 B4 B5 X X X 实例2: d_in = X B1 B2 B3 X B4 B5 B6

我试图设计一个系统,每个时钟周期接收8字节数据输入和8位有效输入,其中有效输入上的每一位要么验证数据字节,要么使数据字节无效

input wire [63:0] d_in;
input wire [7:0]  v_in;
程序应按如下方式处理d_,以对齐所有有效字节

(其中B为有效字节,X为无效字节)

实例1:

d_in = B1 B2 X X B3 X B4 B5

d_out = B1 B2 B3 B4 B5 X X X
实例2:

d_in = X B1 B2 B3 X B4 B5 B6

d_out = B1 B2 B3 B4 B5 B6 X X
我以前主要使用算法,每次迭代时所有位操作都是相同的,例如
assignd_out[7:0]=d_in[15:8]
但事实上,有效字节的数量和顺序可以随每个数据输入而改变,这意味着不能使用此策略

我的问题:

有没有办法用Verilog或VHDL实现这个功能?如果是这样的话,有人能告诉我一个高层次的解决方案或一些相关的阅读,这样我就能更好地理解这个概念。我想如果我能在较高的层次上理解,那么我就能够尝试编码它,但目前我甚至不确定我需要编码什么

谢谢
Zach

既然您要求高级别,我将给出一个伪代码示例,说明一些可能有用的东西,或者至少可以让您继续

d_out = '0; //Assuming that the X bytes can be set to zero in the output.
bytes = 0;
for i in range(8)
 if v_in[i]
   d_out[bytes*8 +: 8] = d_in[i*8 +: 8] //Note the +: notation which is not pseudo, but verilog.
   bytes++
现在在always块中执行此顺序代码,您应该被设置


注意:我并不完全清楚合成结果的外观,但我怀疑它将生成相当多的硬件。

既然您要求高级别,我将给出一个伪代码示例,说明一些可能有效的方法,或者至少可以让您继续

d_out = '0; //Assuming that the X bytes can be set to zero in the output.
bytes = 0;
for i in range(8)
 if v_in[i]
   d_out[bytes*8 +: 8] = d_in[i*8 +: 8] //Note the +: notation which is not pseudo, but verilog.
   bytes++
现在在always块中执行此顺序代码,您应该被设置


注意:我并不完全清楚由此产生的合成结果的外观,但我怀疑它将生成相当多的硬件。

我有一些类似的东西,但不太清楚

将数据输入FIFO,使用FIFO条目预先计算字节启用。 在输出端,读取字节启用部分并使用它移出字节。所以字节启用只需要满足八个条件

1 byte, byteEn(0 downto 1) = "10", shift left 1 byte
2 bytes, byteEn(0 downto 2) = "110", shift left 2 bytes
3 bytes, byteEn(0 downto 3) = "1110", shift left 3 bytes
……等等

换档时,使用FIFO读取启用功能读取下一个单词。 注意:当FIFO为空时,您需要注意,但不要停止管道,以便已经存在的数据继续移出


我不知道它会有多复杂,因为我已经稍微掩饰了一下。

我有一些类似的东西,但不完全一样

将数据输入FIFO,使用FIFO条目预先计算字节启用。 在输出端,读取字节启用部分并使用它移出字节。所以字节启用只需要满足八个条件

1 byte, byteEn(0 downto 1) = "10", shift left 1 byte
2 bytes, byteEn(0 downto 2) = "110", shift left 2 bytes
3 bytes, byteEn(0 downto 3) = "1110", shift left 3 bytes
……等等

换档时,使用FIFO读取启用功能读取下一个单词。 注意:当FIFO为空时,您需要注意,但不要停止管道,以便已经存在的数据继续移出


我不知道这会有多复杂,因为我已经掩饰了一点。

哎哟!如果真的没有设置规则/模式,并且在任何位置都可能有任意数量的字节,那么您将得到一些非常深刻的逻辑。知道了这一点,您应该使用FPGA管道功能来预先计算一些嵌套逻辑,分解深度,并为工具提供一些定时释放。这是假设您不想缓冲输入和移出字节,但这同样不是小事。@fpga_magik如果您不介意的话,您可以扩展一下缓冲输入信号和移出字节的含义吗?我对这个解决方案感兴趣。谢谢!如果真的没有设置规则/模式,并且在任何位置都可能有任意数量的字节,那么您将得到一些非常深刻的逻辑。知道了这一点,您应该使用FPGA管道功能来预先计算一些嵌套逻辑,分解深度,并为工具提供一些定时释放。这是假设您不想缓冲输入和移出字节,但这同样不是小事。@fpga_magik如果您不介意的话,您可以扩展一下缓冲输入信号和移出字节的含义吗?我对这个解决方案感兴趣。谢谢你的意见。我从逻辑上理解这种方法,但我担心会有延迟问题,因为每个时钟周期都有新的数据输入,而且这个解决方案不能管道化(据我所知),您担心这一点是正确的。我怀疑逻辑将是深刻的。然而,它应该很容易实现,所以您可以对它进行一次测试,看看结果如何。在管道方面,我认为这个解决方案没有多大帮助。但我想到了合并。也就是说,有点像合并排序,但只对字节数组末尾的X字节进行排序。不确定它是否是一个可行的解决方案。通过将每个循环迭代实例化为一个单独的模块,中间带有寄存器,以存储模块输出,从而创建管道,从而能够管道化原始解决方案。就面积而言,这是令人讨厌的,但面积效率设计并不是一个要求,因为它只需要在功能上工作并满足时间要求。当然还有更优雅的解决方案,谢谢你的投入。我从逻辑上理解这种方法,但我担心会有延迟问题,因为每个时钟周期都有新的数据输入,而且这个解决方案不能管道化(据我所知),您担心这一点是正确的。我怀疑逻辑将是深刻的。然而,它应该很容易实现,所以您可以对它进行一次测试,看看结果如何。在管道方面,我认为这个解决方案没有多大帮助。但我想到了合并。也就是说,有点像合并排序,但只对字节数组末尾的X字节进行排序。不确定它是否是一个可行的解决方案。通过将每个循环迭代实例化为一个单独的模块,中间带有寄存器,以存储模块输出,从而创建管道,从而能够管道化原始解决方案。就面积而言,这是令人讨厌的,但面积