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_itf 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_itf 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_itf clk,
00049 virtual vmm_hw_clock_control_itf ctl);
00050 int n;
00051
00052 clk.no_pos = 0;
00053 clk.no_neg = 0;
00054 ctl.cclk_en = 0;
00055 ctl.cclk_neg_en = 0;
00056
00057 n = clk.controller.size();
00058 `ifdef VMM_HW_CLOCK_WHY
00059 clk.controller.push_back(ctl.path);
00060 clk.rdy_pos.push_back(1'b1);
00061 clk.rdy_neg.push_back(1'b1);
00062 `endif
00063
00064 fork
00065 automatic int i = n;
00066
00067 forever begin
00068 `ifdef VMM_HW_CLOCK_WHY
00069 clk.rdy_pos[i] = 1;
00070 `endif
00071 wait (ctl.rdy_for_cclk === 1'b0);
00072 `ifdef VMM_HW_CLOCK_WHY
00073 clk.rdy_pos[i] = ctl.rdy_for_cclk;
00074 `endif
00075 clk.no_pos++;
00076 wait (ctl.rdy_for_cclk === 1'b1);
00077 clk.no_pos--;
00078 end
00079
00080 forever begin
00081 `ifdef VMM_HW_CLOCK_WHY
00082 clk.rdy_neg[i] = 1;
00083 `endif
00084 wait (ctl.rdy_for_cclk_neg === 1'b0);
00085 `ifdef VMM_HW_CLOCK_WHY
00086 clk.rdy_neg[i] = ctl.rdy_for_cclk_neg;
00087 `endif
00088 clk.no_neg++;
00089 wait (ctl.rdy_for_cclk_neg === 1'b1);
00090 clk.no_neg--;
00091 end
00092
00093 forever begin
00094 ctl.cclk_en = clk.ck_en;
00095 @ (clk.ck_en);
00096 end
00097
00098 forever begin
00099 ctl.cclk_neg_en = clk.ckn_en;
00100 @ (clk.ckn_en);
00101 end
00102 join_none
00103 endfunction: clk_control
00104 endclass: vmm_hw_arch_null
00105
00106
00107 class vmm_hw_arch_null_in_port extends vmm_hw_in_port;
00108
00109 local virtual vmm_hw_in_if_itf itf;
00110
00111 function new(virtual vmm_hw_in_if_itf itf);
00112 log.set_instance(itf.path);
00113
00114 this.itf = itf;
00115 this.itf.tx_rdy = 1'b0;
00116 endfunction: new
00117
00118 virtual function bit is_rdy();
00119 return this.itf.rx_rdy;
00120 endfunction: is_rdy
00121
00122 virtual task wait_is_rdy();
00123 `vmm_debug(log, "Waiting for RTL to be ready to receive message...");
00124 do begin
00125 @(this.itf.ck);
00126 end
00127 while (this.itf.rx_rdy !== 1'b1);
00128 `vmm_debug(log, "RTL is ready to receive message");
00129 endtask: wait_is_rdy
00130
00131 virtual task send(bit [`VMM_HW_DATA_WIDTH-1:0] data);
00132 if (this.itf.in_use) begin
00133 `vmm_fatal(log, "send() task concurrently activated");
00134 end
00135 this.itf.in_use = 1;
00136 @(this.itf.ck);
00137 this.itf.tx_rdy <= 1'b1;
00138 this.itf.msg <= data;
00139 `vmm_debug(log, "Waiting to send message...");
00140 do begin
00141 @(this.itf.ck);
00142 end
00143 while (this.itf.ck.rx_rdy !== 1'b1);
00144 this.itf.tx_rdy <= 1'b0;
00145 this.itf.in_use = 0;
00146 `vmm_debug(log, $psprintf("Sent message 'h%h", this.itf.msg));
00147 endtask: send
00148 endclass: vmm_hw_arch_null_in_port
00149
00150
00151 class vmm_hw_arch_null_out_port extends vmm_hw_out_port;
00152 local virtual vmm_hw_out_if_itf itf;
00153
00154 function new(virtual vmm_hw_out_if_itf itf);
00155 log.set_instance(itf.path);
00156
00157 this.itf = itf;
00158 this.itf.rx_rdy = 1'b0;
00159 endfunction: new
00160
00161 virtual function bit is_rdy();
00162 return this.itf.tx_rdy;
00163 endfunction: is_rdy
00164
00165 virtual task wait_is_rdy();
00166 `vmm_debug(log, "Waiting for RTL to be ready to send message...");
00167 do begin
00168 @(this.itf.ck);
00169 end
00170 while (this.itf.ck.tx_rdy !== 1'b1);
00171 `vmm_debug(log, "RTL is ready to send message");
00172 endtask: wait_is_rdy
00173
00174 virtual task receive(ref bit [`VMM_HW_DATA_WIDTH-1:0] data,
00175 ref time stamp);
00176 if (this.itf.in_use) begin
00177 `vmm_fatal(log, "receive() task concurrently activated");
00178 end
00179 this.itf.in_use = 1;
00180 `vmm_debug(log, "Waiting to receive message...");
00181 @(this.itf.ck);
00182 this.itf.rx_rdy <= 1'b1;
00183 do
00184 @(this.itf.ck);
00185 while (this.itf.ck.tx_rdy !== 1'b1);
00186 this.itf.rx_rdy <= 1'b0;
00187 this.itf.in_use = 0;
00188 data = this.itf.ck.msg;
00189 stamp = vmm_hw.stamp;
00190 `vmm_debug(log, $psprintf("Receive message 'h%h stamped %0d", data, stamp));
00191 endtask: receive
00192 endclass: vmm_hw_arch_null_out_port
00193
00194 `endif