Calvin Wong wrote:
> Suraj Kurapati wrote:
>> Since the scheduler waits for *all* threads to either (1)
>> terminate or (2) invoke the "wait" or "advance_time" method, we
>> cannot have non-verification-related threads running in the
>> background.
> 
> Yes ... I am currently encountering this. I created two clocks
> and am driving the clocks in verilog.

Please post your Verilog code also.

> I created two threads and had each of them wait for a posedge
> of their particular clock and print out the simulation time.
>
> t1 = Thread.new do
>  5.times do |i|
>    wait until Test.clk0.posedge?
>    puts "@#{simuilation_time} clk0 seen"
>  end
> end
>
> t2 = Thread.new do
>  5.times do |i|
>    wait until Test.clk1.posedge?
>    puts "@#{simulation_time} clk1 seen"
>  end
> end
>
> t1.join
> t2.join
>
> Adding the t1.join and the t2.join causes the simulation to
> lock up.

Correct.  There is no need to join the threads manually; the
scheduler will take care of it behind the scenes.

> If I remove t1 and t2, then the simulation proceeds but in a
> single thread fashion.  Meaning ... t1 runs first, with a lot of
> delay in between, then t2 runs.

Correct, AFAIK Ruby uses green threads in a non-preemptive,
cooperative fashion.  You can set thread priorities using
Thread.priority= to make things more preemptive.

>> is there a better Verilog-related name for the creation of a 
>> verification-related thread than "process"?  How would you like
>> to name this method?
> 
> In my previous projects, we have a C++ verification based
> environment and we used the following terminology for running
> many processes in parallel. 
> 
> c_fork
>  // Process A
>  c_fork_begin
>    for (i=0;i<10;i++) atPosedge("top.clk0");
>  c_fork_end
>
>  // Process B
>  c_fork_begin
>    for (i=0;i<10;i++) atPosedge("top.clk1");
>  c_fork_end
> c_join_all // could also be c_join_any or c_join_none
> 
> c_join_all indicates that all processes needs to be completed 
> prior to exiting the fork block.  c_join_any needs only one
> process to complete prior to exiting, and c_join_none immediately
> exits the block and allows them to run in the background.

Thanks for this insight.  This appears to be a complex interface for
solving (more) complex problems.  I'll stick with process() for now
and evolve my concurrency interface, as necessary, later on.

----

By the way, I have checked in a revised concurrency implementation
(which includes the process() method) into the code repository.
Please try that and see if it solves the problems you mentioned above.

Note that you have to replace:

  t1 = Thread.new do
    ...
  end

with:

  t1 = process do
    ...
  end

Reply via email to