Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute a for loop over multiple clock cycles?

Tags:

verilog

The for loop is working properly , but everything is happening in a single clock cycle. How I make it run a single iteration per cycle?

   `timescale 1ns/10ps
    module multiplier (clock,multiplier,multiplicand,start,done,product);

    input   [7:0]   multiplier ,multiplicand;
    input           start;
    input           clock;
    output  [15:0]  product;
    output          done;

    reg     [15:0]  multiplierF ,multiplicandF;
    reg     [15:0]  productF;
    reg             doneF;

    integer i;

    assign product  =   productF;
    assign done     =   doneF;

    task rpa_16;

    input   [15:0]      multiplierF;
    inout   [15:0]      productF;

    assign productF = multiplierF + productF;

    endtask

    always @ (posedge clock or posedge start)
    begin
    if(start)
        begin
            multiplierF     =   0 ;
            multiplicandF   =   0 ;
            productF        =   0 ;
            doneF           =   0 ;
        end
    else
        begin
            multiplierF     =   {8'b0,multiplier};
            multiplicandF    =   {8'b0,multiplicand};  
        end        
    end


    always @(posedge clk)
    begin
            if(!doneF)
                begin
                    for (i=0;i<7;i=i+1)
                        begin
                            if(multiplicand[i])
                                begin
                                rpa_16(multiplierF,productF); 
                                multiplierF =  multiplierF << 1;
                                productF     = productF;                       
                                end
                            else
                                begin
                                multiplierF = multiplierF << 1;
                                end
                        end
                    doneF = 1;
                end
    end
like image 570
user2128682 Avatar asked Feb 25 '26 00:02

user2128682


1 Answers

I cant paste a picture of the waveform , but I want i to increment after each positive edge . But whats happening is , for loop executes in a single clock cycle and I get the output.

For loops do not imply anything sequential in verilog. If you want a loop that takes 8 clock cycles, then you'll have to rewrite it with an explicit counter variable, perhaps something like this:

always @(posedge clk or negedge reset_)
if(!reset_) begin
   multiplierF <= 0;
   loopcount   <= 0;
   doneF       <= 0;
end else begin
  if(!doneF) begin
     loopcount <= loopcount + 1;
     if(multiplicand[loopcount]) begin
       rpa_16(multiplierF,productF); 
       multiplierF =  multiplierF << 1;
       productF    = productF;                       
     end else begin
       multiplierF = multiplierF << 1;
     end
  end
  if(loopcount == 7) doneF <= 1;
end

Also, you should not be assigning variables like multiplierF in multiple always blocks, you will get non-deterministic behavior and will likely fail to synthesize. On posedge clk both blocks will execute and you cannot know which one will execute last, so it may give different results on different simulators.

like image 142
Tim Avatar answered Feb 27 '26 01:02

Tim



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!