網絡包含兩個節點,一個發送節點,一個接收節點。發送節點按照某種随機的規律産生資料包(包大小和包廂隔可自己定義),然後發送給接收節點。傳輸過程中會有一些随機的差錯(誤包率也可自己定義)。接收節點收到正确的包之後統計吞吐量。并可将接收吞吐量與發送吞吐量進行比較,觀察誤包率對接收吞吐量的影響。
模型中發送節點模型為一個處理器類的節點,其程序模型為:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiIXZ05WZD9CX5RXa2Fmcn9CXwczLcVmds92czlGZvwVP9EUTDZ0aRJkSwk0LcxGbpZ2LcBDM08CXlpXazRnbvZ2LcRlMMVDT2EWNvwFdu9mZvwFNS5WZ0Z0RhZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DO3UzMzgDMyIjNyUDM0EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
其用于産生ICI資料結構,并且使用遠端中斷進行發送和檢錯重傳
發送節點為六個狀态,其中五個為強制狀态一個為非強制狀态,無轉移函數
Init的入口代碼為
pk_code=0;
pk_count=0;
pk_number=0;
該函數作用為獲得仿真屬性值,參數為屬性類型、屬性名、指向屬性值得指針
op_ima_sim_attr_get(OPC_DOUBLE,"FailureRate",&frate);
獲得分級名稱指定的對象ID
dest_id=op_id_from_hierarchical_name("top.my_rx_node.rx_pro") ;為接收節點的程序
統計量注冊,傳回統計量句柄
transmitted_index= op_stat_reg("Transmitted Index", OPC_STAT_INDEX_NONE,OPC_STAT_GLOBAL);
transmitted_traffic= op_stat_reg("Transmitted Traffic", OPC_STAT_INDEX_NONE,OPC_STAT_GLOBAL);
generate_index= op_stat_reg("Generating Index", OPC_STAT_INDEX_NONE,OPC_STAT_GLOBAL);
ack_state=1;
該函數作用是為調用程序預設一個中斷,第一個參數為預設的中斷時間,第二個參數是使用者自定義的代碼,在頭檔案中有聲明,op_sim_time為擷取目前仿真時間
op_intrpt_schedule_self(op_sim_time(),INTRPT_NEW_PKT);
init狀态執行完之後,進入idle狀态,其入口代碼為
if(pk_count>0&& ack_state)
op_intrpt_schedule_self(op_sim_time(),PK_SEND);
頭檔案為
#defineINTRPT_NEW_PKT 0 自定義中斷
#definePK_SEND 1 自定義中斷
#defineRE_SEND 2 自定義中斷
#defineGEN (op_intrpt_type() == OPC_INTRPT_SELF && op_intrpt_code() ==INTRPT_NEW_PKT)
GEN條件中斷類型為自中斷,且中斷值為INTRPT_NEW_PKT,第一次中斷
#defineSEND (op_intrpt_type() == OPC_INTRPT_SELF && op_intrpt_code() ==PK_SEND && ack_state == OPC_TRUE)
SEND條件:中斷類型為自中斷,且中斷值為PK_SEND
#defineACK (op_intrpt_type() == OPC_INTRPT_REMOTE && op_intrpt_code() == pk_code)
ACK條件中斷類型為遠端中斷,并且中斷值為pk_code
#defineRESEND (op_intrpt_type() == OPC_INTRPT_SELF && op_intrpt_code() ==RE_SEND)
RESEND條件:中斷類型為自中斷,并且中斷值為RE_SEND
第一次條件GEN成立,進入gen狀态,其入口代碼
pk_count++;
pk_number++;
op_dist_uniform函數的作用是産生一個均勻分布的随機值,取值範圍為0-0.2
op_intrpt_schedule_self(op_sim_time()+ op_dist_uniform(0.2),INTRPT_NEW_PKT);
op_stat_write(generate_index,pk_number);
gen狀态運作後回到init,之後滿足SECD條件進入send狀态,其入口代碼為
pk_code++;
pk_count--;
建立一個接口
擷取給定接口的某屬性值
pk_inf=op_ici_create("my_td");
op_ici_attr_set(pk_inf,"index",pk_code);
size_dist=op_dist_load("Normal",1000,10000);
pk_size=op_dist_outcome(size_dist);随機生成的包大小
if(pk_size<0)
pk_size=0;
elseif(pk_size>10000)
pk_size=10000;
op_ici_attr_set(pk_inf,"size",pk_size);
op_ici_attr_set(pk_inf,"fal_rate",frate);
op_ici_install(pk_inf);建立一個與輸出中斷相關聯的接口
op_intrpt_schedule_remote(op_sim_time(),pk_code,dest_id);預設一個遠端中斷
ack_state=0;
re_send=op_intrpt_schedule_self(op_sim_time()+0.2,RE_SEND);
op_stat_write(transmitted_index,pk_code);
op_stat_write(transmitted_traffic,pk_size);
op_ici_install(OPC_NIL); 拆除目前ICI的綁定
send 狀态結束後ACK條件滿足,進入ack狀态,其入口代碼為
op_ev_cancel(re_send);撤銷事件
ack_state=1;
send狀态出錯,就會進入resend狀态,其入口代碼
op_ici_install(pk_inf);
op_intrpt_schedule_remote(op_sim_time(),pk_code,dest_id);
re_send=op_intrpt_schedule_self(op_sim_time()+0.2,RE_SEND);
op_ici_install(OPC_NIL);拆除目前ICI的綁定(釋放)
接收節點為四個狀态,其中三個為強制狀态,一個為非強制狀态,無轉移函數
Init的入口代碼為
send_id=op_id_from_hierarchical_name("top.my_tx_node.tx_pro");發送節點的ID
獲得分級名稱指定的對象ID
received_index= op_stat_reg("Received Index",OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
received_traffic= op_stat_reg("Received Traffic", OPC_STAT_INDEX_NONE,OPC_STAT_GLOBAL);
統計量注冊,接收數目和索引
頭檔案為
#defineARRIVAL (op_intrpt_type() == OPC_INTRPT_REMOTE) 遠端中斷
#defineEND (op_intrpt_type() == OPC_INTRPT_ENDSIM) 結束仿真中斷
聲明了包到達的條件及仿真結束的标志
當包到達時進入arrival狀态,執行以下代碼
pk_index=op_intrpt_code();
intrpt_ici=op_intrpt_ici();傳回與目前中斷相關聯的接口
op_ici_attr_get(intrpt_ici,"size",&pk_size);
op_ici_attr_get(intrpt_ici,"fal_rate",&frate);
if(op_dist_uniform(1)>=frate)
{
op_ici_destroy(intrpt_ici);
op_intrpt_schedule_remote(op_sim_time()+op_dist_uniform(0.1),pk_index,send_id);
}
op_stat_write(received_index,pk_index);
op_stat_write(received_traffic,pk_size);
轉載于:https://www.cnblogs.com/galway/p/4643685.html