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 `ifndef VMM_HW_DATA_WIDTH
00024 `define VMM_HW_DATA_WIDTH 1024
00025 `endif
00026
00027 `ifdef VMM_HW_RTL__SV
00028 `else
00029 `define VMM_HW_RTL__SV
00030
00031
00032 //
00033 // Select the target architecture
00034 //
00035 `undef VMM_HW_ARCH
00036
00037 `ifdef VMM_HW_ARCH_SCEMI
00038 // Throw a syntax error if more than one architecture was selected
00039 `ifdef VMM_HW_ARCH
00040 `VMM_HW_More_than_one_HW_platform_architecture_selected
00041 `endif
00042 `define VMM_HW_ARCH
00043 `endif
00044
00045
00046 `ifdef VMM_HW_ARCH_NULL
00047 // Throw a syntax error if more than one architecture was selected
00048 `ifdef VMM_HW_ARCH
00049 `VMM_HW_More_than_one_HW_platform_architecture_selected
00050 `endif
00051 `include "vmm.sv"
00052 `define VMM_HW_ARCH
00053 `endif
00054
00055
00056 // Throw a syntax error if no architecture was selected
00057 `ifdef VMM_HW_ARCH
00058 `else
00059 `VMM_HW_No_HW_platform_architecture_selected
00060 `endif
00061
00062
00063 // Include the DUT if mapping to hardware platform (ie. synthesis)
00064 // or using the NULL architecture
00065 `ifdef VMM_HW_SYNTHESIS_ON
00066 `define VMM_HW_INCL_DUT
00067 `endif
00068 `ifdef VMM_HW_ARCH_NULL
00069 `define VMM_HW_INCL_DUT
00070 `endif
00071
00072
00073 //
00074 //------------------------------------------------------------------
00075 //
00076
00077
00078 `ifdef VMM_HW_SYNTHESIS_ON
00079 `else
00080 interface vmm_hw_in_if_itf(input logic rx_rdy,
00081 output logic tx_rdy,
00082 output logic [`VMM_HW_DATA_WIDTH-1:0] msg,
00083 input logic uclk,
00084 input logic urst,
00085 input int width,
00086 input bit [1024*8-1:0] path);
00087
00088 `ifdef VMM_HW_ARCH_NULL
00089 string inst = path;
00090 vmm_log log = new("vmm_hw_in_if", inst);
00091 bit in_use = 0;
00092
00093 clocking ck @(posedge uclk);
00094 input rx_rdy;
00095 endclocking
00096 `endif
00097
00098 endinterface
00099 `endif
00100
00101
00102 `ifndef VMM_SVDOC
00103 module vmm_hw_in_if(rx_rdy, tx_rdy, msg, uclk, urst);
00104
00105 parameter width = 1;
00106
00107 input rx_rdy;
00108 output tx_rdy;
00109 output [width-1:0] msg;
00110 input uclk;
00111 input urst;
00112
00113 `ifdef VMM_HW_SYNTHESIS_ON
00114
00115 `ifdef VMM_HW_ARCH_SCEMI
00116 SceMiMessageInPort #(width) scemi(rx_rdy, tx_rdy, msg);
00117 `endif
00118
00119
00120 `else
00121
00122 reg [1024*8-1:0] path = `vmm_sformatf("%m");
00123
00124 initial
00125 begin
00126 if (vmm_hw.max_data_width < width) begin
00127 vmm_hw.max_data_width = width;
00128 end
00129 end
00130
00131 wire [`VMM_HW_DATA_WIDTH-1:0] msg_i;
00132 assign msg = msg_i;
00133
00134 vmm_hw_in_if_itf vitf(rx_rdy, tx_rdy, msg_i, uclk, urst, width, path);
00135
00136 `endif
00137
00138 endmodule
00139 `endif
00140
00141
00142 //
00143 //------------------------------------------------------------------
00144 //
00145 `ifdef VMM_HW_SYNTHESIS_ON
00146 `else
00147 interface vmm_hw_out_if_itf(input logic tx_rdy,
00148 output logic rx_rdy,
00149 input logic [`VMM_HW_DATA_WIDTH-1:0] msg,
00150 input logic uclk,
00151 input logic urst,
00152 input int width,
00153 input bit [1024*8-1:0] path);
00154
00155 `ifdef VMM_HW_ARCH_NULL
00156 string inst = path;
00157 vmm_log log = new("vmm_hw_out_if", inst);
00158 bit in_use = 0;
00159
00160 clocking ck @(posedge uclk);
00161 input tx_rdy;
00162 input msg;
00163 endclocking
00164 `endif
00165
00166
00167 endinterface
00168 `endif
00169
00170
00171 `ifndef VMM_SVDOC
00172 module vmm_hw_out_if(tx_rdy, rx_rdy, msg, uclk, urst);
00173 parameter width = 1;
00174 parameter pri = 10;
00175
00176 input tx_rdy;
00177 output rx_rdy;
00178 input [width-1:0] msg;
00179 input uclk;
00180 input urst;
00181
00182
00183 `ifdef VMM_HW_SYNTHESIS_ON
00184
00185 `ifdef VMM_HW_ARCH_SCEMI
00186 SceMiMessageOutPort #(width, pri) scemi(tx_rdy, rx_rdy, msg);
00187 `endif
00188
00189
00190 `else
00191
00192 reg [1024*8-1:0] path = `vmm_sformatf("%m");
00193
00194 initial
00195 begin
00196 if (vmm_hw.max_data_width < width) begin
00197 vmm_hw.max_data_width = width;
00198 end
00199 end
00200
00201 wire [`VMM_HW_DATA_WIDTH-1:0] msg_i = msg;
00202
00203 vmm_hw_out_if_itf vitf(tx_rdy, rx_rdy, msg_i, uclk, urst, width, path);
00204
00205 `endif
00206
00207 endmodule
00208 `endif
00209
00210
00211
00212 //
00213 //------------------------------------------------------------------
00214 //
00215 `ifdef VMM_HW_SYNTHESIS_ON
00216 `else
00217 interface vmm_hw_clock_control_itf(input logic uclk,
00218 input logic urst,
00219 input logic rdy_for_cclk,
00220 output logic cclk_en,
00221 input logic rdy_for_cclk_neg,
00222 output logic cclk_neg_en,
00223 input bit [1024*8-1:0] path,
00224 input int clock_num);
00225
00226 `ifdef VMM_SVDOC
00227 reg foo;
00228 `endif
00229
00230 endinterface
00231 `endif
00232
00233
00234 `ifndef VMM_SVDOC
00235 module vmm_hw_clock_control(uclk, urst,
00236 rdy_for_cclk, cclk_en,
00237 rdy_for_cclk_neg, cclk_neg_en);
00238 parameter clock_num = 1;
00239
00240 output reg uclk;
00241 output reg urst;
00242 input rdy_for_cclk;
00243 output cclk_en;
00244 input rdy_for_cclk_neg;
00245 output cclk_neg_en;
00246
00247
00248 `ifdef VMM_HW_SYNTHESIS_ON
00249 `ifdef VMM_HW_ARCH_SCEMI
00250 SceMiClockControl #(clock_num) scemi(uclk, urst,
00251 rdy_for_cclk, cclk_en,
00252 rdy_for_cclk_neg, cclk_neg_en);
00253 `endif
00254
00255
00256 `else
00257
00258 reg [1024*8-1:0] path = `vmm_sformatf("%m");
00259
00260 `ifdef VMM_HW_ARCH_NULL
00261 // Make sure uclk and cclk are delta-cycle aligned
00262 always @(vmm_hw.uclk) uclk <= vmm_hw.uclk;
00263 always @(vmm_hw.urst) urst <= vmm_hw.urst;
00264
00265 initial
00266 begin
00267 repeat (2) @ (posedge uclk);
00268 if (cclk_en === 1'bx || cclk_neg_en === 1'bx) begin
00269 $write("ERROR: clock controller %m is not associated with a clock source\n");
00270 $finish();
00271 end
00272 end
00273 `endif
00274
00275 vmm_hw_clock_control_itf vitf(uclk, urst,
00276 rdy_for_cclk, cclk_en,
00277 rdy_for_cclk_neg, cclk_neg_en,
00278 path, clock_num);
00279
00280 `endif
00281
00282 endmodule
00283 `endif
00284
00285
00286 //
00287 //------------------------------------------------------------------
00288 //
00289 `ifndef VMM_SVDOC
00290 module vmm_hw();
00291
00292 int max_data_width = 0;
00293
00294 initial
00295 begin
00296 #10;
00297 if (max_data_width > `VMM_HW_DATA_WIDTH) begin
00298 $write("ERROR: `VMM_HW_DATA_WIDTH must be set to %0d or greater instead of %0d\n",
00299 max_data_width, `VMM_HW_DATA_WIDTH);
00300 $finish();
00301 end
00302 end
00303
00304
00305 `ifdef VMM_HW_ARCH_NULL
00306 reg uclk;
00307 reg urst;
00308 reg crst;
00309 time stamp;
00310
00311 int reset_cycles = 8;
00312
00313 initial
00314 begin
00315 stamp = 0;
00316 uclk = 0;
00317
00318 #1; // Make sure 'urst' is asserted before clock rises
00319 forever begin
00320 #1 uclk = 1;
00321 stamp = stamp + 1;
00322 #1 uclk = 0;
00323 end
00324 end
00325
00326 initial
00327 begin
00328 urst = 0;
00329 crst = 0;
00330 #1; // To avoid race condition with 'always @(vmm_hw.urst)'
00331 urst = 1;
00332 repeat (5) @ (posedge uclk);
00333 crst <= 1'b1;
00334 repeat (5) @ (posedge uclk);
00335 urst <= 0;
00336 repeat (reset_cycles * 2) @ (posedge uclk);
00337 crst <= 1'b0;
00338 end
00339
00340 `endif
00341
00342 endmodule
00343 `endif
00344
00345
00346 //
00347 //------------------------------------------------------------------
00348 //
00349 `ifdef VMM_HW_SYNTHESIS_ON
00350 `else
00351 interface vmm_hw_clock_itf(input int clock_num,
00352 input logic ck_en,
00353 input logic ckn_en,
00354 output int no_pos,
00355 output int no_neg);
00356 string controller[$];
00357 logic rdy_pos[$];
00358 logic rdy_neg[$];
00359
00360 function void why();
00361 if (controller.size() == 0) begin
00362 $write("Clock source %M does not have any associated controllers\n");
00363 return;
00364 end
00365 $write("State of controllers associated with %M:\n");
00366 $write(" Pos Neg :: Instance\n");
00367 foreach(controller[i]) begin
00368 $write(" %b %b :: %s\n", rdy_pos[i], rdy_neg[i], controller[i]);
00369 end
00370 endfunction: why
00371
00372 endinterface
00373 `endif
00374
00375
00376 `ifndef VMM_SVDOC
00377 module vmm_hw_clock(cclk, crst, crstn);
00378 parameter clock_num = 1;
00379
00380 parameter ratio_numerator = 1;
00381 parameter ratio_denominator = 1;
00382 parameter duty_hi = 0;
00383 parameter duty_lo = 100;
00384 parameter phase = 0;
00385 parameter reset_cycles = 8;
00386
00387 output cclk;
00388 output crst, crstn;
00389
00390 `ifdef VMM_HW_SYNTHESIS_ON
00391 `else
00392 bit ck_en;
00393 bit ckn_en;
00394 int no_pos;
00395 int no_neg;
00396 `endif
00397
00398 `ifdef VMM_HW_ARCH_NULL
00399 assign crst = vmm_hw.crst;
00400 assign crstn = ~vmm_hw.crst;
00401
00402 wor no_posw; // For Openvera
00403 wor no_negw; // For Openvera
00404
00405 reg cclk = 0;
00406
00407 // Controlled clocks must run while ccrst is asserted
00408 assign ck_en = (vmm_hw.urst === 1'b0) && (cclk == 1'b0) &&
00409 ((no_pos == 0 && no_posw === 1'bz) || crst);
00410 assign ckn_en = (vmm_hw.urst === 1'b0) && (cclk == 1'b1) &&
00411 ((no_neg == 0 && no_negw === 1'bz) || crst);
00412
00413 initial
00414 begin
00415 if (vmm_hw.reset_cycles < reset_cycles) begin
00416 vmm_hw.reset_cycles = reset_cycles;
00417 end
00418
00419 if (ratio_numerator != ratio_denominator) begin
00420 $write("WARNING: Unsupported ratio for clock source %M: %0d/%0d (must be 1/1)\n",
00421 ratio_numerator, ratio_denominator);
00422 end
00423 if (duty_hi != 0 && duty_lo != 0) begin
00424 $write("WARNING: Unsupported duty cycle for clock source %M: %0d/%0d (must be 0/x or x/0)\n",
00425 duty_hi, duty_lo);
00426 end
00427 if (phase != 0) begin
00428 $write("WARNING: Unsupported phase for clock source %M: %0d (must be 0)\n",
00429 phase);
00430 end
00431 end
00432
00433 always @ (posedge vmm_hw.uclk)
00434 begin
00435 if (vmm_hw.urst) cclk <= 1'b0;
00436 else begin
00437 if (ck_en) cclk <= 1'b1;
00438 if (ckn_en) cclk <= 1'b0;
00439 end
00440 end
00441
00442 `endif
00443
00444
00445 `ifdef VMM_HW_SYNTHESIS_ON
00446
00447 `ifdef VMM_HW_ARCH_SCEMI
00448 SceMiClockPort #(clock_num,
00449 ratio_numerator, ratio_denominator,
00450 duty_hi, duty_lo, phase, reset_cycles) scemi(cclk, crst);
00451 `endif
00452
00453
00454 `else
00455
00456 vmm_hw_clock_itf vitf(clock_num, ck_en, ckn_en, no_pos, no_neg);
00457
00458 `endif
00459
00460 endmodule
00461 `endif
00462
00463 `endif // VMM_HW_RTL__SV