verilogfpgaxilinxintel-fpgaxilinx-ise

Find Maximum Number present in Verilog array


I have tried writing a small verilog module that will find the maximum of 10 numbers in an array. At the moment I am just trying to verify the correctness of the module without going into specific RTL methods that will to do such a task.

I am just seeing a a couple of registers when I am synthesizing this module. Nothing more that that. Ideally the output should be 7 which is at index 4 but I am seeing nothing neither on FPGA board or in the test bench. What I am doing wrong with this ?


module findmaximum(input clk,rst,output reg[3:0]max, output reg[3:0]index);
    
    
    reg [3:0]corr_Output[0:9];
    
    always@(posedge clk or posedge rst)  
    
    if(rst)
    begin
    corr_Output[0]=0;
    corr_Output[1]=0;
    corr_Output[2]=0;
    corr_Output[3]=0;
    corr_Output[4]=0;
    corr_Output[5]=0;
    corr_Output[6]=0;
    corr_Output[7]=0;
    corr_Output[8]=0;
    corr_Output[9]=0;
    end
    
    else
    
    begin
    corr_Output[0]=0;
    corr_Output[1]=0;
    corr_Output[2]=0;
    corr_Output[3]=0;
    corr_Output[4]=7;
    corr_Output[5]=0;
    corr_Output[6]=0;
    corr_Output[7]=0;
    corr_Output[8]=0;
    corr_Output[9]=0;
    end
    
    integer i;
    
    always@(posedge clk or posedge rst) 
    
    if(rst)
    begin
    max=0;
    index=0;
    end
    
    else
    
      begin
      max = corr_Output[0];
      for (i = 0; i <= 9; i=i+1)
      begin
        if (corr_Output[i] > max)
        begin
           max  = corr_Output[i];
           index = i;
                         end
                     end 
                end   
    
    
    endmodule

Solution

  • Looking are your code, the only possible outputs are max=0,index=0 and a clock or two after reset max=7,index=4. Therefore, your synthesizer is likely optimizing the code with equivalent behavior with simpler logic.

    For your find max logic to be meaningful, you need to change the values of corr_Output periodically. This can be done via input writes, LFSR (aka pseudo random number generator), and or other logic.

    Other issues:
    Synchronous logic (updated on a clock edge) should be assigned by with non-blocking (<=). Combinational logic should be assigned with blocking (=). When this guideline is not followed there is a risk of behavior differences between simulation and synthesis. In the event you need to compare with intermediate values (like your original max and index), then you need to separate the logic into two always blocks like bellow. See code bellow.

    Also, FPGAs tend to have limited asynchronous reset support. Use synchronous reset instead by removing the reset from the sensitivity list.

    always@(posedge clk) begin
      if (rst) begin
        max <= 4'h0;
        index <= 4'h0;
      end
      else begin
        max <= next_max;
        index <= next_index;
    end
    
    always @* begin
      next_max = corr_Output[0];
      next_index = 4'h0;
      for (i = 1; i <= 9; i=i+1) begin // <-- start at 1, not 0 (0 is same a default)
        if (corr_Output[i] > next_max) begin
          next_max  = corr_Output[i];
          next_index = i;
        end
      end 
    end