Jordan.M
Jordan.M

Reputation: 1

SystemVerilog equivalent of C while loop

I am attempting to write a synthesizable systemverilog construct similar to the C code below. From a given range (0 to 9), a number is provided. The goal is then to randomly select another number from the range that does not match the number that has already been provided. I am using an 8-bit Galois LFSR PRNG for the randomness. I just don't know how then to select the alternate number without a while loop to correct a duplicate choice. Any suggestions?

Lets say the number already provided is 5:

const int RANGE = 10;
int given_no = 5;
int other_no = rand() % RANGE;
while(other_no == given_no) {
  other_no = rand() % RANGE;
}

For those who do not code in C, rand() simply returns a random integer between 0 and a value called RAND_MAX (lets assume RAND_MAX = 0xFFFF). % RANGE simply determines the remainder from division by RANGE. Hence the line rand() % RANGE is simply generating a random integer from 0 to 9.

Output:

Assuming the first call of rand() % RANGE before the while loop generates a value other than 5 (for example 4), the while loop never runs. The variable would be:

given_no = 5 
other_no = 4

If on the first call rand() % RANGE returns 5, the while loop will run and generate a second random number between 0-9. This will continue until the random number generated is not 5. Like so . .

given_no = 5
other_no = 5
other_no = 5
other_no = 4

An SV module to do this would look something like this ->

// 8-bit LFSR Pseudo-Random Number Generator
'include "lfsr8.sv"

module second_choice (
  // A random number between 0 - 9 that is not the same as fst_val
  output logic [3:0] snd_val,
  // Pre-given number between 0 - 9
  input logic [3:0] fst_val,
  // Possible system-wide signals
  input logic clk, enable_lfsr, enable_snd_choice
);

  // Random 8-bit value from lfsr
  logic [7:0] rand_out

  lfsr8 lfsr8_inst(.rand_out(rand_out), .enable_lfsr(enable_lfsr), .clk(clk));

  always_ff@(posedge clk)
    begin
        if(enable_snd_choice)
          begin
            {{System verilog code to determine snd_val}}
            snd_val <= {{random value between 0 - 9 that != fst_val}}
          end
    end

endmodule

I know enough about systemverilog to know that loops are only synthesizable if the number of iterations is known at compile time. In this instance, the number of iterations is not known. I am therefore looking for an alternative way to do this.

Upvotes: 0

Views: 291

Answers (1)

PhilMasteG
PhilMasteG

Reputation: 3185

As you have guessed, you simply cannot do this in a single clock cycle (or an unbounded while loop).

To achieve something like this, you will have to check on each clock cycle whether the random number is equal to the given number. If that is the case, set the snd_val_valid-output to low (see below).

Otherwise, write the unequal random number into the snd_val output of the module and also set an additional snd_val_valid-output to high, so that the "downstream" modules have a way of determining whether your calculation has already finished or not.

Also, you might want to think about implementing a small state machine, so that you are more flexible about accepting new inputs, stopping after the first unequal number, etc.

Upvotes: 1

Related Questions