Search code examples
arraysmoduleverilogbitmaxlength

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


I am a beginner in Verilog and I have this task.

max_pass circuit filters an array of 32 bits such that the blocks of bits 1 of maximum length remain on position and everything else becomes 0.

A block/set is consisted of minimum 2 bits of 1.

The circuit has to be combinational and the interface of the max_pass module is:

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

The circuit has no memory. Output immediately sees any changes in input.

It is recommended to use modular and hierarchical design.

Examples

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.

Solution

  • A bit of work in progress: to find the maxim block size present, and calculate the location vector.

    block_is[i] represents when there is a block size of i or greater.

    Identify max block size and OR the shifted number of location vectors together to create the output.

    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
    

    Which outputs:

    0001000000001000
    0001110000001110