VMM OpenSource - sv/HAL/vmm_hw_rtl.sv

sv/HAL/vmm_hw_rtl.sv expanded source

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