00001 // 00002 // ------------------------------------------------------------- 00003 // Copyright 2004-2008 Synopsys, Inc. 00004 // All Rights Reserved Worldwide 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the 00007 // "License"); you may not use this file except in 00008 // compliance with the License. You may obtain a copy of 00009 // the License at 00010 // 00011 // http://www.apache.org/licenses/LICENSE-2.0 00012 // 00013 // Unless required by applicable law or agreed to in 00014 // writing, software distributed under the License is 00015 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00016 // CONDITIONS OF ANY KIND, either express or implied. See 00017 // the License for the specific language governing 00018 // permissions and limitations under the License. 00019 // ------------------------------------------------------------- 00020 // 00021 00022 00023 `ifdef VMM_HW_ARCH_NULL__SV 00024 `else 00025 `define VMM_HW_ARCH_NULL__SV 00026 00027 typedef class vmm_hw_arch_null_in_port; 00028 typedef class vmm_hw_arch_null_out_port; 00029 00030 class vmm_hw_arch_null extends vmm_hw_arch; 00031 virtual function vmm_hw_in_port create_in_port(virtual vmm_hw_in_if in_if, 00032 string name); 00033 vmm_hw_arch_null_in_port port = new(in_if); 00034 return port; 00035 endfunction: create_in_port 00036 00037 virtual function vmm_hw_out_port create_out_port(virtual vmm_hw_out_if out_if, 00038 string name); 00039 vmm_hw_arch_null_out_port port = new(out_if); 00040 return port; 00041 endfunction: create_out_port 00042 00043 virtual function string connect_to(string hdl_path, 00044 string name); 00045 return super.connect_to(hdl_path, name); 00046 endfunction: connect_to 00047 00048 virtual function void clk_control(virtual vmm_hw_clock clk, 00049 virtual vmm_hw_clock_control ctl); 00050 int n; 00051 00052 ctl.cclk_en = 0; 00053 ctl.cclk_neg_en = 0; 00054 00055 n = clk.controller.size(); 00056 `ifdef VCS_BUG 00057 clk.controller.push_back(ctl.path); 00058 clk.rdy_pos.push_back(1'b1); 00059 clk.rdy_neg.push_back(1'b1); 00060 `endif 00061 00062 fork 00063 automatic int i = n; 00064 00065 forever begin 00066 `ifdef VCS_BUG 00067 clk.rdy_pos[i] = 1; 00068 `endif 00069 wait (ctl.rdy_for_cclk === 1'b0); 00070 `ifdef VCS_BUG 00071 clk.rdy_pos[i] = ctl.rdy_for_cclk; 00072 `endif 00073 clk.no_pos++; 00074 wait (ctl.rdy_for_cclk === 1'b1); 00075 clk.no_pos--; 00076 end 00077 00078 forever begin 00079 `ifdef VCS_BUG 00080 clk.rdy_neg[i] = 1; 00081 `endif 00082 wait (ctl.rdy_for_cclk_neg === 1'b0); 00083 `ifdef VCS_BUG 00084 clk.rdy_neg[i] = ctl.rdy_for_cclk_neg; 00085 `endif 00086 clk.no_neg++; 00087 wait (ctl.rdy_for_cclk_neg === 1'b1); 00088 clk.no_neg--; 00089 end 00090 00091 forever begin 00092 ctl.cclk_en = clk.ck_en; 00093 @ (clk.ck_en); 00094 end 00095 00096 forever begin 00097 ctl.cclk_neg_en = clk.ckn_en; 00098 @ (clk.ckn_en); 00099 end 00100 join_none 00101 endfunction: clk_control 00102 endclass: vmm_hw_arch_null 00103 00104 00105 class vmm_hw_arch_null_in_port extends vmm_hw_in_port; 00106 00107 local virtual vmm_hw_in_if itf; 00108 00109 function new(virtual vmm_hw_in_if itf); 00110 log.set_instance(itf.path); 00111 00112 this.itf = itf; 00113 this.itf.tx_rdy = 1'b0; 00114 endfunction: new 00115 00116 virtual function bit is_rdy(); 00117 return this.itf.rx_rdy; 00118 endfunction: is_rdy 00119 00120 virtual task wait_is_rdy(); 00121 `vmm_debug(log, "Waiting for RTL to be ready to receive message..."); 00122 do begin 00123 @(this.itf.ck); 00124 end 00125 while (this.itf.rx_rdy !== 1'b1); 00126 `vmm_debug(log, "RTL is ready to receive message"); 00127 endtask: wait_is_rdy 00128 00129 virtual task send(bit [`VMM_HW_MAX_MSG_WIDTH-1:0] data); 00130 if (this.itf.in_use) begin 00131 `vmm_fatal(log, "send() task concurrently activated"); 00132 end 00133 this.itf.in_use = 1; 00134 @(this.itf.ck); 00135 this.itf.tx_rdy <= 1'b1; 00136 this.itf.msg <= data; 00137 `vmm_debug(log, "Waiting to send message..."); 00138 do begin 00139 @(this.itf.ck); 00140 end 00141 while (this.itf.ck.rx_rdy !== 1'b1); 00142 this.itf.tx_rdy <= 1'b0; 00143 this.itf.in_use = 0; 00144 `vmm_debug(log, $psprintf("Sent message 'h%h", this.itf.msg)); 00145 endtask: send 00146 endclass: vmm_hw_arch_null_in_port 00147 00148 00149 class vmm_hw_arch_null_out_port extends vmm_hw_out_port; 00150 local virtual vmm_hw_out_if itf; 00151 00152 function new(virtual vmm_hw_out_if itf); 00153 log.set_instance(itf.path); 00154 00155 this.itf = itf; 00156 this.itf.rx_rdy = 1'b0; 00157 endfunction: new 00158 00159 virtual function bit is_rdy(); 00160 return this.itf.tx_rdy; 00161 endfunction: is_rdy 00162 00163 virtual task wait_is_rdy(); 00164 `vmm_debug(log, "Waiting for RTL to be ready to send message..."); 00165 do begin 00166 @(this.itf.ck); 00167 end 00168 while (this.itf.ck.tx_rdy !== 1'b1); 00169 `vmm_debug(log, "RTL is ready to send message"); 00170 endtask: wait_is_rdy 00171 00172 virtual task receive(ref bit [`VMM_HW_MAX_MSG_WIDTH-1:0] data, 00173 ref time stamp); 00174 if (this.itf.in_use) begin 00175 `vmm_fatal(log, "receive() task concurrently activated"); 00176 end 00177 this.itf.in_use = 1; 00178 `vmm_debug(log, "Waiting to receive message..."); 00179 @(this.itf.ck); 00180 this.itf.rx_rdy <= 1'b1; 00181 do 00182 @(this.itf.ck); 00183 while (this.itf.ck.tx_rdy !== 1'b1); 00184 this.itf.rx_rdy <= 1'b0; 00185 this.itf.in_use = 0; 00186 data = this.itf.ck.msg; 00187 stamp = vmm_hw.stamp; 00188 `vmm_debug(log, $psprintf("Receive message 'h%h stamped %0d", data, stamp)); 00189 endtask: receive 00190 endclass: vmm_hw_arch_null_out_port 00191 00192 `endif