2

So I've used generate statements to make some oscillators in a testbench that I've been working on.

I also have an array of reals called OSC_PER where each element in the array is the period in ns for the oscillator.

I've been trying to make my testbench work such that I give it a parameter (number of devices to test) and the generate statements in my testbench and simulation go out, instantiate the modules and wire everything up. So far, this has been going well, but I think I've ran into a wall with assigning the periods to my oscillators.

generate
  for(i=1; i<=num_duts; i++)
  begin: generate_my_oscillators
    osc osc_c_osc( .en(osc_en[i]), .out(osc_c[i]));
  end
endgenerate

So here's how I've tried to assign the values:

foreach(OSC_PER[i])
  generate_my_oscillators[i].osc_c_osc.per = OSC_PER[i];

This gives me a NOTPAR error; I guess it's illegal to try and iterate over the instance number outside of a genvar statement. Okay, so maybe I can be brute and just lay it all out manually:

generate_my_oscillators[1].osc_c_osc.per = OSC_PER[1]
if(number_devices >= 2)
generate_my_oscillators[2].osc_c_osc.per = OSC_PER[2]
if(number_devices >= 3)
generate_my_oscillators[3].osc_c_osc.per = OSC_PER[3]
.
.
.

However, if I have number_devices = 2, then on the third conditional, I get CUVFGS (Invalid for-generate index) followed by a CUVUNF (failure to lookup the component name for the third device).

If I have values I want to assign to each instance of the oscillator being generated, how should I go about doing that? I'm a little stumped at this point. Maybe I can have it assigned in the generate-for loop?

EDIT: I've tried some more things:

If I move over the definitions of OSC_PER to my testbench and attempt to assign the value of the period in the generate statement like this I get EXPEND "Expecting keyword 'end'":

generate
  for(i=1; i<=num_duts; i++)
  begin: generate_my_oscillators
    osc osc_c_osc( .en(osc_en[i]), .out(osc_c[i]));
    .per = OSC_PER[i];
  end
endgenerate

Okay, I tried this:

generate
  for(i=1; i<=num_duts; i++)
  begin: generate_my_oscillators
    osc osc_c_osc( .en(osc_en[i]), .out(osc_c[i]));
    osc_c_osc.per = OSC_PER[i];
  end
endgenerate

... and I get EXPLA: expecting left parenthesis.

period is an internal signal in each osc, so I cannot place it as such:

generate
  for(i=1; i<=num_duts; i++)
  begin: generate_my_oscillators
    osc osc_c_osc( .en(osc_en[i]), .out(osc_c[i]), .per(OSC_PER[i]);
  end
endgenerate

If I do, I get CUVPOM: Port name 'per' is invalid or has multiple connections.

Now I'm really out of ideas. Any suggestions?

1
  • Is per a parameter, reg, or wire? Commented Jun 9, 2016 at 21:36

1 Answer 1

1

If per is a parameter the recommend way to assign it is:

generate
for(i=1; i<=num_duts; i++) begin: generate_my_oscillators
  osc #( .per(OSC_PER[i]) ) osc_c_osc( .en(osc_en[i]), .out(osc_c[i]) );
end
endgenerate

Alternatively parameter can be assigned with a defparam. This is discurraged as this feature is being considered for depreciation (IEEE Std 1800-2012 § C.4.1)

generate
for(i=1; i<=num_duts; i++) begin: generate_my_oscillators
  osc osc_c_osc( .en(osc_en[i]), .out(osc_c[i]) );
  defparam osc_c_osc.per = OSC_PER[i];
end
endgenerate

Assigning internal values across hierarchical boundaries is not synthesizable. But it is allowed for simulation.

If per is a internal wire then it should be assigned with an assign statement. If per is a reg, integer, real, etc., and OSC_PER is a constant (eg: parameter, `define) then use an initial statement, else an always @*.

generate
for(i=1; i<=num_duts; i++) begin: generate_my_oscillators
  osc osc_c_osc( .en(osc_en[i]), .out(osc_c[i]) );
  // Pick one based on the type of per and OSC_PER
  //assign osc_c_osc.per = OSC_PER[i]; // per is a wire
  //initial osc_c_osc.per = OSC_PER[i]; // per is non-wire and OSC_PER is a constant
  //always @* osc_c_osc.per = OSC_PER[i]; // per & OSC_PER are non-wire variables
end
endgenerate

If per is not a parameter and you want it to be synthesizable, then add it to the port list. This reqiures modifying the osc module itself. Be aware that floating-point (eg real) can work as ports in SystemVerilog for simulation, but is not synthesizable.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.