2011年8月3日 星期三

sample simulation env

底下寫了個 pseudo code for sample simulation.主要建立起每個 Signal 的 class. 在依序填入 Signallist 中,之後根據現在的 time cycle 取得 runnable 的 Signal, 取得 Signal 後,根據其 Driver 的 Method 做動作.如果其 Method 會 Driver 到其他的 input/inout Signal, 再把其 Driver 的 Signal 填入 Signallist 中,再重新 Sort 一次,直到這次的 Cycle 內的所有 Signals 都以完成.
# Sample.v
# module Sample(clk,rst,a,c)
# input  clk,rst;
# intput a[31:0];
# output c[31:0];
# reg    b[31:0];
#
# assign c = (b==10)? b+a : a;
#
# always@ (posedge clk or posedge rst) begin
# if (rst==1'b1)
#     b <= 0;
#  else
#     b <= b + 1;
# end
# endmodule
#
# test_Sample.v
# always
# #10 clk ~= clk  
#
# initial begin
# #0  Rst = 1'b0;
# #5  Rst = 1'b1;
# #20 Rst = 1'b0; 
# .... 
# #100 $finish 
# end
#

init_Architecture() {
 _module_      = Module({name:Sample});
 
 _a_           = _module_.Input.Signal([{name:a},
                                        {length:32},
                                        {cur:[{time:0},{val:x}]},
                                        {nxt:[{time:0},{val:x}]}]);

 _c_           = _module_.Output.Signal([{name:c},
                                         {length:32},
                                         {cur:[{time:0},{val:x}]},
                                         {nxt:[{time:0},{val:x}]}]); 

 _clk_         = _module_.Clk.Signal([{name:Clk},
                                      {length:1},
                                      {cur:[{time:0},{val:x}]},
                                      {nxt:[{time:0},{val:x}]}]});
    
 _rst_         = _module_.Rst.Signal(...); 

 _b_           = _module_.Reg.Signal(...);

 _method_0_    = _module_.Method([{{C1:{_rst_==1'b1}},{P1:{_b_=0}}},
                                  {{C2:{_rst_==1'b0}},{P2:{_b_=_b_+1}}}]);

 [_clk_,_rst_].set_Driver(_method_0_);

 _method_1_    = _module_.Method([{{C1:{_b_==10}},{P1:{c=b+a}}},
                                  {{C2:{_b_!=10}},{P2:{c=a}}}]);

 [_b_].set_Driver(_method_1_);
   
 [_clk_,_rst_,_a_,_c_,_b_].set_Parent(_module_);
 [_method_0_,_method_1_].set_Parent(_module_); 

 gl_Module_List.push(_module_);

 _module_.Signal_List.push([_a_,_c_,_clk_,_rst_]);
}



init_Time_Wave(){

 _gl_clk_  = Clk([{start_time:0},
                  {end_time:100},
                  {period:10}]);

 _gl_rst_  = Rst([{time:  0:F},
                  {time:  5:R},
                  {time: 20:F},
                  {time: 80:R},
                  {time:100:F}]);

 _gl_time_ = Time();
}




run_gl_Module_List(time cur_time,
            time nxt_time) {

 schedule_list = [];
 update_list   = [];

 # @ find the signals
 foreach _module_ ( gl_Module_List ){

   foreach _signal_ ( _module_.Signal_List )
       if( _signal_.cur.time <= cur_time )
           schedule_list.push(_signal_);   
          
 }

 schedule_list.sort_by_time();


 while( !schedule_list.empty() ){

     _schedule_ = schedule_list.pop_left();
     _driver_   = _schedule_.get_Driver();

     method_list = _driver_.get_Methods();
  
     foreach _method_ ( method_list )
         update_list = method.run_Signal_update();
                

     foreach _update_ ( update_list ){

      Signal(_update_).cur.val = Signal(_update_).nxt.val;
      Signal(_update_).cur.time = nxt_time;
      Signal(_update_).nxt_time = nxt_time + nxt_time - cur_time;

        if( Signal(_update_).get_Driver()!= Output ){
            schedule_list.push(_update_);
            schedule_list.sort_by_time();
        }

     }
 }
}



run_Simulation(){

 _gl_cur_time_ = _gl_clk_.start_time();
 _gl_nxt_time_ = 0;
 
 # check simulation time
 while ( _gl_cur_time <= _gl_clk.end_time() ) {

   _gl_nxt_time = _gl_cur_time_ + _gl_clk_.period()>>1; # @ posedge/negedge edge check
 
   run_gl_Module_List(_gl_cur_time_,_gl_nxt_time_); 

   _gl_cur_time = _gl_nxt_time;

 }
}
refs: http://www.ocpip.org/datasheets.php http://www.greensocs.com/ source code download http://sourceforge.net/projects/greensocs/develop

沒有留言:

張貼留言