DuttaA
DuttaA

Reputation: 923

Delays in for loop

So i am writing a code for DES.But now i have hit a roadblock which i cant pass.

module initialPermutation(cipher,plain);
  output reg [63:0]cipher;
  input [63:0]plain;
  integer i,j,k;
  
  initial
    begin
      for(i=57,k=0;i<=63;i=i+2)
        begin
          for(j=i;j>=i-56;j=j-8,k=k+1)
            begin
              cipher[k]=plain[j];
            end
        end
      for(i=56;i<=62;i=i+2)
        begin
          for(j=i;j>=i-56;j=j-8,k=k+1)
            begin
              cipher[k]=plain[j];
            end
        end
    end
endmodule  

This is the initial permutation which runs perfectly fine...but for the final permutation..

module finalPermutation(cipher,plain);
  output reg [63:0]cipher;
  input [63:0]plain;
  integer i,c;
  
  initial
    begin
      for(i=39,c=0;i>=32;i=i-1,c=c+1)
        cipher[0+c*8]=plain[i];
      
      for(i=7,c=0;i>=0;i=i-1,c=c+1)
          cipher[1+c*8]=plain[i];
 
      for(i=47,c=0;i>=40;i=i-1,c=c+1)
          cipher[2+c*8]=plain[i];
      
      for(i=15,c=0;i>=8;i=i-1,c=c+1)
          cipher[3+c*8]=plain[i];
      
      for(i=55,c=0;i>=48;i=i-1,c=c+1)
          cipher[4+c*8]=plain[i];
      
      for(i=24,c=0;i>=16;i=i-1,c=c+1)
          cipher[5+c*8]=plain[i];
      
      for(i=63,c=0;i>=56;i=i-1,c=c+1)
          cipher[6+c*8]=plain[i];
      
      for(i=31,c=0;i>=24;i=i-1,c=c+1)
          cipher[7+c*8]=plain[i];
     
    end
endmodule

this is the code.....it does not run and gives only "xxxx...."...but if i write it like this...

module finalPermutation(cipher,plain);
  output reg [63:0]cipher;
  input [63:0]plain;
  integer i,c;
  
  initial
    begin
      #1;
      for(i=39,c=0;i>=32;i=i-1,c=c+1)
        cipher[0+c*8]=plain[i];
      
      for(i=7,c=0;i>=0;i=i-1,c=c+1)
          cipher[1+c*8]=plain[i];
 
      for(i=47,c=0;i>=40;i=i-1,c=c+1)
          cipher[2+c*8]=plain[i];
      
      for(i=15,c=0;i>=8;i=i-1,c=c+1)
          cipher[3+c*8]=plain[i];
      
      for(i=55,c=0;i>=48;i=i-1,c=c+1)
          cipher[4+c*8]=plain[i];
      
      for(i=24,c=0;i>=16;i=i-1,c=c+1)
          cipher[5+c*8]=plain[i];
      
      for(i=63,c=0;i>=56;i=i-1,c=c+1)
          cipher[6+c*8]=plain[i];
      
      for(i=31,c=0;i>=24;i=i-1,c=c+1)
          cipher[7+c*8]=plain[i];
     
    end
endmodule

where i have inserted a delay after initial statement it runs perfectly fine...both initalPermutation and finalPermutation looks quite same yet one does not run without delay...where is the difference??? And what should i do to remove the delay in finalPermutation? here is the stimulus block for refernce...

module stimulus;
  reg [63:0]plain;
  wire [63:0]out;
  reg [63:0]key;
  
  finalPermutation i(out,plain);
  initial
    begin
      plain=64'b110001111;
      #2 $display("%b ",out);
    end
endmodule

Upvotes: 0

Views: 2773

Answers (2)

Greg
Greg

Reputation: 19104

initial statements and blocks run only one at time 0. If there are multiple initials in the simulation, then there is no guaranteed determinate order in evaluating them. The IEEE1364 (Verilog) & IEEE1800 (SystemVerilog) intentionally allows this type of indeterminism. Simulators tend the order the evaluation based on compiling and instantiation order. You need to write your code in a way that it will not be impacted by this scheduling order.

With initial blocks and statements, there should be no dependence on non-constants. The only exception is for non-synthesizer code (like testbenches and behavioral models for analog components) after blocking statements.

When depended on input signals, combinational RTL logic should use always_comb (SystemVerilog) or always @* (Verilog). If you get to choose between Verilog and SystemVerilog, go the SystemVerilog route. always @* does not guaranty to be evaluated at time-0 (optional for simulator). Sequential RTL logic should use always_ff @(...) (SystemVerilog) or always @(...) (Verilog), where ... in a posedge or negedge clocking signal.

In initialPermutation and finalPermutation change initial to always_comb and you should get the non-X results. If you go with the Verilog always @* strategy, then you may want to add a #1 before assigning plain in your testbench.

Upvotes: 0

dave_59
dave_59

Reputation: 42673

You have a race condition. All initial blocks in all modules execute concurrently. So if your stimulus module's initial block executes after the other initial block, the other blocks do not see a change on their inputs.

But one does not model hardware with initial blocks. They need so be models sensitive to their inputs for combinational logic, or to the edge of a clock for sequential logic.

Upvotes: 1

Related Questions