32 位数组 Verilog 中 1 的最大位块

Maximum block of bits of 1 in a 32 bits array Verilog

我是Verilog的初学者,我有这个任务。

max_pass 电路过滤一个 32 位数组,使得最大长度的位块 1 保留在位置上,其他所有内容都变为 0。

一个block/set由最少2位的1组成。

电路必须组合,max_pass模块的接口为:

input  [31:0] din  ;
output [31:0] dout ;

电路没有记忆。输出会立即看到输入的任何变化。

建议采用模块化分层设计

例子

Example 1   
input:      01011100111111111111011100101010
output:     00000000111111111111000000000000
The maximum length of a block is 12.

Example 2   
input:      00100111111001001011111100101101
output:     00000111111000000011111100000000
Two blocks of maximum length of 6.

Example 3   
input:      11011011011011011011011011011011
output:     11011011011011011011011011011011
Eleven blocks of maximum length of 2.

@摩根

我想到了解决办法。使用 MUX-DMUX 电路,我可以比较 2 个 2 位的数字,假设 M,N 和函数 return 1 if M>N(如果 M=N= 则可以修改为 return 1 11也)。因此,我有一个 32 位数组并开始使用该算法进行比较。 现在,我不确定如何找到最长的块。

2 numbers M=ab N=cd

MUX-DMUX circuit

我们以 16 位为例。

输入:0101 1100 0110 1110 我们有 2 个最大的 3 位块。

位置向量:0001 0000 0000 1000

输出应如下所示:0001 1100 0000 1110

位置向量包含与最大块最左边的 1 位对齐的 1 位。 位置向量是通过将输入向左移动 1,然后在两个数组之间应用 AND 运算,重复该过程,直到我们得到向量。

示例:

         Input:   0101 1100 0110 1110
    Shift left:   1011 1000 1101 1100   
 AND operation:   0001 1000 0100 1100
Shift left again: 0011 0000 1001 1000
AND with input:   0001 0000 0000 1000  --> Location vector

输出在与位置向量相同的位置(在本例中为位置 3 和 12,从右到左计数)有一个 1 位。

第3位的1: 当且仅当位置 3 的输出为 1 并且输入向量在位置 2 为 1 时,前一个位置(位置 2)的输出为 1。 当且仅当位置 2 的输出为 1 且输入向量在位置 1 为 1 时,位置 1 的输出为 1。

对于第12位的1: 当且仅当位置 12 的输出为 1 且输入向量在位置 11 为 1 时,前一个位置(位置 11)的输出为 1。 当且仅当位置 11 的输出为 1 且输入向量在位置 10 为 1 时,位置 10 的输出为 1。

您看到这将如何将最大块位级联到输出了吗?本质上,位置向量中的位用作触发器,输入向量中的位用于维持输出的 1 位脉冲,只要它们持续。

问题是我不确定如何实施此行为代码以及这是否是一个好的解决方案。

我在等你的意见ideas.Thanks!

一些正在进行的工作:找到最大块大小,并计算位置向量。

block_is[i]表示块大小为i或更大时。

确定最大块大小并将位置向量的移位数或运算在一起以创建输出。

module tb;
  reg [15:0] seq;
  reg [15:0] loc_vector;
  reg [15:0] block_detect;



  initial begin
    #1ps seq = 16'b0101_1100_0110_1110;
    #10ns;
    $displayb(loc_vector);
    $displayb(block_detect);
    $finish();
  end

  reg [15:0] block_is = 16'b0;
  reg  [3:0] max_block;  //integer max of block_is 

  always @* begin
    block_is[0] = ~|seq; //All 0
    block_is[1] = |seq;  //Atleast 1
    block_is[2] = 
    (seq[15:14] == 2'b11) |
    (seq[14:13] == 2'b11) |
    (seq[13:12] == 2'b11) |
    (seq[12:11] == 2'b11) |
    (seq[11:10] == 2'b11) |
    (seq[10: 9] == 2'b11) |
    (seq[ 9: 8] == 2'b11) |
    (seq[ 8: 7] == 2'b11) |
    (seq[ 7: 6] == 2'b11) |
    (seq[ 6: 5] == 2'b11) |
    (seq[ 5: 4] == 2'b11) |
    (seq[ 4: 3] == 2'b11) |
    (seq[ 3: 2] == 2'b11) |
    (seq[ 2: 1] == 2'b11) |
    (seq[ 1: 0] == 2'b11) ; 

    block_is[3] =
    (seq[15:13] == 3'b111) |
    (seq[14:12] == 3'b111) |
    (seq[13:11] == 3'b111) |
    (seq[12:10] == 3'b111) |
    (seq[11: 9] == 3'b111) |
    (seq[10: 8] == 3'b111) |
    (seq[ 9: 7] == 3'b111) |
    (seq[ 8: 6] == 3'b111) |
    (seq[ 7: 5] == 3'b111) |
    (seq[ 6: 4] == 3'b111) |
    (seq[ 5: 3] == 3'b111) |
    (seq[ 4: 2] == 3'b111) |
    (seq[ 3: 1] == 3'b111) |
    (seq[ 2: 0] == 3'b111) ; 

    //etc complete for block_is 4 to 14

    block_is[15] = &seq; //AND reduction all 1's

    loc_vector = seq;
    if (block_is[1]) begin
      //always do first shift if have block of 1
      loc_vector = loc_vector & (seq << 1);
    end
    if (block_is[2]) begin
      //do second shift if have at least a block of 2
      loc_vector = loc_vector & (seq << 2);
    end

    //Find max Block Size
    for (int i=0; i<16; i=i+1) begin
      if (block_is[i]) begin
        max_block = i;
      end
    end

    block_detect = loc_vector;
    //Turn Location Vectors in to max_blocks
    for (int i=2; i<16; i=i+1) begin
      if ( max_block >=i )
        block_detect = block_detect | (loc_vector >> (i-1));
    end
  end

endmodule

输出:

0001000000001000
0001110000001110