2
votes

I need to randomize a large memory. All of the data is contained inside of latch modules -- 1 per bit.

How do I fix the following?

// Quick mock up of the memory, which I can't change
`define WIDTH 64*144

module latch(
  output reg Q);
endmodule

module memory;
  wire [`WIDTH-1:0] latchData;
  latch latch[`WIDTH-1:0] (.Q(latchData[`WIDTH-1:0]));
endmodule

// My testbench, which I can change
module test;

  reg [31:0] index;

  memory memory();

  initial begin
    $display("Initial data: %0d", memory.latchData);
    injectRandomData();
    $display("Randomized data: %0d", memory.latchData);
  end

  task injectRandomData();
    // Using for loop does not work
    //for (index=0; index < `WIDTH; index = index+1) begin
    //  memory.latch[index].Q = $urandom;
    //end

    // Doing it this way seems terrible
    memory.latch[0].Q = $urandom;
    memory.latch[1].Q = $urandom;
    memory.latch[2].Q = $urandom;
    // ... a bunch more to go; don't wait up

  endtask

endmodule

Code on EDA Playground: http://www.edaplayground.com/s/4/235

2

2 Answers

3
votes

Quick and dirty solution:

task injectRandomData();
  ->do_InjectRandomData;
  #0; // gen always block a change to finish;
endtask

event do_InjectRandomData;
genvar index;
generate
  for(index = 0; index < `WIDTH; index = index +1) begin : gen_loop
    always @(do_InjectRandomData) begin : set_rand
      memory.latch[index].Q = $urandom;
    end
  end
endgenerate

Code on EDA Playground: http://www.edaplayground.com/s/6/236

3
votes

You cannot dynamically index an array of instances. Two ways to fix this:

  1. Do you really need to model a memory at such a low level? Change the memory model to an RTL description. It will be much better for performance anyways.
  2. Use a generate block with a for-loop around the initial block instead of a for-loop inside the initial block. If you need to do this at some time other than time 0 you can use an event to trigger it.
genvar index;
event injectRandomData;
for (index=0; index &lt `WIDTH; index++) begin
   always @injectRandomData
      memory.latch[index].Q = $urandom; 
end