├── .gitignore ├── DVConPaper_2018.pdf ├── DVConSlides_2018.pdf ├── License.txt ├── README.md ├── distrib ├── License.txt ├── README.txt ├── SRM_Reference.html ├── examples │ ├── Makefile.ius │ ├── Makefile.vcs │ ├── jnpr_setup.csh │ └── trivial │ │ ├── Makefile.ius │ │ └── Makefile.vcs └── src │ ├── base │ ├── srm_base_coverage.svh │ ├── srm_base_field.svh │ ├── srm_base_field_policy.svh │ ├── srm_base_handle.svh │ ├── srm_base_reg.svh │ ├── srm_field.svh │ ├── srm_field_policies.svh │ ├── srm_node.svh │ ├── srm_reg.svh │ ├── srm_table.svh │ └── srm_table_entry.svh │ ├── bus │ ├── srm_bus_adapter.svh │ ├── srm_bus_predictor.svh │ └── srm_generic_xact.svh │ ├── common │ └── srm_utils.svh │ ├── srm.sv │ └── srm_pkg.sv ├── docs ├── Notes.md ├── images │ ├── Slide23.JPG │ ├── Slide8.JPG │ ├── srm_example.jpg │ ├── srm_uvm_active.jpg │ └── srm_uvm_passive.jpg ├── overview.txt ├── release.md └── testbench.md ├── env ├── jnpr_setup.csh ├── setup.bash └── setup.csh ├── natural_docs ├── Config │ ├── Languages.txt │ └── Topics.txt ├── Info │ ├── CSSGuide.txt │ ├── File Parsing.txt │ ├── HTMLTestCases.pm │ ├── Languages.txt │ ├── NDMarkup.txt │ ├── Symbol Management.txt │ └── images │ │ └── Logo.png ├── JavaScript │ └── NaturalDocs.js ├── License-GPL.txt ├── Modules │ └── NaturalDocs │ │ ├── BinaryFile.pm │ │ ├── Builder.pm │ │ ├── Builder │ │ ├── Base.pm │ │ ├── FramedHTML.pm │ │ ├── HTML.pm │ │ └── HTMLBase.pm │ │ ├── ClassHierarchy.pm │ │ ├── ClassHierarchy │ │ ├── Class.pm │ │ └── File.pm │ │ ├── ConfigFile.pm │ │ ├── Constants.pm │ │ ├── DefineMembers.pm │ │ ├── Error.pm │ │ ├── File.pm │ │ ├── ImageReferenceTable.pm │ │ ├── ImageReferenceTable │ │ ├── Reference.pm │ │ └── String.pm │ │ ├── Languages.pm │ │ ├── Languages │ │ ├── ActionScript.pm │ │ ├── Ada.pm │ │ ├── Advanced.pm │ │ ├── Advanced │ │ │ ├── Scope.pm │ │ │ └── ScopeChange.pm │ │ ├── Base.pm │ │ ├── CSharp.pm │ │ ├── PLSQL.pm │ │ ├── Pascal.pm │ │ ├── Perl.pm │ │ ├── Prototype.pm │ │ ├── Prototype │ │ │ └── Parameter.pm │ │ ├── Simple.pm │ │ └── Tcl.pm │ │ ├── Menu.pm │ │ ├── Menu │ │ └── Entry.pm │ │ ├── NDMarkup.pm │ │ ├── Parser.pm │ │ ├── Parser │ │ ├── JavaDoc.pm │ │ ├── Native.pm │ │ └── ParsedTopic.pm │ │ ├── Project.pm │ │ ├── Project │ │ ├── ImageFile.pm │ │ └── SourceFile.pm │ │ ├── ReferenceString.pm │ │ ├── Settings.pm │ │ ├── Settings │ │ └── BuildTarget.pm │ │ ├── SourceDB.pm │ │ ├── SourceDB │ │ ├── Extension.pm │ │ ├── File.pm │ │ ├── Item.pm │ │ ├── ItemDefinition.pm │ │ └── WatchedFileDefinitions.pm │ │ ├── StatusMessage.pm │ │ ├── SymbolString.pm │ │ ├── SymbolTable.pm │ │ ├── SymbolTable │ │ ├── File.pm │ │ ├── IndexElement.pm │ │ ├── Reference.pm │ │ ├── ReferenceTarget.pm │ │ ├── Symbol.pm │ │ └── SymbolDefinition.pm │ │ ├── Topics.pm │ │ ├── Topics │ │ └── Type.pm │ │ └── Version.pm ├── NaturalDocs ├── NaturalDocs.bat ├── Styles │ ├── Default.css │ └── main.css ├── images │ ├── arrow_1.gif │ ├── bg_column_green.gif │ ├── bg_column_green_grey.gif │ ├── bg_feature.jpg │ ├── bg_h3_roundcorners.gif │ ├── bg_main.gif │ ├── bg_masthead.jpg │ ├── bg_navbar.gif │ ├── bg_roundcorners2.gif │ ├── bg_tableheader.gif │ ├── bg_thick_grey_bar.gif │ ├── bullet_GreenOnGrey.gif │ ├── ovmm_atomic_gen.gif │ └── ovmm_scenario_gen.gif └── logo.html ├── notes.md ├── scripts ├── Proj │ ├── Data │ │ ├── ClassHierarchy.nd │ │ ├── ConfigFileInfo.nd │ │ ├── FileInfo.nd │ │ ├── ImageFileInfo.nd │ │ ├── ImageReferenceTable.nd │ │ ├── IndexInfo.nd │ │ ├── PreviousMenuState.nd │ │ ├── PreviousSettings.nd │ │ └── SymbolTable.nd │ ├── Languages.txt │ ├── Menu.txt │ └── Topics.txt ├── copyright.txt ├── gen_nd ├── insert_copyright ├── shell.rb └── srun ├── unit_fwk ├── Makefile.erb ├── README.md ├── gen_unit_tests ├── main.sv.erb ├── sim_cfiles.rb ├── srm_unit_test.svh └── srm_unit_test_pkg.sv └── unit_tests ├── README.md ├── models ├── cpu_multi_field.svh ├── cpu_reg32.svh ├── cpu_table32.svh ├── cpu_top.svh ├── cpu_volatile_field.svh └── test_models_pkg.sv ├── sim.cfiles ├── test_bus_predictor.svh ├── test_default_offset.svh ├── test_field_access.svh ├── test_field_policies.svh ├── test_field_rw.svh ├── test_leaf_policies.svh ├── test_model_coverage.svh ├── test_reg32.svh ├── test_reg32_rand.svh ├── test_reg_coverage.svh ├── test_reg_reset.svh ├── test_reg_rw.svh ├── test_srm_utils_1.svh ├── test_srm_utils_2.svh ├── test_table32.svh ├── test_table_coverage.svh ├── test_table_reset.svh ├── test_table_rw.svh ├── test_top.svh ├── test_volatile_field.svh ├── unit_test_pkg.sv └── utils.svh /.gitignore: -------------------------------------------------------------------------------- 1 | run/* 2 | *~ 3 | core.* 4 | *.tar.gz 5 | *.diff 6 | *.orig 7 | *.patch 8 | 9 | *.swp 10 | *.swo 11 | *.o 12 | *.so 13 | *.swn 14 | docs/temp_images 15 | setup.csh 16 | srm_ref/nd/Proj/ 17 | distrib/docs/html/ 18 | rgen/* 19 | -------------------------------------------------------------------------------- /DVConPaper_2018.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/DVConPaper_2018.pdf -------------------------------------------------------------------------------- /DVConSlides_2018.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/DVConSlides_2018.pdf -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Juniper Networks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple Register Model 2 | Simple Register Model (srm) are system verilog classes that help to develop register model (aka regstore, register abstraction layer) for [uvm testbenches](http://accellera.org/downloads/standards/uvm). 3 | 4 | It is open sourced and available under MIT license. I presented it in DVCon2018. Check a copy of the [slides](DVConSlides_2018.pdf) or the full [paper](DVConPaper_2018.pdf) 5 | 6 | It is designed to be used in uvm testbenches instead of the *uvm_reg* package that is shipped with uvm distribution. 7 | 8 | The intended users of the package are design verificatipn (DV) engineers involved in developing uvm testbneches and writing uvm sequences for verifying the design. 9 | 10 | ## Getting Started 11 | Easiest way to get started with srm is to download the tar file from the [release area](https://github.com/Juniper/simple_reg_model/releases) and follow the instructions. 12 | 13 | ## Installing the Package 14 | 1. Download tar file from release area. Say the name of file is svm-1.0.tar.gz 15 | 16 | 2. Unpack the tar file in the install directory. 17 | ``` 18 | cd 19 | tar xvfz svm-1.0.tar.gz 20 | ``` 21 | 22 | 3. Setup the environment variable SRM_HOME to point to the install directory. 23 | For example in Bash shell. 24 | 25 | ``` 26 | export SRM_HOME=/srm-1.0 27 | ``` 28 | 29 | ## Using the Package 30 | You must compile the file $SRM_HOME/src/srm.sv first. You will need to specify the location of $SRM_HOME/src as a include directory in your 31 | compilation command line using the +incdir+ command-line option. 32 | 33 | You can then make the SRM library accessible to your SystemVerilog code by importing the package 'srm_pkg' in the appropriate scope. 34 | 35 | Examples for different simulator can be found in the installation directory $SRM_HOME/examples/ 36 | 37 | 38 | ## Demo 39 | A example uvm testbench can be downloaded from [here](https://github.com/sanjeevs/srm_sap). 40 | 41 | ## Documentation 42 | Srm docuementation can be found [here](https://github.com/Juniper/simple_reg_model/wiki). 43 | -------------------------------------------------------------------------------- /distrib/License.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Juniper Networks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /distrib/README.txt: -------------------------------------------------------------------------------- 1 | The UVM package is licensed under the MIT license. The full text of 2 | the license is provided in this package in the file LICENSE.txt 3 | 4 | Extenal Dependecny 5 | ------------------- 6 | This package requires UVM package to be already installed. Please refer to the 7 | accellera website to download and install it. 8 | 9 | Installing the package 10 | ------------------ 11 | 12 | Installation of SRM requires first unpacking the package in a convenient 13 | location. 14 | 15 | % mkdir path/to/convenient/location 16 | % cd path/to/convenient/location 17 | % gunzip -c path/to/SRM/distribution/tar.gz | tar xvf - 18 | 19 | You should define the $SRM_HOME environment variable to that 20 | convenient location using an absolute path name. The following 21 | instructions assume that this variable is appropriately set. 22 | 23 | % setenv SRM_HOME /absolute/path/to/convenient/location 24 | 25 | 26 | Using the SRM 27 | ------------- 28 | 29 | You must compile the file $SRM_HOME/src/srm.sv first. You will need 30 | to specify the location of $SRM_HOME/src as a include directory in your 31 | compilation command line using the +incdir+ command-line option. 32 | 33 | You can then make the SRM library accessible to your SystemVerilog 34 | code by importing the package 'srm_pkg' in the appropriate scope. 35 | 36 | 37 | Prerequisites 38 | ------------- 39 | 40 | - IEEE1800 compliant SV simulator 41 | - gmake-compliant make to execute Makefile based examples 42 | - uvm package installed 43 | 44 | 45 | Running the examples 46 | -------------------- 47 | 48 | The examples assume the following steps to be completed: 49 | 50 | - The Compiler/Simulator environment has been setup according to the vendors 51 | instruction and you can execute compile/simulation on the commandline. 52 | 53 | - Following environment variables have been defined. 54 | UVM_HOME points to the uvm install directory. 55 | 56 | To run any of the examples: 57 | 58 | 1. change to the example dir (ex: cd examples/trivial) 59 | 2. execute "make -f Makefile.{ius|vcs}" depending upon your simulator vendor to run the example. 60 | The makefiles assume a gmake compiliant make tool. 61 | 62 | optional: 63 | - to see the commands and steps executed use "make -f Makefile.{ius|vcs} -n" 64 | 65 | 66 | 67 | 68 | 69 | ------------------------------------------------------------------------ 70 | -------------------------------------------------------------------------------- /distrib/SRM_Reference.html: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /distrib/examples/Makefile.ius: -------------------------------------------------------------------------------- 1 | ## 2 | ## ------------------------------------------------------------- 3 | ## Copyright 2010 Cadence. 4 | ## All Rights Reserved Worldwide 5 | ## 6 | ## Licensed under the Apache License, Version 2.0 (the 7 | ## "License"); you may not use this file except in 8 | ## compliance with the License. You may obtain a copy of 9 | ## the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in 14 | ## writing, software distributed under the License is 15 | ## distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 16 | ## CONDITIONS OF ANY KIND, either express or implied. See 17 | ## the License for the specific language governing 18 | ## permissions and limitations under the License. 19 | ## ------------------------------------------------------------- 20 | ## 21 | 22 | x: all 23 | 24 | # 25 | # Include file for IUS Makefiles 26 | # 27 | ifndef UVM_HOME 28 | $(error UVM_HOME is not set) 29 | endif 30 | 31 | ifndef SRM_HOME 32 | $(error SRM_HOME is not set) 33 | endif 34 | 35 | UVM_VERBOSITY = UVM_LOW 36 | 37 | # 38 | # Note that "-access rw" have an adverse impact on performance 39 | # and should not be used unless necessary. 40 | # 41 | # They are used here because they are required by some examples 42 | # (backdoor register accesses). 43 | # 44 | 45 | 46 | TEST = /usr/bin/test 47 | N_ERRS = 0 48 | N_FATALS = 0 49 | 50 | IUS = irun -access rw -uvmnocdnsextra -uvmhome $(UVM_HOME) +UVM_VERBOSITY=$(UVM_VERBOSITY) -quiet 51 | 52 | 53 | CHECK = \ 54 | @$(TEST) \( `grep -c 'UVM_ERROR : $(N_ERRS)' irun.log` -eq 1 \) -a \ 55 | \( `grep -c 'UVM_FATAL : $(N_FATALS)' irun.log` -eq 1 \) 56 | 57 | clean: 58 | rm -rf *~ core csrc simv* vc_hdrs.h ucli.key *.log INCA_libs 59 | 60 | all: 61 | $(IUS) -incdir $(SRM_HOME)/src $(SRM_HOME)/src/srm.sv 62 | 63 | -------------------------------------------------------------------------------- /distrib/examples/Makefile.vcs: -------------------------------------------------------------------------------- 1 | ## 2 | ## ------------------------------------------------------------- 3 | ## Copyright 2010-2011 Synopsys, Inc. 4 | ## All Rights Reserved Worldwide 5 | ## 6 | ## Licensed under the Apache License, Version 2.0 (the 7 | ## "License"); you may not use this file except in 8 | ## compliance with the License. You may obtain a copy of 9 | ## the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in 14 | ## writing, software distributed under the License is 15 | ## distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 16 | ## CONDITIONS OF ANY KIND, either express or implied. See 17 | ## the License for the specific language governing 18 | ## permissions and limitations under the License. 19 | ## ------------------------------------------------------------- 20 | ## 21 | 22 | x: all 23 | 24 | # 25 | # Include file for VCS Makefiles 26 | # 27 | ifndef SRM_HOME 28 | $(error SRM_HOME is not set) 29 | endif 30 | 31 | UVM_VERBOSITY = UVM_LOW 32 | 33 | # 34 | # Note that +acc and +vpi have an adverse impact on performance 35 | # and should not be used unless necessary. 36 | # 37 | # They are used here because they are required by some examples 38 | # (backdoor register accesses). 39 | # 40 | 41 | 42 | TEST = /usr/bin/test 43 | N_ERRS = 0 44 | N_FATALS = 0 45 | 46 | VCS = vcs -sverilog -timescale=1ns/1ns \ 47 | +acc +vpi -ntb_opts uvm -CFLAGS -DVCS 48 | 49 | SIMV = ./simv +UVM_VERBOSITY=$(UVM_VERBOSITY) -l vcs.log 50 | 51 | URG = urg -format text -dir simv.vdb 52 | 53 | CHECK = \ 54 | @$(TEST) \( `grep -c 'UVM_ERROR : $(N_ERRS)' vcs.log` -eq 1 \) -a \ 55 | \( `grep -c 'UVM_FATAL : $(N_FATALS)' vcs.log` -eq 1 \) 56 | 57 | clean: 58 | rm -rf *~ core csrc simv* vc_hdrs.h ucli.key urg* *.log *.history 59 | 60 | all: 61 | $(VCS) +incdir+$(SRM_HOME)/src $(SRM_HOME)/src/srm.sv 62 | 63 | -------------------------------------------------------------------------------- /distrib/examples/jnpr_setup.csh: -------------------------------------------------------------------------------- 1 | # Cheat sheet for my work csh setup. 2 | # You should create an equivalent shell script for all the dependcies required for 3 | # running the simulator. 4 | # source to setup the variables. 5 | 6 | module add vcs/2014.03-SP1-3 7 | module add verilog/INCISIVE15.10.022 8 | setenv UVM_HOME /usr/hw-tools/uvm/uvm-1.2 9 | setenv SRM_HOME `pwd`/.. 10 | -------------------------------------------------------------------------------- /distrib/examples/trivial/Makefile.ius: -------------------------------------------------------------------------------- 1 | ## 2 | ## ------------------------------------------------------------- 3 | ## Copyright 2010 Cadence. 4 | ## All Rights Reserved Worldwide 5 | ## 6 | ## Licensed under the Apache License, Version 2.0 (the 7 | ## "License"); you may not use this file except in 8 | ## compliance with the License. You may obtain a copy of 9 | ## the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in 14 | ## writing, software distributed under the License is 15 | ## distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 16 | ## CONDITIONS OF ANY KIND, either express or implied. See 17 | ## the License for the specific language governing 18 | ## permissions and limitations under the License. 19 | ## ------------------------------------------------------------- 20 | ## 21 | include ../Makefile.ius 22 | 23 | all: 24 | $(IUS) -incdir $(SRM_HOME)/src $(SRM_HOME)/src/srm.sv 25 | 26 | -------------------------------------------------------------------------------- /distrib/examples/trivial/Makefile.vcs: -------------------------------------------------------------------------------- 1 | ## 2 | ## ------------------------------------------------------------- 3 | ## Copyright 2010-2011 Synopsys, Inc. 4 | ## All Rights Reserved Worldwide 5 | ## 6 | ## Licensed under the Apache License, Version 2.0 (the 7 | ## "License"); you may not use this file except in 8 | ## compliance with the License. You may obtain a copy of 9 | ## the License at 10 | ## 11 | ## http://www.apache.org/licenses/LICENSE-2.0 12 | ## 13 | ## Unless required by applicable law or agreed to in 14 | ## writing, software distributed under the License is 15 | ## distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 16 | ## CONDITIONS OF ANY KIND, either express or implied. See 17 | ## the License for the specific language governing 18 | ## permissions and limitations under the License. 19 | ## ------------------------------------------------------------- 20 | ## 21 | include ../Makefile.vcs 22 | 23 | all: 24 | $(VCS) +incdir+$(SRM_HOME)/src $(SRM_HOME)/src/srm.sv 25 | 26 | -------------------------------------------------------------------------------- /distrib/src/base/srm_base_coverage.svh: -------------------------------------------------------------------------------- 1 | // 2 | // -------------------------------------------------------------- 3 | // Copyright (c) 2017-2023, Juniper Networks, Inc. 4 | // All rights reserved. 5 | // 6 | // This code is licensed to you under the MIT license. 7 | // You many not use this code except in compliance with this license. 8 | // This code is not an official Juniper product. You may obtain a copy 9 | // of the license at 10 | // 11 | // https://opensource.org/licenses/MIT 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 16 | // implied. See the License for the specific language governing 17 | // permissions and limitations under the License. 18 | // ------------------------------------------------------------- 19 | // 20 | `ifndef INCLUDED_srm_base_coverage 21 | `define INCLUDED_srm_base_coverage 22 | 23 | typedef class srm_base_reg; 24 | 25 | // ------------------------------------------------------------- 26 | // CLASS: srm_base_coverage 27 | // Base class for coverage model. 28 | // 29 | // User coverage model must derive from this base class and install 30 | // it at any level of the design hierarchy. 31 | // ------------------------------------------------------------- 32 | class srm_base_coverage; 33 | string _name; 34 | 35 | //---------------------- 36 | // Group: Initialization 37 | //---------------------- 38 | 39 | // Function: new 40 | // Create a new instance with the name. 41 | // 42 | function new(string name); 43 | _name = name; 44 | endfunction 45 | 46 | // Function: get_name 47 | // Get the name of the object. 48 | // 49 | virtual function get_name(); 50 | return _name; 51 | endfunction 52 | 53 | // Function: post_write 54 | // This will get called at the end of write task for the attached 55 | // nodes. 56 | // 57 | virtual function void post_write(srm_base_reg entry); 58 | // Add code for fcov of writes. 59 | endfunction 60 | 61 | // Function: post_read 62 | // This will get called at the end of read task for the attached 63 | // nodes. 64 | // 65 | virtual function void post_read(srm_base_reg entry); 66 | // Add code for fcov of reads. 67 | endfunction 68 | 69 | // Function: sample_xact 70 | // FIXME: only see it in write but not in read. 71 | virtual function void sample_xact(const ref srm_generic_xact_t xact); 72 | // Add code for fcov of xact. 73 | endfunction 74 | 75 | endclass 76 | 77 | `endif 78 | -------------------------------------------------------------------------------- /distrib/src/base/srm_base_field_policy.svh: -------------------------------------------------------------------------------- 1 | // 2 | // -------------------------------------------------------------- 3 | // Copyright (c) 2017-2023, Juniper Networks, Inc. 4 | // All rights reserved. 5 | // 6 | // This code is licensed to you under the MIT license. 7 | // You many not use this code except in compliance with this license. 8 | // This code is not an official Juniper product. You may obtain a copy 9 | // of the license at 10 | // 11 | // https://opensource.org/licenses/MIT 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 16 | // implied. See the License for the specific language governing 17 | // permissions and limitations under the License. 18 | // ------------------------------------------------------------- 19 | // 20 | `ifndef INCLUDED_srm_base_field_policy_svh 21 | `define INCLUDED_srm_base_field_policy_svh 22 | 23 | typedef class srm_base_field; 24 | //---------------------------------------------------------------- 25 | // Class: srm_base_field_policy 26 | // Base class for access policy on a field per address map. 27 | // 28 | // A policy represents the update to be done to the field model when 29 | // a read or write issued to the design. For example a field can be 30 | // read_write in 'cpu_map' but read_only for 'gpu_map'. 31 | // ReadWrite policy would imply that the write to the design or read from 32 | // the design from the cpu_map would update the field model. 33 | // A ReadOnly policy would imply that only reads from the design in gpu_map would 34 | // update the field model. Writes to the design field would be ignored by the model. 35 | // 36 | //---------------------------------------------------------------- 37 | 38 | virtual class srm_base_field_policy; 39 | 40 | // Function: read_policy 41 | // Model the affect of doing a read from the field in the design. 42 | // 43 | // Returns 0: Skip update to the field model. 44 | // 1: Update the field model. 45 | // 46 | pure virtual function bit read_policy(srm_base_field field, 47 | ref srm_data_t bytes); 48 | 49 | // Function: write_policy 50 | // Model the affect of doing a write to the field in the design. 51 | // 52 | // Returns 0: Skip update to the field model. 53 | // 1: Update the field model with data. 54 | // 55 | pure virtual function bit write_policy(srm_base_field field, 56 | ref srm_data_t bytes); 57 | 58 | // Function: get_name 59 | // Name of the policy 60 | // 61 | pure virtual function string get_name(); 62 | 63 | endclass 64 | 65 | `endif 66 | -------------------------------------------------------------------------------- /distrib/src/base/srm_base_handle.svh: -------------------------------------------------------------------------------- 1 | // 2 | // -------------------------------------------------------------- 3 | // Copyright (c) 2017-2023, Juniper Networks, Inc. 4 | // All rights reserved. 5 | // 6 | // This code is licensed to you under the MIT license. 7 | // You many not use this code except in compliance with this license. 8 | // This code is not an official Juniper product. You may obtain a copy 9 | // of the license at 10 | // 11 | // https://opensource.org/licenses/MIT 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 16 | // implied. See the License for the specific language governing 17 | // permissions and limitations under the License. 18 | // ------------------------------------------------------------- 19 | // 20 | `ifndef INCLUDED_srm_base_handle_svh 21 | `define INCLUDED_srm_base_handle_svh 22 | 23 | //----------------------------------------------------------------- 24 | // CLASS: srm_base_handle 25 | // Client options for configurating the access. 26 | //----------------------------------------------------------------- 27 | 28 | class srm_base_handle extends uvm_object; 29 | 30 | `uvm_object_utils(srm_base_handle) 31 | 32 | // Variable: priority 33 | // Priority of the sub sequence. 34 | int seq_priority; 35 | 36 | // Variable: addr_map_name 37 | // Name of the address map. 38 | string addr_map_name; 39 | 40 | // Variable: enable_functional_coverage 41 | // Enables functional coverage for all the access to the design. 42 | bit enable_functional_coverage; 43 | 44 | // Variable: skip_read_error_msg 45 | // Debug variable to switch off error messages from failing reads. 46 | bit skip_read_error_msg; 47 | 48 | // Varaible: status 49 | // Status of the bus xact returned by agent. 50 | srm_status_e generic_xact_status; 51 | 52 | // Variable: error_msgs 53 | // List of error messages encountered so far. 54 | string error_msgs[$]; 55 | 56 | //------------------ 57 | // Group: Initialization 58 | //------------------- 59 | 60 | // Function: new 61 | // 62 | // Create a new instance. 63 | // 64 | // Use UVM Factory instead to create the instance. 65 | function new(string name=""); 66 | super.new(name); 67 | endfunction 68 | 69 | // Function: initialize 70 | // 71 | // Initialize the instance of base handle. 72 | // 73 | // Factory uses the default constructor. 74 | virtual function void initialize(string addr_map_name); 75 | this.addr_map_name = addr_map_name; 76 | this.skip_read_error_msg = 0; 77 | this.generic_xact_status = SRM_IS_OK; 78 | this.seq_priority = -1; 79 | endfunction 80 | 81 | // Function: append_error 82 | // 83 | // Append error msgs for debug later by the client. 84 | // 85 | function void append_error(string msg); 86 | error_msgs.push_back(msg); 87 | endfunction 88 | 89 | // Function: is_correct_adapter 90 | // 91 | // Return true for the correct adapter. 92 | // 93 | // Virtual function that must be implemented by the subclass. Returns false 94 | // by default. 95 | // 96 | virtual function bit is_correct_adapter(srm_bus_adapter adapter); 97 | return 0; 98 | endfunction 99 | 100 | // Function: search_backwards_for_adapter 101 | // 102 | // Walk backward to root looking for correct adapter. 103 | // 104 | // Return null if no correct adapter found. 105 | // 106 | virtual function srm_bus_adapter search_backwards_for_adapter(srm_node obj); 107 | srm_node ptr = obj; 108 | srm_bus_adapter adapters[$]; 109 | 110 | while(ptr != null) begin 111 | adapters = ptr.get_adapters(); 112 | for(int i = 0; i < adapters.size(); i++) begin 113 | if(is_correct_adapter(adapters[i])) return adapters[i]; 114 | end 115 | ptr = ptr.get_parent(); 116 | end 117 | 118 | return null; 119 | endfunction 120 | 121 | // Function: get_adapter 122 | // 123 | // Select the correct adapter and return it. 124 | // 125 | // TbConfiguraration Error is no adapter found. 126 | // 127 | virtual function srm_bus_adapter get_adapter(srm_node obj); 128 | srm_bus_adapter adapter = search_backwards_for_adapter(obj); 129 | if(adapter == null) begin 130 | `uvm_fatal("TbConfigurationError", 131 | $psprintf("Could not locate adapter for \"%s\" node", obj.get_full_name())); 132 | end 133 | return adapter; 134 | endfunction 135 | endclass 136 | 137 | `endif 138 | -------------------------------------------------------------------------------- /distrib/src/base/srm_table_entry.svh: -------------------------------------------------------------------------------- 1 | // 2 | // -------------------------------------------------------------- 3 | // Copyright (c) 2017-2023, Juniper Networks, Inc. 4 | // All rights reserved. 5 | // 6 | // This code is licensed to you under the MIT license. 7 | // You many not use this code except in compliance with this license. 8 | // This code is not an official Juniper product. You may obtain a copy 9 | // of the license at 10 | // 11 | // https://opensource.org/licenses/MIT 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 16 | // implied. See the License for the specific language governing 17 | // permissions and limitations under the License. 18 | // ------------------------------------------------------------- 19 | // 20 | `ifndef INCLUDED_srm_table_entry_svh 21 | `define INCLUDED_srm_table_entry_svh 22 | 23 | //-------------------------------------------------------- 24 | // CLASS: srm_table_entry 25 | // Models the entry of the register array. 26 | // 27 | // The array entry is just a specialization of the register with an 28 | // additional attribute "index" representing the position in the array. 29 | // The template data must be a packed structure representing the fields 30 | // of the register. 31 | //-------------------------------------------------------- 32 | virtual class srm_table_entry#(type T = int) extends srm_reg#(T); 33 | local srm_addr_t _index; // For address computation in array. 34 | 35 | //------------------------------- 36 | // Group: Initialization 37 | //------------------------------- 38 | 39 | // Function: new 40 | // 41 | // Create a new instance of the entry in the array. 42 | // 43 | // ~parent~ represents the array to which the entry belongs. 44 | // ~index~ represents the position within the array. 45 | // 46 | function new(string name, srm_node parent, srm_addr_t index); 47 | super.new(name, parent); 48 | _index = index; 49 | endfunction 50 | 51 | //---------------------- 52 | // Group: Address computation 53 | //---------------------- 54 | 55 | // Function: get_index 56 | // 57 | // Returns the index of the entry in array. 58 | // 59 | virtual function srm_addr_t get_index(); 60 | return _index; 61 | endfunction 62 | 63 | // Function: get_offset 64 | // 65 | // Return the byte offset of the entry in the array. 66 | // 67 | // Get the offset of entry 0 and then add the index*width. 68 | // 69 | virtual function srm_addr_t get_offset(string addr_map_name); 70 | srm_addr_t offset = _parent.get_offset(addr_map_name); 71 | return offset + (_index * get_width_bytes()); 72 | endfunction 73 | 74 | //------------------ 75 | // Group: Private 76 | //------------------- 77 | // Function: clone 78 | // 79 | // Abstract method that is overwritten by the derived class. 80 | // 81 | // Should create a clone of the prototype at the specified index. 82 | // 83 | pure virtual function srm_table_entry#(T) clone(srm_addr_t index); 84 | 85 | // Function: initialize 86 | // 87 | // Private function to initialize the clone. 88 | // 89 | protected function void __initialize(srm_table_entry#(T) obj); 90 | super.__initialize(obj); 91 | endfunction 92 | 93 | 94 | 95 | endclass 96 | 97 | `endif 98 | -------------------------------------------------------------------------------- /distrib/src/bus/srm_bus_adapter.svh: -------------------------------------------------------------------------------- 1 | // 2 | // -------------------------------------------------------------- 3 | // Copyright (c) 2017-2023, Juniper Networks, Inc. 4 | // All rights reserved. 5 | // 6 | // This code is licensed to you under the MIT license. 7 | // You many not use this code except in compliance with this license. 8 | // This code is not an official Juniper product. You may obtain a copy 9 | // of the license at 10 | // 11 | // https://opensource.org/licenses/MIT 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 16 | // implied. See the License for the specific language governing 17 | // permissions and limitations under the License. 18 | // ------------------------------------------------------------- 19 | // 20 | `ifndef INCLUDED_srm_bus_adapter_svh 21 | `define INCLUDED_srm_bus_adapter_svh 22 | 23 | //----------------------------------------------------------------- 24 | // CLASS: srm_bus_adapter 25 | // Abstract base class for bus adapter. 26 | // 27 | // Derived class must override the execute method to convert the generic 28 | // bus operation to a design specific transaction. 29 | //----------------------------------------------------------------- 30 | class srm_bus_adapter extends uvm_object; 31 | 32 | `uvm_object_utils(srm_bus_adapter) 33 | 34 | //------------------ 35 | // Group: Initialization 36 | //------------------- 37 | 38 | // Function: new 39 | // 40 | // Create a new instance of a register. 41 | // 42 | // Use uvm factory to create the instance of the adapter. 43 | // 44 | function new(string name=""); 45 | super.new(name); 46 | endfunction 47 | 48 | // Task: execute 49 | // 50 | // Execute the generic bus transaction on the actual bus. 51 | // 52 | // ~generic_xact~ is the generic transaction emitted by the register model. 53 | // 54 | // ~seq_priority~ is the priority of the sequence generating the transaction. 55 | // 56 | // This is a virtual task that must be implemented by the subclass. 57 | // 58 | virtual task execute(ref srm_generic_xact_t generic_xact, int seq_priority); 59 | endtask 60 | 61 | // Function: generic_xact_to_hdl_data 62 | // 63 | // Converts the byte array from generic xact to uvm_hdl_data_t type. 64 | // 65 | // ~generic_xact~ is the generic transaction emitted by the register model. 66 | // 67 | // Returns the uvm_hdl_data_t 68 | // 69 | function uvm_hdl_data_t generic_xact_to_hdl_data(ref srm_generic_xact_t generic_xact); 70 | uvm_hdl_data_t hdl_data = 'd0; 71 | // [31:0] = {byte3, byte2, byte1, byte0} 72 | for(int i = generic_xact.data.size()-1; i >= 0; i--) begin 73 | hdl_data <<= 8; 74 | hdl_data[7:0] = generic_xact.data[i]; 75 | end 76 | return hdl_data; 77 | endfunction 78 | 79 | // Function: hdl_data_to_generic_xact 80 | // 81 | // Converts the hdl data type to byte array inside the generic xact. 82 | // 83 | // ~generic_xact~ is the generic transaction that will be updated. 84 | // 85 | // ~hdl_data~ is the incoming data reg. 86 | // 87 | function hdl_data_to_generic_xact(ref srm_generic_xact_t generic_xact, uvm_hdl_data_t hdl_data); 88 | foreach(generic_xact.data[i]) begin 89 | generic_xact.data[i] = hdl_data[7:0]; 90 | hdl_data >>= 8; 91 | end 92 | endfunction 93 | 94 | endclass 95 | 96 | `endif 97 | -------------------------------------------------------------------------------- /distrib/src/bus/srm_bus_predictor.svh: -------------------------------------------------------------------------------- 1 | // 2 | // -------------------------------------------------------------- 3 | // Copyright (c) 2017-2023, Juniper Networks, Inc. 4 | // All rights reserved. 5 | // 6 | // This code is licensed to you under the MIT license. 7 | // You many not use this code except in compliance with this license. 8 | // This code is not an official Juniper product. You may obtain a copy 9 | // of the license at 10 | // 11 | // https://opensource.org/licenses/MIT 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 16 | // implied. See the License for the specific language governing 17 | // permissions and limitations under the License. 18 | // ------------------------------------------------------------- 19 | // 20 | `ifndef INCLUDED_srm_bus_predictor 21 | `define INCLUDED_srm_bus_predictor 22 | 23 | // Class: srm_bus_predictor 24 | // Abstract base class for updating the register model with the transaction on the bus. 25 | // 26 | // This uvm component is used in *passive* mode where we need to update the model (say 27 | // for coverage) due to accesses by an embedded cpu or legacy traffic. The TbWriter would 28 | // subclass this component and provide the implementation of bus2_generic_xact. Then he/she 29 | // would hook the output of the bus monitor to the analysis port of this component. 30 | // 31 | typedef class srm_node; 32 | 33 | class srm_bus_predictor #(type BUSTYPE=int) extends uvm_component; 34 | 35 | `uvm_component_param_utils(srm_bus_predictor#(BUSTYPE)) 36 | 37 | // Variable: bus_in 38 | // Observed bus transacations of type ~BUSTYPE~ are received from this 39 | // port and processed. 40 | // 41 | uvm_analysis_imp #(BUSTYPE, srm_bus_predictor #(BUSTYPE)) bus_in; 42 | 43 | // Variable: regmodel 44 | // This is used to update the corresponding register. Must be configured before 45 | // the run phase. 46 | srm_node regmodel; 47 | 48 | // Variable: addr_map_name 49 | // This is used to find the corresponding register. Must be configured before 50 | // the run phase. 51 | string addr_map_name; 52 | 53 | // Function: new 54 | // Create a new instance of this type, giving the optional ~name~ and ~parent~. 55 | // 56 | function new(string name, uvm_component parent); 57 | super.new(name, parent); 58 | bus_in = new("bus_in", this); 59 | endfunction 60 | 61 | // Function: bus2reg 62 | // Convert the bus transacation to a generic register transaction. 63 | // 64 | // Derived class must override this to convert bus to generic transaction. 65 | // 66 | virtual function srm_generic_xact_t bus_2_generic_xact(BUSTYPE tr); 67 | srm_generic_xact_t x; 68 | return x; 69 | endfunction 70 | 71 | // Function: write 72 | // Triggered when the bus transaction appears on the analysis import *bus_in* 73 | // 74 | // Converts the bus xact to generic, extract the address and do a reverse map to find 75 | // the node instance. Then it updates the node with the transaction. 76 | // 77 | // If the reverse map fails then the function will raise uvm_fatal. 78 | // 79 | virtual function void write(BUSTYPE tr); 80 | srm_generic_xact_t xact; 81 | srm_node node; 82 | xact = bus_2_generic_xact(tr); 83 | node = regmodel.address_2_instance(addr_map_name, xact.addr); 84 | if(node == null) begin 85 | `uvm_fatal("TbConfigurationError", 86 | $psprintf("Could not find node for address=0x%0x in address map \"%s\"", 87 | xact.addr, addr_map_name)); 88 | end 89 | node.predictor_update(xact); 90 | endfunction 91 | 92 | endclass 93 | 94 | `endif 95 | -------------------------------------------------------------------------------- /distrib/src/bus/srm_generic_xact.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_srm_generic_xact_svh 2 | `define INCLUDED_srm_generic_xact_svh 3 | 4 | //----------------------------------------------------------------- 5 | // STRUCT: srm_generic_xact 6 | // Generic bus xact emitted by the register model. 7 | // 8 | // The adapter class will translate this generic xact into design specific 9 | // transaction. 10 | // 11 | // DataFormat: 12 | // {byte_n, byte_n_1,......, byte_1, byte_0} = [msb....lsb] 13 | //----------------------------------------------------------------- 14 | typedef struct { 15 | string addr_map_name; // Name of the address map. 16 | srm_access_e kind; // Read/Write cmd. 17 | srm_addr_t addr; // Byte address of the register. 18 | srm_data_t data; // List of bytes to be written/read. 19 | srm_byte_enable_t byte_enables; // List of byte enables. 20 | srm_status_e status; // Return value from agent. 21 | } srm_generic_xact_t; 22 | 23 | 24 | `endif 25 | -------------------------------------------------------------------------------- /distrib/src/srm.sv: -------------------------------------------------------------------------------- 1 | // 2 | // -------------------------------------------------------------- 3 | // Copyright (c) 2017-2023, Juniper Networks, Inc. 4 | // All rights reserved. 5 | // 6 | // This code is licensed to you under the MIT license. 7 | // You many not use this code except in compliance with this license. 8 | // This code is not an official Juniper product. You may obtain a copy 9 | // of the license at 10 | // 11 | // https://opensource.org/licenses/MIT 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 16 | // implied. See the License for the specific language governing 17 | // permissions and limitations under the License. 18 | // ------------------------------------------------------------- 19 | // 20 | `include "srm_pkg.sv" 21 | -------------------------------------------------------------------------------- /distrib/src/srm_pkg.sv: -------------------------------------------------------------------------------- 1 | // 2 | // -------------------------------------------------------------- 3 | // Copyright (c) 2017-2023, Juniper Networks, Inc. 4 | // All rights reserved. 5 | // 6 | // This code is licensed to you under the MIT license. 7 | // You many not use this code except in compliance with this license. 8 | // This code is not an official Juniper product. You may obtain a copy 9 | // of the license at 10 | // 11 | // https://opensource.org/licenses/MIT 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 16 | // implied. See the License for the specific language governing 17 | // permissions and limitations under the License. 18 | // ------------------------------------------------------------- 19 | // 20 | `ifndef INCLUDED_srm_pkg_sv 21 | `define INCLUDED_srm_pkg_sv 22 | 23 | `include "uvm_macros.svh" 24 | 25 | package srm_pkg; 26 | import uvm_pkg::*; 27 | typedef longint srm_addr_t; 28 | typedef srm_addr_t srm_addr_lst_t[]; 29 | typedef byte srm_data_t[]; 30 | typedef bit srm_byte_enable_t[]; 31 | 32 | typedef enum { 33 | SRM_READ, 34 | SRM_WRITE 35 | } srm_access_e; 36 | 37 | typedef enum { 38 | SRM_IS_OK, 39 | SRM_NOT_OK, 40 | SRM_READ_DATA_MISMATCH, 41 | SRM_HAS_X 42 | } srm_status_e; 43 | 44 | typedef enum { 45 | SRM_NO_HIER, 46 | SRM_HIER 47 | } srm_hier_e; 48 | 49 | `include "common/srm_utils.svh" 50 | `include "bus/srm_generic_xact.svh" 51 | `include "bus/srm_bus_adapter.svh" 52 | `include "bus/srm_bus_predictor.svh" 53 | `include "base/srm_base_field_policy.svh" 54 | `include "base/srm_base_field.svh" 55 | `include "base/srm_field.svh" 56 | `include "base/srm_field_policies.svh" 57 | `include "base/srm_base_coverage.svh" 58 | `include "base/srm_base_handle.svh" 59 | `include "base/srm_node.svh" 60 | `include "base/srm_base_reg.svh" 61 | `include "base/srm_reg.svh" 62 | `include "base/srm_table_entry.svh" 63 | `include "base/srm_table.svh" 64 | endpackage 65 | 66 | `endif 67 | -------------------------------------------------------------------------------- /docs/Notes.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | This is the top level directory of the simple reg model repository. The distrib directory will contain code that is intended for distribution. 3 | 4 | ## Simple Register Model 5 | Simple Register Model (srm) are system verilog classes that help to develop register model (aka regstore, register abstraction layer) for uvm testbenches. It is open sourced and available under MIT license. 6 | 7 | It is designed to be used in uvm testbenches instead of the *uvm_reg* package that is shipped with uvm distribution. 8 | 9 | The intended users of the package are design verificatipn (DV) engineers involved in developing uvm testbneches and writing uvm sequences for verifying the design. 10 | 11 | ## Getting the Distribution 12 | This git repo is the development directory for the register package. Users of the package should download and install the tar version from here. 13 | 14 | ## Overview 15 | A typical setup of a uvm testbench using srm register package is shown below in Figure 1. A srm register model of a chip consist of a register map as shown. The register model generates generic bus transactions that are sent to the appropriate adapter which forwards it to the bus specific agent. 16 | 17 | ![Srm Example](docs/images/srm_example.jpg) 18 | 19 | ## Limitations Of UVM Register Package 20 | 21 | ### A. Large Memory Footprint 22 | UVM register package causes memory to be statically allocated for all the locations in the address map, independent of the actual locations accessed by the test. In fact, each register needs to be as large as the largest register in the design. It is well known that most tests, especially at the system level, access only a small fraction of the address space. Hence it is wasteful to pay for all the locations in each test. 23 | UVM register does provide a “vreg” lightweight api. This is just an access API with no storage inside the model intended for memories with their own custom model (like external memories). Hence this is not a valid solution for on chip structures. 24 | 25 | ### B. Randomization Fails For Large Tables 26 | In current chips that I work on, I have extensive tables implemented as embedded memories inside the design. UVM register has no equivalent classes to model these tables and instead implements them as static array of registers. Time taken for randomization on these static arrays increases exponentially with the number of entries, and I find that I can practically only randomize tables of less than 5K entries. 27 | 28 | ### C. Confusing Access API 29 | The UVM register package exposes 3 values associated with each register (“mirrored value”, “desired value” and “random value”) to the test writer. To manipulate these, the test writer has to choose a multitude of access functions like “mirror”, “update”, “predict” etc. I find this strategy of creating multiple access methods to implement independent concerns of randomization and access type, confusing and hard to remember for the test writer. It was interesting to find that others on the internet had reached the same conclusion. 30 | 31 | ### D. Hard to Understand Code 32 | In UVM 1.1d, the 26 files are containing over 22,000 lines of source code for the register package. In the User Guide, the description of the UVM Register layer, is alone 26% of the number of pages. Hence it is hard to understand and modify it. 33 | 34 | ## Advantages Of SRM Register Package 35 | 36 | ### A. Efficient Memory Footprint 37 | SRM models tables by the “srm_table” which uses an associative array for storage. Hence entries are allocated only when written. The registers are modeled as template classes “srm_reg” and so the storage is limited to the actual size of the register. 38 | 39 | ### B. Randomization Works For Large Tables 40 | Randomization in SRM is implemented separately as a separate hierarchy of system verilog constraint classes. The test writer can apply the constraints on each entry of the table individually in a loop instead of applying it to the entire table in one shot. 41 | 42 | ### C. Clean Access API 43 | The SRM access API exposes only the last value written by the test writer. Writes to the register always update this value and read, by default, checks all the nonvolatile fields in this value. Field access are allowed and the generic bus transactions have byte enables to identify the bytes being written and read to. It is the responsibility of the bus adapter to translate these partial transactions to actual writes and reads. 44 | 45 | ### D. Modular Code 46 | The core SRM consists of < 4K lines of code. It cleanly separates randomization, access type (frontdoor/sidedoor/backdoor) into a separate class hierarchy, so each class has only a single responsibility. Each class has unit tests to enable high coverage. 47 | 48 | ## Additional Links 49 | 50 | Please follow the links below for more details. 51 | 1. **Creating a distribution**: [Details](docs/release.md) 52 | 53 | 2. **UVM Testbench Integration**: [Details](docs/testbench.md) 54 | 55 | -------------------------------------------------------------------------------- /docs/images/Slide23.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/docs/images/Slide23.JPG -------------------------------------------------------------------------------- /docs/images/Slide8.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/docs/images/Slide8.JPG -------------------------------------------------------------------------------- /docs/images/srm_example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/docs/images/srm_example.jpg -------------------------------------------------------------------------------- /docs/images/srm_uvm_active.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/docs/images/srm_uvm_active.jpg -------------------------------------------------------------------------------- /docs/images/srm_uvm_passive.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/docs/images/srm_uvm_passive.jpg -------------------------------------------------------------------------------- /docs/overview.txt: -------------------------------------------------------------------------------- 1 | Title: Overview 2 | 3 | There are 2 major classes. The template class "srm_reg" models single entry register. Register arrays are just a composite class of many such register. Each register consist of a list of fields modelled as a template "srm_field" class. Each srm_field has certain attributes like width, access policy etc. 4 | 5 | The class diagram of a register layer model is shown below. 6 | 7 | The parent class is called "srm_component" which represents the node in the hierarchy tree. The class "srm_base_reg" handles all the generic operations on the register. Similarly the "srm_base_field" handles all the generic field operations. The class "srm_array_entry" derived from "srm_reg" represents each entry in the array. 8 | 9 | (see basic_class_hier.png) 10 | 11 | -------------------------------------------------------------------------------- /docs/release.md: -------------------------------------------------------------------------------- 1 | 1. Create a sandbox 2 | ``` 3 | mkdir /srm-1.0 4 | ``` 5 | 6 | 2. Generate the documentation. 7 | ``` 8 | source env/setup.bash 9 | cd docs/nd 10 | ./gen_nd 11 | ``` 12 | 13 | 3. Copy the distrib directory 14 | ``` 15 | cd ../../ 16 | cp -r distrib/* 17 | tar cvfz srm-1.0.tar.gz * 18 | mv srm-1.0.tar.gz 19 | ``` 20 | -------------------------------------------------------------------------------- /docs/testbench.md: -------------------------------------------------------------------------------- 1 | ## UVM Testbench Active Mode 2 | In active operation, the register access is sourced from the register model via the access API. These read and write operations on the register model are converted to generic bus transactions by the model. These are then forwarded to the selected bus adapter as per the configured adapter policy. The bus adapter chosen implements the actual conversion from the generic transaction to the specific bus transaction. Unlike UVM registers, even backdoor is implemented as a separate adapter rather than being a part of the register model. 3 | 4 | This is shown below in Figure 1. Here the model has a handle to 3 adapters. The backdoor adapter may just use dpi to directly set/get the design flops. A frontdoor adapter instead would run the actual bus transaction to implement the transfer. A sidedoor adapter may skip the DUT host block and issue the access directly to the block’s local pio decoder. 5 | 6 | ![Uvm Active](images/srm_uvm_active.jpg) 7 | Figure 1: UVM Testbench Active Mode 8 | 9 | ## UVM Testbench Passive Mode 10 | For passive operation, the register access is not generated by the register model. This could be created by some other mechanism like embedded software, or a legacy non UVM environment but the model is still required to be accurate for the checks and functional coverage. 11 | In this case, a predictor is used to observe the bus transactions and then forward them to the SRM register model. An example of Instruction set simulator based test bench is shown below in Figure 2. 12 | 13 | ![Uvm Passive](images/srm_uvm_passive.jpg) 14 | Figure 2: UVM Testbench Passive Mode 15 | 16 | -------------------------------------------------------------------------------- /env/jnpr_setup.csh: -------------------------------------------------------------------------------- 1 | source env/setup.csh 2 | 3 | # Juniper specific configuration 4 | setenv UVM_HOME /volume/ea-verif02/users/sanjeevs/work/uvm-1.2 5 | module add vcs/2014.03-SP1-3 6 | module add verilog/INCISIVE15.10.022 7 | setenv UML_HOME $HOME/work/uml 8 | setenv GRAPHVIZ_DOT /usr/bin/dot 9 | -------------------------------------------------------------------------------- /env/setup.bash: -------------------------------------------------------------------------------- 1 | export SRM_ROOT=`pwd` 2 | export PATH=$PATH:$SRM_ROOT/bin:$SRM_ROOT/unit_fwk 3 | export UML_HOME=$HOME/work/uml 4 | export GRAPHVIZ_DOT=/usr/bin/dot 5 | 6 | -------------------------------------------------------------------------------- /env/setup.csh: -------------------------------------------------------------------------------- 1 | setenv SRM_ROOT `pwd` 2 | setenv SRM_HOME $SRM_ROOT/distrib 3 | set path = ($path $SRM_ROOT/scripts $SRM_ROOT/unit_fwk/) 4 | 5 | -------------------------------------------------------------------------------- /natural_docs/Info/NDMarkup.txt: -------------------------------------------------------------------------------- 1 | 2 | Architecture: NDMarkup 3 | _______________________________________________________________________________ 4 | 5 | A markup format used by the parser, both internally and in objects. Text formatted in 6 | NDMarkup will only have the tags documented below. 7 | 8 | 9 | About: Top-Level Tags 10 | 11 | All content will be surrounded by one of the top-level tags. These tags will not appear within each other. 12 | 13 |

- Surrounds a paragraph. Paragraph breaks will replace double line breaks, and single line breaks will 14 | be removed completely. 15 | 16 | - Surrounds code or text diagrams that should appear literally in the output. 17 | 18 | - Surrounds a heading. 19 | 20 |
    - Surrounds a bulleted (unordered) list. 21 |
    - Surrounds a description list, which is what you are reading. 22 | 23 | - An inline image. Target contains the image target, and original contains the 24 | original text in case it doesn't resolve. 25 | 26 | 27 | About: List Item Tags 28 | 29 | These tags will only appear within their respective lists. 30 | 31 |
  • - Surrounds a bulleted list item. 32 | - Surrounds a description list entry, which is the left side. It will always be followed by a description list 33 | description. 34 | - Surrounds a description list symbol. This is the same as a description list entry, except that the content 35 | is also a referenceable symbol. This occurs when inside a list topic. This tag will always 36 | be followed by a description list description. 37 |
    - Surrounds a description list description, which is the right side. It will always be preceded by a description 38 | list entry or symbol. 39 | 40 | About: Text Tags 41 | 42 | These tags will only appear in paragraphs, headings, or description list descriptions. 43 | 44 | - Bold 45 | - Italics 46 | - Underline 47 | 48 | - Surrounds a potential link to a symbol; potential because the target is not guaranteed to 49 | exist. This tag merely designates an attempted link. Target is what is attempting to be 50 | linked to, name is the text that should appear for a successful link, and original is the 51 | original text in case the link doesn't resolve. 52 | 53 | - An external link. There's no need for an original attribute because it will always be 54 | turned into an actual link. 55 | - A link to an e-mail address. 56 | 57 | - An image link. Target contains the image target, and original contains the original 58 | text in case it doesn't resolve. 59 | 60 | 61 | About: Amp Chars 62 | 63 | These are the only amp chars supported, and will appear everywhere. Every other character will appear as is. 64 | 65 | & - The ampersand &. 66 | " - The double quote ". 67 | < - The less than sign <. 68 | > - The greater than sign >. 69 | 70 | About: Tabs 71 | 72 | NDMarkup will not contain tab characters, only spaces. Any tab characters appearing in the source files will be 73 | expanded/replaced as necessary. 74 | 75 | 76 | About: General Tag Properties 77 | 78 | Since the tags are generated, they will always have the following properties, which will make pattern matching much 79 | easier. 80 | 81 | - Tags and amp chars will always be in all lowercase. 82 | - Properties will appear exactly as documented here. They will be in all lowercase, in the documented order, and will have no 83 | extraneous whitespace. Anything appearing in the properties will have amp chars. 84 | - All code is valid, meaning tags will always be closed,
  • s will only appear within
      s, etc. 85 | 86 | So, for example, you can match description list entries with /(.+?)<\/de>/ and $1 will be the text. No surprises or 87 | gotchas. No need for sophisticated parsing routines. 88 | 89 | Remember that for symbol definitions, the text should appear as is, but internally (such as for the anchor) they need to 90 | be passed through Defines()> so that the output file is just as tolerant as 91 | . 92 | -------------------------------------------------------------------------------- /natural_docs/Info/images/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/Info/images/Logo.png -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/ClassHierarchy/File.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Class: NaturalDocs::ClassHierarchy::File 4 | # 5 | ############################################################################### 6 | # 7 | # An object that stores information about what hierarchy information is present in a file. It does not store its ; it 8 | # assumes that it will be stored in a hashref where the key is the . 9 | # 10 | ############################################################################### 11 | 12 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 13 | # Natural Docs is licensed under the GPL 14 | 15 | use strict; 16 | use integer; 17 | 18 | package NaturalDocs::ClassHierarchy::File; 19 | 20 | 21 | # 22 | # Topic: Implementation 23 | # 24 | # Since there's only one member in the class, and it's a hashref, the class is simply the hashref itself blessed as a class. 25 | # The keys are the class that are defined in the file, and the values are existence hashrefs of each class' 26 | # parent , or undef if none. 27 | # 28 | 29 | 30 | ############################################################################### 31 | # Group: Modification Functions 32 | 33 | 34 | # 35 | # Function: New 36 | # 37 | # Creates and returns a new class. 38 | # 39 | sub New 40 | { 41 | my ($package) = @_; 42 | 43 | my $object = { }; 44 | bless $object, $package; 45 | 46 | return $object; 47 | }; 48 | 49 | # 50 | # Function: AddClass 51 | # Adds a rew class to the file. 52 | # 53 | sub AddClass #(class) 54 | { 55 | my ($self, $class) = @_; 56 | 57 | if (!exists $self->{$class}) 58 | { $self->{$class} = undef; }; 59 | }; 60 | 61 | # 62 | # Function: DeleteClass 63 | # Deletes a class from the file. 64 | # 65 | sub DeleteClass #(class) 66 | { 67 | my ($self, $class) = @_; 68 | delete $self->{$class}; 69 | }; 70 | 71 | # 72 | # Function: AddParentReference 73 | # Adds a parent to a class . 74 | # 75 | sub AddParentReference #(class, parentReference) 76 | { 77 | my ($self, $class, $parent) = @_; 78 | 79 | if (!exists $self->{$class} || !defined $self->{$class}) 80 | { $self->{$class} = { }; }; 81 | 82 | $self->{$class}->{$parent} = 1; 83 | }; 84 | 85 | # 86 | # Function: DeleteParentReference 87 | # Deletes a parent from a class . 88 | # 89 | sub DeleteParentReference #(class, parent) 90 | { 91 | my ($self, $class, $parent) = @_; 92 | 93 | if (exists $self->{$class}) 94 | { 95 | delete $self->{$class}->{$parent}; 96 | 97 | if (!scalar keys %{$self->{$class}}) 98 | { $self->{$class} = undef; }; 99 | }; 100 | }; 101 | 102 | 103 | 104 | ############################################################################### 105 | # Group: Information Functions 106 | 107 | 108 | # 109 | # Function: Classes 110 | # Returns an array of the class that are defined by this file, or an empty array if none. 111 | # 112 | sub Classes 113 | { 114 | my ($self) = @_; 115 | return keys %{$self}; 116 | }; 117 | 118 | # 119 | # Function: HasClass 120 | # Returns whether the file defines the passed class . 121 | # 122 | sub HasClass #(class) 123 | { 124 | my ($self, $class) = @_; 125 | return exists $self->{$class}; 126 | }; 127 | 128 | # 129 | # Function: ParentReferencesOf 130 | # Returns an array of the parent that are defined by the class, or an empty array if none. 131 | # 132 | sub ParentReferencesOf #(class) 133 | { 134 | my ($self, $class) = @_; 135 | 136 | if (!exists $self->{$class} || !defined $self->{$class}) 137 | { return ( ); } 138 | else 139 | { return keys %{$self->{$class}}; }; 140 | }; 141 | 142 | # 143 | # Function: HasParentReference 144 | # Returns whether the file defines the passed class and parent . 145 | # 146 | sub HasParentReference #(class, parent) 147 | { 148 | my ($self, $class, $parent) = @_; 149 | 150 | if (!$self->HasClass($class)) 151 | { return undef; }; 152 | 153 | return exists $self->{$class}->{$parent}; 154 | }; 155 | 156 | 157 | 1; 158 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/DefineMembers.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Package: NaturalDocs::DefineMembers 4 | # 5 | ############################################################################### 6 | # 7 | # A custom Perl pragma to define member constants and accessors for use in Natural Docs objects while supporting inheritance. 8 | # 9 | # Each member will be defined as a numeric constant which should be used as that variable's index into the object arrayref. 10 | # They will be assigned sequentially from zero, and take into account any members defined this way in parent classes. Note 11 | # that you can *not* use multiple inheritance with this method. 12 | # 13 | # If a parameter ends in parenthesis, it will be generated as an accessor for the previous member. If it also starts with "Set", 14 | # the accessor will accept a single parameter to replace the value with. If it's followed with "duparrayref", it will assume the 15 | # parameter is either an arrayref or undef, and if the former, will duplicate it to set the value. 16 | # 17 | # Example: 18 | # 19 | # > package MyPackage; 20 | # > 21 | # > use NaturalDocs::DefineMembers 'VAR_A', 'VarA()', 'SetVarA()', 22 | # > 'VAR_B', 'VarB()', 23 | # > 'VAR_C', 24 | # > 'VAR_D', 'VarD()', 'SetVarD() duparrayref'; 25 | # > 26 | # > sub SetC #(C) 27 | # > { 28 | # > my ($self, $c) = @_; 29 | # > $self->[VAR_C] = $c; 30 | # > }; 31 | # 32 | ############################################################################### 33 | 34 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 35 | # Natural Docs is licensed under the GPL 36 | 37 | 38 | package NaturalDocs::DefineMembers; 39 | 40 | sub import #(member, member, ...) 41 | { 42 | my ($self, @parameters) = @_; 43 | my $package = caller(); 44 | 45 | no strict 'refs'; 46 | my $parent = ${$package . '::ISA'}[0]; 47 | use strict 'refs'; 48 | 49 | my $memberConstant = 0; 50 | my $lastMemberName; 51 | 52 | if (defined $parent && $parent->can('END_OF_MEMBERS')) 53 | { $memberConstant = $parent->END_OF_MEMBERS(); }; 54 | 55 | my $code = '{ package ' . $package . ";\n"; 56 | 57 | foreach my $parameter (@parameters) 58 | { 59 | if ($parameter =~ /^(.+)\(\) *(duparrayref)?$/i) 60 | { 61 | my ($functionName, $pragma) = ($1, lc($2)); 62 | 63 | if ($functionName =~ /^Set/) 64 | { 65 | if ($pragma eq 'duparrayref') 66 | { 67 | $code .= 68 | 'sub ' . $functionName . ' 69 | { 70 | if (defined $_[1]) 71 | { $_[0]->[' . $lastMemberName . '] = [ @{$_[1]} ]; } 72 | else 73 | { $_[0]->[' . $lastMemberName . '] = undef; }; 74 | };' . "\n"; 75 | } 76 | else 77 | { 78 | $code .= 'sub ' . $functionName . ' { $_[0]->[' . $lastMemberName . '] = $_[1]; };' . "\n"; 79 | }; 80 | } 81 | else 82 | { 83 | $code .= 'sub ' . $functionName . ' { return $_[0]->[' . $lastMemberName . ']; };' . "\n"; 84 | }; 85 | } 86 | else 87 | { 88 | $code .= 'use constant ' . $parameter . ' => ' . $memberConstant . ";\n"; 89 | $memberConstant++; 90 | $lastMemberName = $parameter; 91 | }; 92 | }; 93 | 94 | $code .= 'use constant END_OF_MEMBERS => ' . $memberConstant . ";\n"; 95 | $code .= '};'; 96 | 97 | eval $code; 98 | }; 99 | 100 | 1; 101 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Package: NaturalDocs::ImageReferenceTable::Reference 4 | # 5 | ############################################################################### 6 | # 7 | # A class for references being tracked in . 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | 18 | package NaturalDocs::ImageReferenceTable::Reference; 19 | 20 | use base 'NaturalDocs::SourceDB::Item'; 21 | 22 | 23 | use NaturalDocs::DefineMembers 'TARGET', 'Target()', 'SetTarget()', 24 | 'NEEDS_REBUILD', 'NeedsRebuild()', 'SetNeedsRebuild()'; 25 | 26 | 27 | # 28 | # Variables: Members 29 | # 30 | # The following constants are indexes into the object array. 31 | # 32 | # TARGET - The image this reference resolves to, or undef if none. 33 | # 34 | 35 | 36 | # 37 | # Functions: Member Functions 38 | # 39 | # Target - Returns the image this reference resolves to, or undef if none. 40 | # SetTarget - Replaces the image this reference resolves to, or undef if none. 41 | # 42 | 43 | 44 | 1; 45 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/ImageReferenceTable/String.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Package: NaturalDocs::ImageReferenceTable::String 4 | # 5 | ############################################################################### 6 | # 7 | # A package for creating and managing . 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | 18 | package NaturalDocs::ImageReferenceTable::String; 19 | 20 | 21 | # 22 | # Type: ImageReferenceString 23 | # 24 | # A string representing a unique image reference. It's composed of the reference text and the directory of the source file. 25 | # The source file name itself isn't included because two files in the same directory with the same reference text will always go 26 | # to the same targets. 27 | # 28 | 29 | 30 | # 31 | # Function: Make 32 | # 33 | # Converts a source and the reference text to an . 34 | # 35 | sub Make #(FileName sourceFile, string text) => ImageReferenceString 36 | { 37 | my ($self, $sourceFile, $text) = @_; 38 | 39 | my $path = NaturalDocs::File->NoFileName($sourceFile); 40 | 41 | # Condense whitespace and remove any separator characters. 42 | $path =~ tr/ \t\r\n\x1C/ /s; 43 | $text =~ tr/ \t\r\n\x1C/ /s; 44 | 45 | return $path . "\x1C" . $text; 46 | }; 47 | 48 | 49 | # 50 | # Function: InformationOf 51 | # 52 | # Returns the information contained in the as the array ( path, text ). 53 | # 54 | sub InformationOf #(ImageReferenceString referenceString) 55 | { 56 | my ($self, $referenceString) = @_; 57 | return split(/\x1C/, $referenceString); 58 | }; 59 | 60 | 61 | # 62 | # Function: ToBinaryFile 63 | # 64 | # Writes an to . Can also encode an undef. 65 | # 66 | # Format: 67 | # 68 | # > [AString16: path] [AString16: reference text] ... 69 | # 70 | # Undef is represented by the first AString16 being undef. 71 | # 72 | sub ToBinaryFile #(ImageReferenceString referenceString) 73 | { 74 | my ($self, $referenceString) = @_; 75 | 76 | if (defined $referenceString) 77 | { 78 | my ($path, $text) = split(/\x1C/, $referenceString); 79 | 80 | NaturalDocs::BinaryFile->WriteAString16($path); 81 | NaturalDocs::BinaryFile->WriteAString16($text); 82 | } 83 | else 84 | { 85 | NaturalDocs::BinaryFile->WriteAString16(undef); 86 | }; 87 | }; 88 | 89 | 90 | # 91 | # Function: FromBinaryFile 92 | # 93 | # Loads an or undef from and returns it. 94 | # 95 | sub FromBinaryFile 96 | { 97 | my $self = shift; 98 | 99 | my $path = NaturalDocs::BinaryFile->GetAString16(); 100 | 101 | if (!defined $path) 102 | { return undef; }; 103 | 104 | my $text = NaturalDocs::BinaryFile->GetAString16(); 105 | 106 | return $path . "\x1C" . $text; 107 | }; 108 | 109 | 110 | 1; 111 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/Languages/Ada.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Class: NaturalDocs::Languages::Ada 4 | # 5 | ############################################################################### 6 | # 7 | # A subclass to handle the language variations of Ada 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | package NaturalDocs::Languages::Ada; 18 | 19 | use base 'NaturalDocs::Languages::Simple'; 20 | 21 | 22 | # 23 | # Function: ParseParameterLine 24 | # Overridden because Ada uses Pascal-style parameters 25 | # 26 | sub ParseParameterLine #(...) 27 | { 28 | my ($self, @params) = @_; 29 | return $self->SUPER::ParsePascalParameterLine(@params); 30 | }; 31 | 32 | sub TypeBeforeParameter 33 | { 34 | return 0; 35 | }; 36 | 37 | 38 | 1; 39 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/Languages/Advanced/Scope.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Class: NaturalDocs::Languages::Advanced::Scope 4 | # 5 | ############################################################################### 6 | # 7 | # A class used to store a scope level. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | package NaturalDocs::Languages::Advanced::Scope; 18 | 19 | # 20 | # Constants: Implementation 21 | # 22 | # The object is implemented as a blessed arrayref. The constants below are used as indexes. 23 | # 24 | # CLOSING_SYMBOL - The closing symbol character of the scope. 25 | # PACKAGE - The package of the scope. 26 | # USING - An arrayref of for using statements, or undef if none. 27 | # 28 | use NaturalDocs::DefineMembers 'CLOSING_SYMBOL', 'PACKAGE', 'USING'; 29 | # Dependency: New() depends on the order of these constants as well as that there is no inherited members. 30 | 31 | 32 | # 33 | # Function: New 34 | # 35 | # Creates and returns a new object. 36 | # 37 | # Parameters: 38 | # 39 | # closingSymbol - The closing symbol character of the scope. 40 | # package - The package of the scope. 41 | # using - An arrayref of using , or undef if none. The contents of the array will be duplicated. 42 | # 43 | # If package is set to undef, it is assumed that it inherits the value of the previous scope on the stack. 44 | # 45 | sub New #(closingSymbol, package, using) 46 | { 47 | # Dependency: This depends on the order of the parameters matching the constants, and that there are no inherited 48 | # members. 49 | my $package = shift; 50 | 51 | my $object = [ @_ ]; 52 | bless $object, $package; 53 | 54 | if (defined $object->[USING]) 55 | { $object->[USING] = [ @{$object->[USING]} ]; }; 56 | 57 | return $object; 58 | }; 59 | 60 | 61 | # Function: ClosingSymbol 62 | # Returns the closing symbol character of the scope. 63 | sub ClosingSymbol 64 | { return $_[0]->[CLOSING_SYMBOL]; }; 65 | 66 | # Function: Package 67 | # Returns the package of the scope, or undef if none. 68 | sub Package 69 | { return $_[0]->[PACKAGE]; }; 70 | 71 | # Function: SetPackage 72 | # Sets the package of the scope. 73 | sub SetPackage #(package) 74 | { $_[0]->[PACKAGE] = $_[1]; }; 75 | 76 | # Function: Using 77 | # Returns an arrayref of for using statements, or undef if none 78 | sub Using 79 | { return $_[0]->[USING]; }; 80 | 81 | # Function: AddUsing 82 | # Adds a to the array. 83 | sub AddUsing #(using) 84 | { 85 | my ($self, $using) = @_; 86 | 87 | if (!defined $self->[USING]) 88 | { $self->[USING] = [ ]; }; 89 | 90 | push @{$self->[USING]}, $using; 91 | }; 92 | 93 | 94 | 95 | 1; 96 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Class: NaturalDocs::Languages::Advanced::ScopeChange 4 | # 5 | ############################################################################### 6 | # 7 | # A class used to store a scope change. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | package NaturalDocs::Languages::Advanced::ScopeChange; 18 | 19 | # 20 | # Constants: Implementation 21 | # 22 | # The object is implemented as a blessed arrayref. The constants below are used as indexes. 23 | # 24 | # SCOPE - The new scope . 25 | # LINE_NUMBER - The line number of the change. 26 | # 27 | use NaturalDocs::DefineMembers 'SCOPE', 'LINE_NUMBER'; 28 | # Dependency: New() depends on the order of these constants as well as that there is no inherited members. 29 | 30 | 31 | # 32 | # Function: New 33 | # 34 | # Creates and returns a new object. 35 | # 36 | # Parameters: 37 | # 38 | # scope - The the scope was changed to. 39 | # lineNumber - What line it occurred on. 40 | # 41 | sub New #(scope, lineNumber) 42 | { 43 | # Dependency: This depends on the order of the parameters matching the constants, and that there are no inherited 44 | # members. 45 | my $self = shift; 46 | 47 | my $object = [ @_ ]; 48 | bless $object, $self; 49 | 50 | return $object; 51 | }; 52 | 53 | 54 | # Function: Scope 55 | # Returns the the scope was changed to. 56 | sub Scope 57 | { return $_[0]->[SCOPE]; }; 58 | 59 | # Function: SetScope 60 | # Replaces the the scope was changed to. 61 | sub SetScope #(scope) 62 | { $_[0]->[SCOPE] = $_[1]; }; 63 | 64 | # Function: LineNumber 65 | # Returns the line number of the change. 66 | sub LineNumber 67 | { return $_[0]->[LINE_NUMBER]; }; 68 | 69 | 70 | 1; 71 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/Languages/Prototype.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Class: NaturalDocs::Languages::Prototype 4 | # 5 | ############################################################################### 6 | # 7 | # A data class for storing parsed prototypes. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | use NaturalDocs::Languages::Prototype::Parameter; 18 | 19 | 20 | package NaturalDocs::Languages::Prototype; 21 | 22 | use NaturalDocs::DefineMembers 'BEFORE_PARAMETERS', 'BeforeParameters()', 'SetBeforeParameters()', 23 | 'AFTER_PARAMETERS', 'AfterParameters()', 'SetAfterParameters()', 24 | 'PARAMETERS', 'Parameters()'; 25 | # Dependency: New(), constant order, no parents. 26 | 27 | 28 | # 29 | # Function: New 30 | # 31 | # Creates and returns a new prototype object. 32 | # 33 | # Parameters: 34 | # 35 | # beforeParameters - The part of the prototype before the parameter list. 36 | # afterParameters - The part of the prototype after the parameter list. 37 | # 38 | # You cannot set the parameters from here. Use . 39 | # 40 | sub New #(beforeParameters, afterParameters) 41 | { 42 | my ($package, @params) = @_; 43 | 44 | # Dependency: Constant order, no parents. 45 | 46 | my $object = [ @params ]; 47 | bless $object, $package; 48 | 49 | return $object; 50 | }; 51 | 52 | 53 | # 54 | # Functions: Members 55 | # 56 | # BeforeParameters - Returns the part of the prototype before the parameter list. If there is no parameter list, this will be the 57 | # only thing that returns content. 58 | # SetBeforeParameters - Replaces the part of the prototype before the parameter list. 59 | # AfterParameters - Returns the part of the prototype after the parameter list, if any. 60 | # SetAfterParameters - Replaces the part of the prototype after the parameter list. 61 | # Parameters - Returns the parameter list as an arrayref of , or undef if none. 62 | # 63 | 64 | # 65 | # Function: AddParameter 66 | # 67 | # Adds a to the list. 68 | # 69 | sub AddParameter #(parameter) 70 | { 71 | my ($self, $parameter) = @_; 72 | 73 | if (!defined $self->[PARAMETERS]) 74 | { $self->[PARAMETERS] = [ ]; }; 75 | 76 | push @{$self->[PARAMETERS]}, $parameter; 77 | }; 78 | 79 | 80 | # 81 | # Function: OnlyBeforeParameters 82 | # 83 | # Returns whether is the only thing set. 84 | # 85 | sub OnlyBeforeParameters 86 | { 87 | my $self = shift; 88 | return (!defined $self->[PARAMETERS] && !defined $self->[AFTER_PARAMETERS]); 89 | }; 90 | 91 | 92 | 1; 93 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Class: NaturalDocs::Languages::Prototype::Parameter 4 | # 5 | ############################################################################### 6 | # 7 | # A data class for storing parsed prototype parameters. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | package NaturalDocs::Languages::Prototype::Parameter; 18 | 19 | use NaturalDocs::DefineMembers 'TYPE', 'Type()', 'SetType()', 20 | 'TYPE_PREFIX', 'TypePrefix()', 'SetTypePrefix()', 21 | 'NAME', 'Name()', 'SetName()', 22 | 'NAME_PREFIX', 'NamePrefix()', 'SetNamePrefix()', 23 | 'DEFAULT_VALUE', 'DefaultValue()', 'SetDefaultValue()', 24 | 'DEFAULT_VALUE_PREFIX', 'DefaultValuePrefix()', 'SetDefaultValuePrefix()'; 25 | # Dependency: New() depends on the order of these constants and that they don't inherit from another class. 26 | 27 | 28 | # 29 | # Constants: Members 30 | # 31 | # The object is implemented as a blessed arrayref, with the following constants as its indexes. 32 | # 33 | # TYPE - The parameter type, if any. 34 | # TYPE_PREFIX - The parameter type prefix which should be aligned separately, if any. 35 | # NAME - The parameter name. 36 | # NAME_PREFIX - The parameter name prefix which should be aligned separately, if any. 37 | # DEFAULT_VALUE - The default value expression, if any. 38 | # DEFAULT_VALUE_PREFIX - The default value prefix which should be aligned separately, if any. 39 | # 40 | 41 | # 42 | # Function: New 43 | # 44 | # Creates and returns a new prototype object. 45 | # 46 | # Parameters: 47 | # 48 | # type - The parameter type, if any. 49 | # typePrefix - The parameter type prefix which should be aligned separately, if any. 50 | # name - The parameter name. 51 | # namePrefix - The parameter name prefix which should be aligned separately, if any. 52 | # defaultValue - The default value expression, if any. 53 | # defaultValuePrefix - The default value prefix which should be aligned separately, if any. 54 | # 55 | sub New #(type, typePrefix, name, namePrefix, defaultValue, defaultValuePrefix) 56 | { 57 | my ($package, @params) = @_; 58 | 59 | # Dependency: This depends on the order of the parameters being the same as the order of the constants, and that the 60 | # constants don't inherit from another class. 61 | 62 | my $object = [ @params ]; 63 | bless $object, $package; 64 | 65 | return $object; 66 | }; 67 | 68 | 69 | # 70 | # Functions: Members 71 | # 72 | # Type - The parameter type, if any. 73 | # SetType - Replaces the parameter type. 74 | # TypePrefix - The parameter type prefix, which should be aligned separately, if any. 75 | # SetTypePrefix - Replaces the parameter type prefix. 76 | # Name - The parameter name. 77 | # SetName - Replaces the parameter name. 78 | # NamePrefix - The parameter name prefix, which should be aligned separately, if any. 79 | # SetNamePrefix - Replaces the parameter name prefix. 80 | # DefaultValue - The default value expression, if any. 81 | # SetDefaultValue - Replaces the default value expression. 82 | # DefaultValuePrefix - The default value prefix, which should be aligned separately, if any. 83 | # SetDefaultValuePrefix - Replaces the default value prefix. 84 | # 85 | 86 | 87 | 1; 88 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/NDMarkup.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Package: NaturalDocs::NDMarkup 4 | # 5 | ############################################################################### 6 | # 7 | # A package of support functions for dealing with . 8 | # 9 | # Usage and Dependencies: 10 | # 11 | # The package doesn't depend on any Natural Docs packages and is ready to use right away. 12 | # 13 | ############################################################################### 14 | 15 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 16 | # Natural Docs is licensed under the GPL 17 | 18 | 19 | use strict; 20 | use integer; 21 | 22 | package NaturalDocs::NDMarkup; 23 | 24 | # 25 | # Function: ConvertAmpChars 26 | # 27 | # Substitutes certain characters with their amp chars. 28 | # 29 | # Parameters: 30 | # 31 | # text - The block of text to convert. 32 | # 33 | # Returns: 34 | # 35 | # The converted text block. 36 | # 37 | sub ConvertAmpChars #(text) 38 | { 39 | my ($self, $text) = @_; 40 | 41 | $text =~ s/&/&/g; 42 | $text =~ s//>/g; 44 | $text =~ s/\"/"/g; 45 | 46 | return $text; 47 | }; 48 | 49 | 50 | # 51 | # Function: RestoreAmpChars 52 | # 53 | # Replaces amp chars with their original symbols. 54 | # 55 | # Parameters: 56 | # 57 | # text - The text to restore. 58 | # 59 | # Returns: 60 | # 61 | # The restored text. 62 | # 63 | sub RestoreAmpChars #(text) 64 | { 65 | my ($self, $text) = @_; 66 | 67 | $text =~ s/"/\"/g; 68 | $text =~ s/>/>/g; 69 | $text =~ s/</ since the last build. 32 | # DEFAULT_MENU_TITLE - The file's default title in the menu. 33 | # 34 | 35 | # DEPENDENCY: New() depends on its parameter list being in the same order as these constants. If the order changes, New() 36 | # needs to be changed. 37 | use NaturalDocs::DefineMembers 'HAS_CONTENT', 'LAST_MODIFIED', 'STATUS', 'DEFAULT_MENU_TITLE'; 38 | 39 | 40 | ############################################################################### 41 | # Group: Functions 42 | 43 | # 44 | # Function: New 45 | # 46 | # Creates and returns a new file object. 47 | # 48 | # Parameters: 49 | # 50 | # hasContent - Whether the file contains Natural Docs content or not. 51 | # lastModified - The integer timestamp of when the file was last modified. 52 | # status - The since the last build. 53 | # defaultMenuTitle - The file's title in the menu. 54 | # 55 | # Returns: 56 | # 57 | # A reference to the new object. 58 | # 59 | sub New #(hasContent, lastModified, status, defaultMenuTitle) 60 | { 61 | # DEPENDENCY: This function depends on its parameter list being in the same order as the member constants. If either order 62 | # changes, this function needs to be changed. 63 | 64 | my $package = shift; 65 | 66 | my $object = [ @_ ]; 67 | bless $object, $package; 68 | 69 | return $object; 70 | }; 71 | 72 | # Function: HasContent 73 | # Returns whether the file contains Natural Docs content or not. 74 | sub HasContent 75 | { return $_[0]->[HAS_CONTENT]; }; 76 | 77 | # Function: SetHasContent 78 | # Sets whether the file contains Natural Docs content or not. 79 | sub SetHasContent #(hasContent) 80 | { $_[0]->[HAS_CONTENT] = $_[1]; }; 81 | 82 | # Function: LastModified 83 | # Returns the integer timestamp of when the file was last modified. 84 | sub LastModified 85 | { return $_[0]->[LAST_MODIFIED]; }; 86 | 87 | # Function: SetLastModified 88 | # Sets the file's last modification timestamp. 89 | sub SetLastModified #(lastModified) 90 | { $_[0]->[LAST_MODIFIED] = $_[1]; }; 91 | 92 | # Function: Status 93 | # Returns the since the last build. 94 | sub Status 95 | { return $_[0]->[STATUS]; }; 96 | 97 | # Function: SetStatus 98 | # Sets the since the last build. 99 | sub SetStatus #(status) 100 | { $_[0]->[STATUS] = $_[1]; }; 101 | 102 | # Function: DefaultMenuTitle 103 | # Returns the file's default title on the menu. 104 | sub DefaultMenuTitle 105 | { return $_[0]->[DEFAULT_MENU_TITLE]; }; 106 | 107 | # Function: SetDefaultMenuTitle 108 | # Sets the file's default title on the menu. 109 | sub SetDefaultMenuTitle #(menuTitle) 110 | { $_[0]->[DEFAULT_MENU_TITLE] = $_[1]; }; 111 | 112 | 113 | 1; 114 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/Settings/BuildTarget.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Class: NaturalDocs::Settings::BuildTarget 4 | # 5 | ############################################################################### 6 | # 7 | # A class that stores information about a build target. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | package NaturalDocs::Settings::BuildTarget; 18 | 19 | use NaturalDocs::DefineMembers 'BUILDER', 'Builder()', 'SetBuilder()', 20 | 'DIRECTORY', 'Directory()', 'SetDirectory()'; 21 | 22 | 23 | # 24 | # Constants: Members 25 | # 26 | # The class is implemented as a blessed arrayref with the members below. 27 | # 28 | # BUILDER - The -derived object for the target's output format. 29 | # DIRECTORY - The output directory of the target. 30 | # 31 | 32 | # 33 | # Function: New 34 | # 35 | # Creates and returns a new object. 36 | # 37 | # Parameters: 38 | # 39 | # builder - The -derived object for the target's output format. 40 | # directory - The directory to place the output files in. 41 | # 42 | sub New #(builder, directory) 43 | { 44 | my ($package, $builder, $directory) = @_; 45 | 46 | my $object = [ ]; 47 | bless $object, $package; 48 | 49 | $object->SetBuilder($builder); 50 | $object->SetDirectory($directory); 51 | 52 | return $object; 53 | }; 54 | 55 | 56 | # 57 | # Functions: Member Functions 58 | # 59 | # Builder - Returns the -derived object for the target's output format. 60 | # SetBuilder - Replaces the -derived object for the target's output format. 61 | # Directory - Returns the directory for the target's output files. 62 | # SetDirectory - Replaces the directory for the target's output files. 63 | # 64 | 65 | 66 | 1; 67 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/SourceDB/Extension.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Package: NaturalDocs::SourceDB::Extension 4 | # 5 | ############################################################################### 6 | # 7 | # A base package for all extensions. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | 18 | package NaturalDocs::SourceDB::Extension; 19 | 20 | 21 | ############################################################################### 22 | # Group: Interface Functions 23 | # These functions must be overridden by the derived class. 24 | 25 | 26 | # 27 | # Function: Register 28 | # 29 | # Override this function to register the package with RegisterExtension()>. 30 | # 31 | sub Register 32 | { 33 | die "Called SourceDB::Extension->Register(). This function should be overridden by every extension."; 34 | }; 35 | 36 | 37 | # 38 | # Function: Load 39 | # 40 | # Called by Load()> to load the extension's data. Returns whether it was successful. 41 | # 42 | # *This function might not be called.* If there's a situation that would cause all the source files to be reparsed anyway, 43 | # may skip calling Load() for the remaining extensions. You should *not* depend on this function 44 | # for any critical initialization that needs to happen every time regardless. 45 | # 46 | sub Load # => bool 47 | { 48 | return 1; 49 | }; 50 | 51 | 52 | # 53 | # Function: Save 54 | # 55 | # Called by Save()> to save the extension's data. 56 | # 57 | sub Save 58 | { 59 | }; 60 | 61 | 62 | # 63 | # Function: OnDeletedDefinition 64 | # 65 | # Called for each definition deleted by . This is called *after* the definition has been deleted from 66 | # the database, so don't expect to be able to read it. 67 | # 68 | sub OnDeletedDefinition #(string itemString, FileName file, bool wasLastDefinition) 69 | { 70 | }; 71 | 72 | 73 | # 74 | # Function: OnChangedDefinition 75 | # 76 | # Called for each definition changed by . This is called *after* the definition has been changed, so 77 | # don't expect to be able to read the original value. 78 | # 79 | sub OnChangedDefinition #(string itemString, FileName file) 80 | { 81 | }; 82 | 83 | 84 | 1; 85 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/SourceDB/File.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Package: NaturalDocs::SourceDB::File 4 | # 5 | ############################################################################### 6 | # 7 | # A class used to index items by file. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | 18 | package NaturalDocs::SourceDB::File; 19 | 20 | use NaturalDocs::DefineMembers 'ITEMS'; 21 | 22 | 23 | # 24 | # Variables: Members 25 | # 26 | # These constants serve as indexes into the object array. 27 | # 28 | # ITEMS - An arrayref where an is the index and the members are existence hashrefs of the item strigs defined 29 | # in this file. The arrayref will always exist, but the hashrefs may be undef. 30 | # 31 | 32 | 33 | # 34 | # Function: New 35 | # 36 | # Returns a new object. 37 | # 38 | sub New 39 | { 40 | my $package = shift; 41 | 42 | my $object = [ ]; 43 | $object->[ITEMS] = [ ]; 44 | 45 | bless $object, $package; 46 | return $object; 47 | }; 48 | 49 | 50 | # 51 | # Function: AddItem 52 | # 53 | # Adds an item to this file. Returns whether this added a new item. 54 | # 55 | sub AddItem #(ExtensionID extension, string itemString) => bool 56 | { 57 | my ($self, $extension, $itemString) = @_; 58 | 59 | if (!defined $self->[ITEMS]->[$extension]) 60 | { 61 | $self->[ITEMS]->[$extension] = { $itemString => 1 }; 62 | return 1; 63 | } 64 | elsif (!exists $self->[ITEMS]->[$extension]->{$itemString}) 65 | { 66 | $self->[ITEMS]->[$extension]->{$itemString} = 1; 67 | return 1; 68 | } 69 | else 70 | { 71 | return 0; 72 | }; 73 | }; 74 | 75 | 76 | # 77 | # Function: HasItem 78 | # 79 | # Returns whether the item exists in this file. 80 | # 81 | sub HasItem #(ExtensionID extension, string itemString) => bool 82 | { 83 | my ($self, $extension, $itemString) = @_; 84 | 85 | if (defined $self->[ITEMS]->[$extension]) 86 | { return exists $self->[ITEMS]->[$extension]->{$itemString}; } 87 | else 88 | { return 0; }; 89 | }; 90 | 91 | 92 | # 93 | # Function: DeleteItem 94 | # 95 | # Deletes the passed item. Returns whether it existed. 96 | # 97 | sub DeleteItem #(ExtensionID extension, string itemString) => bool 98 | { 99 | my ($self, $extension, $itemString) = @_; 100 | 101 | if (!defined $self->[ITEMS]->[$extension]) 102 | { return 0; } 103 | elsif (exists $self->[ITEMS]->[$extension]->{$itemString}) 104 | { 105 | delete $self->[ITEMS]->[$extension]->{$itemString}; 106 | return 1; 107 | } 108 | else 109 | { return 0; }; 110 | }; 111 | 112 | 113 | # 114 | # Function: ListItems 115 | # 116 | # Returns an array of all the item strings defined for a particular extension, or an empty list if none. 117 | # 118 | sub ListItems #(ExtensionID extension) => string array 119 | { 120 | my ($self, $extension) = @_; 121 | 122 | if (defined $self->[ITEMS]->[$extension]) 123 | { return keys %{$self->[ITEMS]->[$extension]}; } 124 | else 125 | { return ( ); }; 126 | }; 127 | 128 | 129 | 1; 130 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Package: NaturalDocs::SourceDB::ItemDefinition 4 | # 5 | ############################################################################### 6 | # 7 | # A base class for all item definitions for extensions that track more than existence. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | 18 | package NaturalDocs::SourceDB::ItemDefinition; 19 | 20 | 21 | # 22 | # Function: Compare 23 | # 24 | # Returns whether the definitions are equal. This version returns true by default, you must override it in your subclasses 25 | # to make the results relevant. This is important for AnalyzeTrackedFileChanges()>. 26 | # 27 | # This will only be called between objects of the same . If you use multiple derived classes for the same 28 | # , you will have to take that into account yourself. 29 | # 30 | # Parameters: 31 | # 32 | # other - Another -derived object to compare this one to. It will always be from 33 | # the same . 34 | # 35 | # Returns: 36 | # 37 | # Whether they are equal. 38 | # 39 | sub Compare #(other) 40 | { 41 | return 1; 42 | }; 43 | 44 | 45 | 1; 46 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Package: NaturalDocs::SourceDB::WatchedFileDefinitions 4 | # 5 | ############################################################################### 6 | # 7 | # A class to track the definitions appearing in a watched file. This is only used for extensions that track definition info with 8 | # -derived objects. Do not use it for extensions that only track existence. 9 | # 10 | ############################################################################### 11 | 12 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 13 | # Natural Docs is licensed under the GPL 14 | 15 | use strict; 16 | use integer; 17 | 18 | 19 | package NaturalDocs::SourceDB::WatchedFileDefinitions; 20 | 21 | 22 | # 23 | # Variables: Members 24 | # 25 | # This object would only have one member, which is an array, so the object itself serves as that member. 26 | # 27 | # are used as indexes into this object. Each entry is a hashref that maps item strings to 28 | # -derived objects. This is only done for extensions that use those objects to track 29 | # definitions, it's not needed for extensions that only track existence. If there are no definitions, the entry will be undef. 30 | # 31 | 32 | 33 | # 34 | # Function: New 35 | # 36 | # Creates and returns a new object. 37 | # 38 | sub New 39 | { 40 | my $class = shift; 41 | 42 | my $object = [ ]; 43 | bless $object, $class; 44 | 45 | return $object; 46 | }; 47 | 48 | 49 | 50 | ############################################################################### 51 | # Group: Definition Functions 52 | # 53 | 54 | 55 | # 56 | # Function: AddDefinition 57 | # 58 | # Adds a definition for the passed item string. If it's already defined, the new definition will be ignored. 59 | # 60 | # Parameters: 61 | # 62 | # extension - The . 63 | # itemString - The item string. 64 | # definition - The definition, which must be an object derived from . 65 | # 66 | # Returns: 67 | # 68 | # Whether the definition was added, which is to say, whether this was the first definition for the passed . 69 | # 70 | sub AddDefinition #(ExtensionID extension, string itemString, NaturalDocs::SourceDB::ItemDefinition definition) => bool 71 | { 72 | my ($self, $extension, $itemString, $definition) = @_; 73 | 74 | if (!defined $self->[$extension]) 75 | { $self->[$extension] = { }; }; 76 | 77 | if (!exists $self->[$extension]->{$itemString}) 78 | { 79 | $self->[$extension]->{$itemString} = $definition; 80 | return 1; 81 | } 82 | else 83 | { return 0; }; 84 | }; 85 | 86 | 87 | # 88 | # Function: GetDefinition 89 | # 90 | # Returns the -derived object for the passed item string or undef if there is none. 91 | # 92 | sub GetDefinition #(ExtensionID extension, string itemString) => NaturalDocs::SourceDB::ItemDefinition 93 | { 94 | my ($self, $extension, $itemString) = @_; 95 | 96 | if (defined $self->[$extension]) 97 | { return $self->[$extension]->{$itemString}; } 98 | else 99 | { return undef; }; 100 | }; 101 | 102 | 103 | # 104 | # Function: DeleteDefinition 105 | # 106 | # Removes the definition for the passed item string. Returns whether it was successful, meaning whether a definition existed 107 | # for that item. 108 | # 109 | sub DeleteDefinition #(ExtensionID extension, string itemString) => bool 110 | { 111 | my ($self, $extension, $itemString) = @_; 112 | 113 | if (defined $self->[$extension]) 114 | { 115 | if (exists $self->[$extension]->{$itemString}) 116 | { 117 | delete $self->[$extension]->{$itemString}; 118 | 119 | if (!scalar keys %{$self->[$extension]}) 120 | { $self->[$extension] = undef; }; 121 | 122 | return 1; 123 | }; 124 | }; 125 | 126 | return 0; 127 | }; 128 | 129 | 130 | # 131 | # Function: HasDefinitions 132 | # 133 | # Returns whether there are any definitions for this item. 134 | # 135 | sub HasDefinitions #(ExtensionID extension) => bool 136 | { 137 | my ($self, $extension) = @_; 138 | 139 | return (defined $self->[$extension]); 140 | }; 141 | 142 | 143 | # 144 | # Function: HasDefinition 145 | # 146 | # Returns whether there is a definition for the passed item string. 147 | # 148 | sub HasDefinition #(ExtensionID extension, string itemString) => bool 149 | { 150 | my ($self, $extension, $itemString) = @_; 151 | 152 | if (defined $self->[$extension]) 153 | { return (exists $self->[$extension]->{$itemString}); } 154 | else 155 | { return 0; }; 156 | }; 157 | 158 | 159 | 1; 160 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/StatusMessage.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Package: NaturalDocs::StatusMessage 4 | # 5 | ############################################################################### 6 | # 7 | # A package to handle status message updates. Automatically handles IsQuiet()>. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | package NaturalDocs::StatusMessage; 18 | 19 | 20 | # 21 | # var: message 22 | # The message to display. 23 | # 24 | my $message; 25 | 26 | # 27 | # var: total 28 | # The number of items to work through. 29 | # 30 | my $total; 31 | 32 | # 33 | # var: completed 34 | # The number of items completed. 35 | # 36 | my $completed; 37 | 38 | # 39 | # var: lastMessageTime 40 | # The time the last message was posted. 41 | # 42 | my $lastMessageTime; 43 | 44 | 45 | # 46 | # constant: TIME_BETWEEN_UPDATES 47 | # The number of seconds that should occur between updates. 48 | # 49 | use constant TIME_BETWEEN_UPDATES => 10; 50 | 51 | 52 | 53 | # 54 | # Function: Start 55 | # 56 | # Starts the status message. 57 | # 58 | # Parameters: 59 | # 60 | # message - The message to post. 61 | # total - The number of items that are going to be worked through. 62 | # 63 | sub Start #(message, total) 64 | { 65 | my $self = shift; 66 | 67 | if (!NaturalDocs::Settings->IsQuiet()) 68 | { 69 | ($message, $total) = @_; 70 | $completed = 0; 71 | 72 | print $message . "\n"; 73 | 74 | $lastMessageTime = time(); 75 | }; 76 | }; 77 | 78 | 79 | # 80 | # Function: CompletedItem 81 | # 82 | # Should be called every time an item is completed. 83 | # 84 | sub CompletedItem 85 | { 86 | my $self = shift; 87 | 88 | if (!NaturalDocs::Settings->IsQuiet()) 89 | { 90 | # We scale completed by 100 since we need to anyway to get the percentage. 91 | 92 | $completed += 100; 93 | 94 | if (time() >= $lastMessageTime + TIME_BETWEEN_UPDATES && $completed != $total * 100) 95 | { 96 | print $message . ' (' . ($completed / $total) . '%)' . "\n"; 97 | $lastMessageTime = time(); 98 | }; 99 | }; 100 | }; 101 | 102 | 1; 103 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/SymbolTable/File.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Package: NaturalDocs::SymbolTable::File 4 | # 5 | ############################################################################### 6 | # 7 | # A class representing a file, keeping track of what symbols and references are defined in it. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | package NaturalDocs::SymbolTable::File; 18 | 19 | 20 | ############################################################################### 21 | # Group: Implementation 22 | 23 | # 24 | # Constants: Members 25 | # 26 | # The class is implemented as a blessed arrayref. The following constants are its members. 27 | # 28 | # SYMBOLS - An existence hashref of the it defines. 29 | # REFERENCES - An existence hashref of the in the file. 30 | # 31 | 32 | # DEPENDENCY: New() depends on the order of these constants. If they change, New() has to be updated. 33 | use constant SYMBOLS => 0; 34 | use constant REFERENCES => 1; 35 | 36 | 37 | ############################################################################### 38 | # Group: Modification Functions 39 | 40 | 41 | # 42 | # Function: New 43 | # 44 | # Creates and returns a new object. 45 | # 46 | sub New 47 | { 48 | my $package = shift; 49 | 50 | # Let's make it safe, since normally you can pass values to New. Having them just be ignored would be an obscure error. 51 | if (scalar @_) 52 | { die "You can't pass values to NaturalDocs::SymbolTable::File->New()\n"; }; 53 | 54 | # DEPENDENCY: This code depends on the order of the member constants. 55 | my $object = [ { }, { } ]; 56 | bless $object, $package; 57 | 58 | return $object; 59 | }; 60 | 61 | 62 | # 63 | # Function: AddSymbol 64 | # 65 | # Adds a definition. 66 | # 67 | # Parameters: 68 | # 69 | # symbol - The being added. 70 | # 71 | sub AddSymbol #(symbol) 72 | { 73 | my ($self, $symbol) = @_; 74 | $self->[SYMBOLS]{$symbol} = 1; 75 | }; 76 | 77 | 78 | # 79 | # Function: DeleteSymbol 80 | # 81 | # Removes a definition. 82 | # 83 | # Parameters: 84 | # 85 | # symbol - The to delete. 86 | # 87 | sub DeleteSymbol #(symbol) 88 | { 89 | my ($self, $symbol) = @_; 90 | delete $self->[SYMBOLS]{$symbol}; 91 | }; 92 | 93 | 94 | # 95 | # Function: AddReference 96 | # 97 | # Adds a reference definition. 98 | # 99 | # Parameters: 100 | # 101 | # referenceString - The being added. 102 | # 103 | sub AddReference #(referenceString) 104 | { 105 | my ($self, $referenceString) = @_; 106 | $self->[REFERENCES]{$referenceString} = 1; 107 | }; 108 | 109 | 110 | # 111 | # Function: DeleteReference 112 | # 113 | # Removes a reference definition. 114 | # 115 | # Parameters: 116 | # 117 | # referenceString - The to delete. 118 | # 119 | sub DeleteReference #(referenceString) 120 | { 121 | my ($self, $referenceString) = @_; 122 | delete $self->[REFERENCES]{$referenceString}; 123 | }; 124 | 125 | 126 | 127 | ############################################################################### 128 | # Group: Information Functions 129 | 130 | 131 | # 132 | # Function: HasAnything 133 | # 134 | # Returns whether the file has any symbol or reference definitions at all. 135 | # 136 | sub HasAnything 137 | { 138 | return (scalar keys %{$_[0]->[SYMBOLS]} || scalar keys %{$_[0]->[REFERENCES]}); 139 | }; 140 | 141 | # 142 | # Function: Symbols 143 | # 144 | # Returns an array of all the defined in this file. If none, returns an empty array. 145 | # 146 | sub Symbols 147 | { 148 | return keys %{$_[0]->[SYMBOLS]}; 149 | }; 150 | 151 | 152 | # 153 | # Function: References 154 | # 155 | # Returns an array of all the defined in this file. If none, returns an empty array. 156 | # 157 | sub References 158 | { 159 | return keys %{$_[0]->[REFERENCES]}; 160 | }; 161 | 162 | 163 | # 164 | # Function: DefinesSymbol 165 | # 166 | # Returns whether the file defines the passed or not. 167 | # 168 | sub DefinesSymbol #(symbol) 169 | { 170 | my ($self, $symbol) = @_; 171 | return exists $self->[SYMBOLS]{$symbol}; 172 | }; 173 | 174 | 175 | # 176 | # Function: DefinesReference 177 | # 178 | # Returns whether the file defines the passed or not. 179 | # 180 | sub DefinesReference #(referenceString) 181 | { 182 | my ($self, $referenceString) = @_; 183 | return exists $self->[REFERENCES]{$referenceString}; 184 | }; 185 | 186 | 1; 187 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Class: NaturalDocs::SymbolTable::ReferenceTarget 4 | # 5 | ############################################################################### 6 | # 7 | # A class for storing information about a reference target. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | package NaturalDocs::SymbolTable::ReferenceTarget; 18 | 19 | 20 | ############################################################################### 21 | # Group: Implementation 22 | 23 | # 24 | # Constants: Members 25 | # 26 | # The class is implemented as a blessed arrayref. The following constants are its members. 27 | # 28 | # SYMBOL - The target . 29 | # FILE - The the target is defined in. 30 | # TYPE - The target . 31 | # PROTOTYPE - The target's prototype, or undef if none. 32 | # SUMMARY - The target's summary, or undef if none. 33 | # 34 | 35 | # DEPENDENCY: New() depends on the order of these constants. If they change, New() has to be updated. 36 | use constant SYMBOL => 0; 37 | use constant FILE => 1; 38 | use constant TYPE => 2; 39 | use constant PROTOTYPE => 3; 40 | use constant SUMMARY => 4; 41 | 42 | ############################################################################### 43 | # Group: Functions 44 | 45 | 46 | # 47 | # Function: New 48 | # 49 | # Creates and returns a new object. 50 | # 51 | # Parameters: 52 | # 53 | # symbol - The target . 54 | # file - The the target is defined in. 55 | # type - The of the target symbol. 56 | # prototype - The target's prototype. Set to undef if not defined or not applicable. 57 | # summary - The target's summary. Set to undef if not defined or not applicable. 58 | # 59 | sub New #(symbol, file, type, prototype, summary) 60 | { 61 | # DEPENDENCY: This code depends on the order of the member constants. 62 | 63 | my $package = shift; 64 | 65 | my $object = [ @_ ]; 66 | bless $object, $package; 67 | 68 | return $object; 69 | }; 70 | 71 | 72 | # Function: Symbol 73 | # Returns the target's . 74 | sub Symbol 75 | { return $_[0]->[SYMBOL]; }; 76 | 77 | # Function: File 78 | # Returns the the target is defined in. 79 | sub File 80 | { return $_[0]->[FILE]; }; 81 | 82 | # Function: Type 83 | # Returns the target's . 84 | sub Type 85 | { return $_[0]->[TYPE]; }; 86 | 87 | # Function: Prototype 88 | # Returns the target's prototype, or undef if not defined or not applicable. 89 | sub Prototype 90 | { return $_[0]->[PROTOTYPE]; }; 91 | 92 | # Function: Summary 93 | # Returns the target's summary, or undef if not defined or not applicable. 94 | sub Summary 95 | { return $_[0]->[SUMMARY]; }; 96 | 97 | 1; 98 | -------------------------------------------------------------------------------- /natural_docs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Package: NaturalDocs::SymbolTable::SymbolDefinition 4 | # 5 | ############################################################################### 6 | # 7 | # A class representing a symbol definition. This does not store the definition symbol, class, or file. 8 | # 9 | ############################################################################### 10 | 11 | # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure 12 | # Natural Docs is licensed under the GPL 13 | 14 | use strict; 15 | use integer; 16 | 17 | package NaturalDocs::SymbolTable::SymbolDefinition; 18 | 19 | 20 | ############################################################################### 21 | # Group: Implementation 22 | 23 | # 24 | # Constants: Members 25 | # 26 | # The class is implemented as a blessed arrayref. The following constants are its members. 27 | # 28 | # TYPE - The symbol . 29 | # PROTOTYPE - The symbol's prototype, if applicable. Will be undef otherwise. 30 | # SUMMARY - The symbol's summary, if applicable. Will be undef otherwise. 31 | # 32 | use constant TYPE => 0; 33 | use constant PROTOTYPE => 1; 34 | use constant SUMMARY => 2; 35 | # New depends on the order of the constants. 36 | 37 | 38 | ############################################################################### 39 | # Group: Functions 40 | 41 | # 42 | # Function: New 43 | # 44 | # Creates and returns a new object. 45 | # 46 | # Parameters: 47 | # 48 | # type - The symbol . 49 | # prototype - The symbol prototype, if applicable. Undef otherwise. 50 | # summary - The symbol's summary, if applicable. Undef otherwise. 51 | # 52 | sub New #(type, prototype, summary) 53 | { 54 | # This depends on the parameter list being the same as the constant order. 55 | 56 | my $package = shift; 57 | 58 | my $object = [ @_ ]; 59 | bless $object, $package; 60 | 61 | return $object; 62 | }; 63 | 64 | 65 | # Function: Type 66 | # Returns the definition's . 67 | sub Type 68 | { return $_[0]->[TYPE]; }; 69 | 70 | # Function: SetType 71 | # Changes the . 72 | sub SetType #(type) 73 | { $_[0]->[TYPE] = $_[1]; }; 74 | 75 | # Function: Prototype 76 | # Returns the definition's prototype, or undef if it doesn't have one. 77 | sub Prototype 78 | { return $_[0]->[PROTOTYPE]; }; 79 | 80 | # Function: SetPrototype 81 | # Changes the prototype. 82 | sub SetPrototype #(prototype) 83 | { $_[0]->[PROTOTYPE] = $_[1]; }; 84 | 85 | # Function: Summary 86 | # Returns the definition's summary, or undef if it doesn't have one. 87 | sub Summary 88 | { return $_[0]->[SUMMARY]; }; 89 | 90 | # Function: SetSummary 91 | # Changes the summary. 92 | sub SetSummary #(summary) 93 | { $_[0]->[SUMMARY] = $_[1]; }; 94 | 95 | 96 | 1; 97 | -------------------------------------------------------------------------------- /natural_docs/NaturalDocs.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set NaturalDocsParams= 4 | 5 | rem Shift and loop so we can get more than nine parameters. 6 | rem This is especially important if we have spaces in file names. 7 | 8 | :MORE 9 | if "%1"=="" goto NOMORE 10 | set NaturalDocsParams=%NaturalDocsParams% %1 11 | shift 12 | goto MORE 13 | :NOMORE 14 | 15 | perl NaturalDocs %NaturalDocsParams% 16 | 17 | set NaturalDocsParams= -------------------------------------------------------------------------------- /natural_docs/images/arrow_1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/arrow_1.gif -------------------------------------------------------------------------------- /natural_docs/images/bg_column_green.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/bg_column_green.gif -------------------------------------------------------------------------------- /natural_docs/images/bg_column_green_grey.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/bg_column_green_grey.gif -------------------------------------------------------------------------------- /natural_docs/images/bg_feature.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/bg_feature.jpg -------------------------------------------------------------------------------- /natural_docs/images/bg_h3_roundcorners.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/bg_h3_roundcorners.gif -------------------------------------------------------------------------------- /natural_docs/images/bg_main.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/bg_main.gif -------------------------------------------------------------------------------- /natural_docs/images/bg_masthead.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/bg_masthead.jpg -------------------------------------------------------------------------------- /natural_docs/images/bg_navbar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/bg_navbar.gif -------------------------------------------------------------------------------- /natural_docs/images/bg_roundcorners2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/bg_roundcorners2.gif -------------------------------------------------------------------------------- /natural_docs/images/bg_tableheader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/bg_tableheader.gif -------------------------------------------------------------------------------- /natural_docs/images/bg_thick_grey_bar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/bg_thick_grey_bar.gif -------------------------------------------------------------------------------- /natural_docs/images/bullet_GreenOnGrey.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/bullet_GreenOnGrey.gif -------------------------------------------------------------------------------- /natural_docs/images/ovmm_atomic_gen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/ovmm_atomic_gen.gif -------------------------------------------------------------------------------- /natural_docs/images/ovmm_scenario_gen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/natural_docs/images/ovmm_scenario_gen.gif -------------------------------------------------------------------------------- /natural_docs/logo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Menu - 7 | 8 | 9 | 10 | 12 | 13 | 14 | 15 | 16 |
      17 |
      18 | 20 |
      21 | 22 | 23 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /notes.md: -------------------------------------------------------------------------------- 1 | # Things to do 2 | 3 | ## Handle Class 4 | Purpose of the handle class is to select the adapter and the address map. 2 use cases 5 | 6 | 1. Always select the adapter inside the agent using get_name(). Upto user to keep the name unique. 7 | 8 | ``` 9 | virtual function int is_correct_adapter(); 10 | return -1; // If this is ignored 11 | return 0 ; // If not selected 12 | return 1`; // If selected 13 | endfunction 14 | ``` 15 | 16 | 2. Iterate over all the adapters in the node. Say search for background adapter which happens 17 | to be the last one in the list. if not found then go back and select the sidedoor else just 18 | select the front door. 19 | 20 | 3. Handle should have intialize method for getting the name of the adapter. 21 | ``` 22 | handle.initialize(.name(adapter.get_name())); 23 | ``` 24 | 25 | ## Adapter 26 | ## convert data in adapter to uvm_hdl_data_t HDL_MAX_WIDTH 27 | 28 | ## Locking 29 | -------------------------------------------------------------------------------- /scripts/Proj/Data/ClassHierarchy.nd: -------------------------------------------------------------------------------- 1 | $ srm_w0crs_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_w0t_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_node@/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_node.svhsrm_base_fieldF/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_field.svhsrm_search_adapterI/home/sanjeev/foo/simple_reg_model/distrib/src/bus/srm_search_adapter.svh 2 | uvm_object SystemVerilogsrm_woc_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_base_field_policyM/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_field_policy.svh srm_ws_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilog srm_tableA/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_table.svhsrm_node SystemVerilogsrm_w1src_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_wsrc_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilog srm_rw_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_wrc_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilog srm_wc_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilog srm_base_regD/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_reg.svhsrm_node SystemVerilogsrm_base_handleG/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_handle.svh 3 | uvm_object SystemVerilogsrm_base_coverageI/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_coverage.svh srm_ro_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_w0src_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_w0c_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_w1crs_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_wos_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_table_entryG/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_table_entry.svh srm_reg#(T) SystemVerilog srm_wo_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilog srm_rc_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilog srm_rs_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_bus_adapterF/home/sanjeev/foo/simple_reg_model/distrib/src/bus/srm_bus_adapter.svh 4 | uvm_object SystemVerilog srm_fieldA/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field.svhsrm_base_field SystemVerilogsrm_w1s_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_bus_predictorH/home/sanjeev/foo/simple_reg_model/distrib/src/bus/srm_bus_predictor.svhsrm_wcrs_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_wrs_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_reg?/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_reg.svh srm_base_reg SystemVerilogBuilt In Field Access PoliciesJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_w1c_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_w1t_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilogsrm_w0s_policyJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_field_policy SystemVerilog srm_utilsC/home/sanjeev/foo/simple_reg_model/distrib/src/common/srm_utils.svh -------------------------------------------------------------------------------- /scripts/Proj/Data/ConfigFileInfo.nd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/scripts/Proj/Data/ConfigFileInfo.nd -------------------------------------------------------------------------------- /scripts/Proj/Data/FileInfo.nd: -------------------------------------------------------------------------------- 1 | Development Release 01-12-2008 (1.35 base) 2 | SystemVerilog 3 | /home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_coverage.svh 1518360145 1 srm_base_coverage 4 | /home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field.svh 1518360145 1 srm_field 5 | /home/sanjeev/foo/simple_reg_model/distrib/src/srm.sv 1518360145 0 /home/sanjeev/foo/simple_reg_model/distrib/src/srm.sv 6 | /home/sanjeev/foo/simple_reg_model/distrib/src/bus/srm_search_adapter.svh 1518360145 1 srm_search_adapter 7 | /home/sanjeev/foo/simple_reg_model/distrib/src/bus/srm_bus_adapter.svh 1518360145 1 srm_bus_adapter 8 | /home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_handle.svh 1518360145 1 srm_base_handle 9 | /home/sanjeev/foo/simple_reg_model/distrib/src/srm_pkg.sv 1518360145 0 /home/sanjeev/foo/simple_reg_model/distrib/src/srm_pkg.sv 10 | /home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_field_policy.svh 1518360145 1 srm_base_field_policy 11 | /home/sanjeev/foo/simple_reg_model/distrib/src/common/srm_utils.svh 1518360145 1 srm_utils 12 | /home/sanjeev/foo/simple_reg_model/distrib/src/bus/srm_generic_xact.svh 1518360145 0 /home/sanjeev/foo/simple_reg_model/distrib/src/bus/srm_generic_xact.svh 13 | /home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_reg.svh 1518360145 1 srm_base_reg 14 | /home/sanjeev/foo/simple_reg_model/distrib/src/bus/srm_bus_predictor.svh 1518360145 1 srm_bus_predictor 15 | /home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_field.svh 1518360145 1 srm_base_field 16 | /home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_reg.svh 1518360145 1 srm_reg 17 | /home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_table_entry.svh 1518360145 1 srm_table_entry 18 | /home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_node.svh 1518360145 1 srm_node 19 | /home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_table.svh 1518360145 1 srm_table 20 | /home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svh 1518360145 1 Built In Field Access Policies 21 | -------------------------------------------------------------------------------- /scripts/Proj/Data/ImageFileInfo.nd: -------------------------------------------------------------------------------- 1 | $  -------------------------------------------------------------------------------- /scripts/Proj/Data/ImageReferenceTable.nd: -------------------------------------------------------------------------------- 1 | $  -------------------------------------------------------------------------------- /scripts/Proj/Data/IndexInfo.nd: -------------------------------------------------------------------------------- 1 | $ MethodVariableClassGeneral -------------------------------------------------------------------------------- /scripts/Proj/Data/PreviousMenuState.nd: -------------------------------------------------------------------------------- 1 | $ Built In Field Access PoliciesJ/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field_policies.svhsrm_base_coverageI/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_coverage.svhsrm_base_fieldF/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_field.svhsrm_base_field_policyM/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_field_policy.svhsrm_base_handleG/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_handle.svh srm_base_regD/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_base_reg.svhsrm_bus_adapterF/home/sanjeev/foo/simple_reg_model/distrib/src/bus/srm_bus_adapter.svhsrm_bus_predictorH/home/sanjeev/foo/simple_reg_model/distrib/src/bus/srm_bus_predictor.svh srm_fieldA/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_field.svhsrm_node@/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_node.svhsrm_reg?/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_reg.svhsrm_search_adapterI/home/sanjeev/foo/simple_reg_model/distrib/src/bus/srm_search_adapter.svh srm_tableA/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_table.svhsrm_table_entryG/home/sanjeev/foo/simple_reg_model/distrib/src/base/srm_table_entry.svh srm_utilsC/home/sanjeev/foo/simple_reg_model/distrib/src/common/srm_utils.svhIndexClassesclass 2 | EverythinggeneralMethodsmethod Variablesvariable -------------------------------------------------------------------------------- /scripts/Proj/Data/PreviousSettings.nd: -------------------------------------------------------------------------------- 1 | $ ./home/sanjeev/foo/simple_reg_model/distrib/src14/home/sanjeev/foo/simple_reg_model/distrib/docs/html 2 | FramedHTML -------------------------------------------------------------------------------- /scripts/Proj/Data/SymbolTable.nd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Juniper/simple_reg_model/247c70cb1a5f2937989610563785926c45af06a1/scripts/Proj/Data/SymbolTable.nd -------------------------------------------------------------------------------- /scripts/Proj/Menu.txt: -------------------------------------------------------------------------------- 1 | Format: Development Release 01-12-2008 (1.35 base) 2 | 3 | 4 | # You can add a title and sub-title to your menu like this: 5 | # Title: [project name] 6 | # SubTitle: [subtitle] 7 | 8 | # You can add a footer to your documentation like this: 9 | # Footer: [text] 10 | # If you want to add a copyright notice, this would be the place to do it. 11 | 12 | # You can add a timestamp to your documentation like one of these: 13 | # Timestamp: Generated on month day, year 14 | # Timestamp: Updated mm/dd/yyyy 15 | # Timestamp: Last updated mon day 16 | # 17 | # m - One or two digit month. January is "1" 18 | # mm - Always two digit month. January is "01" 19 | # mon - Short month word. January is "Jan" 20 | # month - Long month word. January is "January" 21 | # d - One or two digit day. 1 is "1" 22 | # dd - Always two digit day. 1 is "01" 23 | # day - Day with letter extension. 1 is "1st" 24 | # yy - Two digit year. 2006 is "06" 25 | # yyyy - Four digit year. 2006 is "2006" 26 | # year - Four digit year. 2006 is "2006" 27 | 28 | 29 | # -------------------------------------------------------------------------- 30 | # 31 | # Cut and paste the lines below to change the order in which your files 32 | # appear on the menu. Don't worry about adding or removing files, Natural 33 | # Docs will take care of that. 34 | # 35 | # You can further organize the menu by grouping the entries. Add a 36 | # "Group: [name] {" line to start a group, and add a "}" to end it. 37 | # 38 | # You can add text and web links to the menu by adding "Text: [text]" and 39 | # "Link: [name] ([URL])" lines, respectively. 40 | # 41 | # The formatting and comments are auto-generated, so don't worry about 42 | # neatness when editing the file. Natural Docs will clean it up the next 43 | # time it is run. When working with groups, just deal with the braces and 44 | # forget about the indentation and comments. 45 | # 46 | # -------------------------------------------------------------------------- 47 | 48 | 49 | File: Built In Field Access Policies (base/srm_field_policies.svh) 50 | File: srm_base_coverage (base/srm_base_coverage.svh) 51 | File: srm_base_field (base/srm_base_field.svh) 52 | File: srm_base_field_policy (base/srm_base_field_policy.svh) 53 | File: srm_base_handle (base/srm_base_handle.svh) 54 | File: srm_base_reg (base/srm_base_reg.svh) 55 | File: srm_bus_adapter (bus/srm_bus_adapter.svh) 56 | File: srm_bus_predictor (bus/srm_bus_predictor.svh) 57 | File: srm_field (base/srm_field.svh) 58 | File: srm_node (base/srm_node.svh) 59 | File: srm_reg (base/srm_reg.svh) 60 | File: srm_search_adapter (bus/srm_search_adapter.svh) 61 | File: srm_table (base/srm_table.svh) 62 | File: srm_table_entry (base/srm_table_entry.svh) 63 | File: srm_utils (common/srm_utils.svh) 64 | 65 | Group: Index { 66 | 67 | Class Index: Classes 68 | Index: Everything 69 | Method Index: Methods 70 | Variable Index: Variables 71 | } # Group: Index 72 | 73 | -------------------------------------------------------------------------------- /scripts/Proj/Topics.txt: -------------------------------------------------------------------------------- 1 | Format: Development Release 01-12-2008 (1.35 base) 2 | 3 | # This is the Natural Docs topics file for this project. If you change anything 4 | # here, it will apply to THIS PROJECT ONLY. If you'd like to change something 5 | # for all your projects, edit the Topics.txt in Natural Docs' Config directory 6 | # instead. 7 | 8 | 9 | # If you'd like to prevent keywords from being recognized by Natural Docs, you 10 | # can do it like this: 11 | # Ignore Keywords: [keyword], [keyword], ... 12 | # 13 | # Or you can use the list syntax like how they are defined: 14 | # Ignore Keywords: 15 | # [keyword] 16 | # [keyword], [plural keyword] 17 | # ... 18 | 19 | 20 | #------------------------------------------------------------------------------- 21 | # SYNTAX: 22 | # 23 | # Topic Type: [name] 24 | # Alter Topic Type: [name] 25 | # Creates a new topic type or alters one from the main file. Each type gets 26 | # its own index and behavior settings. Its name can have letters, numbers, 27 | # spaces, and these charaters: - / . ' 28 | # 29 | # Plural: [name] 30 | # Sets the plural name of the topic type, if different. 31 | # 32 | # Keywords: 33 | # [keyword] 34 | # [keyword], [plural keyword] 35 | # ... 36 | # Defines or adds to the list of keywords for the topic type. They may only 37 | # contain letters, numbers, and spaces and are not case sensitive. Plural 38 | # keywords are used for list topics. You can redefine keywords found in the 39 | # main topics file. 40 | # 41 | # Index: [yes|no] 42 | # Whether the topics get their own index. Defaults to yes. Everything is 43 | # included in the general index regardless of this setting. 44 | # 45 | # Scope: [normal|start|end|always global] 46 | # How the topics affects scope. Defaults to normal. 47 | # normal - Topics stay within the current scope. 48 | # start - Topics start a new scope for all the topics beneath it, 49 | # like class topics. 50 | # end - Topics reset the scope back to global for all the topics 51 | # beneath it. 52 | # always global - Topics are defined as global, but do not change the scope 53 | # for any other topics. 54 | # 55 | # Class Hierarchy: [yes|no] 56 | # Whether the topics are part of the class hierarchy. Defaults to no. 57 | # 58 | # Page Title If First: [yes|no] 59 | # Whether the topic's title becomes the page title if it's the first one in 60 | # a file. Defaults to no. 61 | # 62 | # Break Lists: [yes|no] 63 | # Whether list topics should be broken into individual topics in the output. 64 | # Defaults to no. 65 | # 66 | # Can Group With: [type], [type], ... 67 | # Defines a list of topic types that this one can possibly be grouped with. 68 | # Defaults to none. 69 | #------------------------------------------------------------------------------- 70 | 71 | # The following topics are defined in the main file, if you'd like to alter 72 | # their behavior or add keywords: 73 | # 74 | # Generic, Class, Interface, Section, File, Group, Function, Variable, 75 | # Property, Type, Constant, Enumeration, Event, Delegate, Example, 76 | # Parameter, Typedef, Port, Usage, Subgroup, Method, Module, Program, 77 | # Global, Package, Macro, Database, Database Table, Database View, 78 | # Database Index, Database Cursor, Database Trigger, Cookie, Build 79 | # Target 80 | 81 | # If you add something that you think would be useful to other developers 82 | # and should be included in Natural Docs by default, please e-mail it to 83 | # topics [at] naturaldocs [dot] org. 84 | -------------------------------------------------------------------------------- /scripts/copyright.txt: -------------------------------------------------------------------------------- 1 | // 2 | // -------------------------------------------------------------- 3 | // Copyright (c) 2017-2023, Juniper Networks, Inc. 4 | // All rights reserved. 5 | // 6 | // This code is licensed to you under the MIT license. 7 | // You many not use this code except in compliance with this license. 8 | // This code is not an official Juniper product. You may obtain a copy 9 | // of the license at 10 | // 11 | // https://opensource.org/licenses/MIT 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 16 | // implied. See the License for the specific language governing 17 | // permissions and limitations under the License. 18 | // ------------------------------------------------------------- 19 | // 20 | -------------------------------------------------------------------------------- /scripts/gen_nd: -------------------------------------------------------------------------------- 1 | #!/bin/csh 2 | 3 | 4 | set nd_dir = ../natural_docs 5 | set outdir = ../distrib/docs/html 6 | 7 | rm -rf $outdir 8 | mkdir -p $outdir/images 9 | 10 | cp -r $nd_dir/images/b* $outdir/images 11 | cp $nd_dir/logo.html $outdir 12 | perl $nd_dir/NaturalDocs \ 13 | -do \ 14 | -ro \ 15 | -i ../distrib/src \ 16 | -p ./Proj \ 17 | -o FramedHTML $outdir 18 | -------------------------------------------------------------------------------- /scripts/insert_copyright: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'optparse' 3 | require 'ostruct' 4 | require 'pp' 5 | 6 | options = OpenStruct.new 7 | options.copyright = ENV["SRM_ROOT"] + "/bin/copyright.txt" 8 | options.del_copyright = false 9 | 10 | OptionParser.new do |opts| 11 | opts.banner = "Usage: insert_copyright [-d] [-c copyright_file] source_file" 12 | 13 | opts.on("-c", "--copyright FILE", "Copyright file to insert") do |cfile| 14 | options.copyright = cfile 15 | end 16 | 17 | opts.on("-d", "--del", "Delete existing copyright") do |del| 18 | options.del_copyright = true 19 | end 20 | end.parse!(ARGV) 21 | 22 | abort "Must specify a source file" unless ARGV 23 | source_file = ARGV[0] 24 | abort "Input file \"#{source_file}\" is missing." unless File.exists?(source_file) 25 | 26 | copyright = IO.readlines(options.copyright) 27 | source = IO.readlines(source_file) 28 | 29 | num_skips = 0 30 | if(options.del_copyright) 31 | source.each do |line| 32 | if(line =~ /^\/\//) 33 | num_skips += 1 34 | else 35 | break 36 | end 37 | end 38 | end 39 | source.shift(num_skips) 40 | 41 | destination = copyright + source 42 | 43 | File.open(source_file, "w") do |fh| 44 | destination.each do |line| 45 | fh.write line 46 | end 47 | end 48 | 49 | -------------------------------------------------------------------------------- /scripts/shell.rb: -------------------------------------------------------------------------------- 1 | module Shell; 2 | require 'open3' 3 | require 'rainbow' 4 | 5 | def self.sh(cmd) 6 | system("rm -rf stdout.txt") 7 | system("rm -rf stderr.txt") 8 | command = cmd.split[0] 9 | begin 10 | puts Rainbow("\nRunning #{cmd}\n").bright 11 | stdout, stderr, status = Open3.capture3(cmd) 12 | rescue 13 | abort(Rainbow("\nCommand \"#{command}\" threw an exception. Check if the path is correct").bright.red) 14 | end 15 | 16 | if status.success? 17 | puts Rainbow("\nSuccessfully ran cmd\n").green 18 | stdout.split(/\n/).each do |line| 19 | yield line if block_given? 20 | end 21 | true 22 | else 23 | $stderr.puts(Rainbow("\nProblem running #{cmd}\n").bright); 24 | 25 | $stderr.puts(Rainbow("\nStoring output of command in stdout.txt stderr.txt\n").bright); 26 | File.open('stdout.txt', "w") do |fh| 27 | fh.write(stdout) 28 | end 29 | File.open('stderr.txt', "w") do |fh| 30 | fh.write(stderr) 31 | end 32 | abort Rainbow("Command \"#{command}\" FAILED:Terminating the program").bright.red 33 | end 34 | end 35 | 36 | def self.parse_verilog_log(logfile) 37 | lines = [] 38 | File.open(logfile).each do |line| 39 | lines << line if line =~ /^SRUN_TEST/ 40 | end 41 | lines 42 | end 43 | 44 | def self.parse_unit_test_result(logfile) 45 | lines = [] 46 | File.open(logfile).each do |line| 47 | if line =~ /^UnitTestRun/ 48 | a = line.split(":") 49 | prefix, full_path, line, testname, result = a 50 | filename = File.basename(full_path) 51 | if result =~ /PASS/ 52 | result = Rainbow("#{result}").bright.green 53 | else 54 | result = Rainbow("#{result}").bright.red 55 | end 56 | lines << "#{filename}:#{line}:#{testname}:#{result}" 57 | end 58 | end 59 | lines 60 | end 61 | end 62 | 63 | -------------------------------------------------------------------------------- /scripts/srun: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'optparse' 4 | require 'ostruct' 5 | require 'fileutils' 6 | require_relative "shell" 7 | 8 | options = OpenStruct.new 9 | options.sim_files = [] 10 | options.testname = "" 11 | options.output_dir = "run" 12 | options.logfile = "test.log" 13 | options.unit_test = "all" 14 | 15 | OptionParser.new do |opts| 16 | opts.banner = "Usage: srun -f -t " 17 | 18 | opts.on("-f", "--file SIMFILE", 19 | "Require the path to the simulation control file") do |sim_file| 20 | options.sim_files << sim_file 21 | end 22 | 23 | opts.on("-t", "--testname TEST", 24 | "Require the name of the uvm top level test to run") do |test| 25 | options.testname = test 26 | end 27 | 28 | opts.on("-u", "--unit_test TEST", 29 | "Optional name of the unit test to run") do |test| 30 | options.unit_test = test 31 | end 32 | 33 | opts.on("-o", "--out output_dir", 34 | "output directory to create the build and run dir.") do |dir| 35 | options.output_dir = dir 36 | end 37 | 38 | opts.on("-l", "--log logfile", "test.log output file.") do |log| 39 | options.logfile = log 40 | end 41 | 42 | end.parse(ARGV) 43 | 44 | abort "ERROR: Must specify cfile for sim" if options.sim_files.empty? 45 | options.sim_files.each do |f| 46 | abort "ERROR: File #{f} does not exist" unless File.exist?(f) 47 | end 48 | 49 | logfile = options.logfile 50 | 51 | cflags_opts = "" 52 | testname = options.testname || abort("ERROR: UVM test name must be specified") 53 | uvm_home = ENV["UVM_HOME"] || abort("UVM_HOME must be set in the env") 54 | srm_home = ENV["SRM_ROOT"] || abort("SRM_ROOT must be set in the env") 55 | 56 | #compile_opts = " +define+srm " 57 | #-compile_opts += %Q(+incdir+#{uvm_home}/src +incdir+#{srm_home}/dpi +incdir+#{srm_home}/src #{uvm_home}/src/uvm.sv #{uvm_home}/src/dpi/uvm_dpi.cc ) 58 | compile_opts = " +define+srm -uvm +ncaccess+r+w " 59 | compile_opts += %Q(+incdir+#{srm_home}/dpi +incdir+#{srm_home}/distrib/src +incdir+#{srm_home}/tests/cluelogic ) 60 | loader_opts = "" 61 | 62 | runtime_opts = "-l #{options.logfile} " 63 | runtime_opts += "+UVM_TESTNAME=#{testname} " if testname != "" 64 | runtime_opts += "+UNIT_TEST_NAME=#{options.unit_test} " 65 | 66 | output_dir = options.output_dir 67 | FileUtils.mkdir_p output_dir unless Dir.exists?(output_dir) 68 | 69 | cfile = "" 70 | options.sim_files.each do |f| 71 | f = FileUtils.pwd() + "/#{f} " unless f.match(/^\//) 72 | cfile += "-f " + "#{f}" 73 | end 74 | 75 | FileUtils.cd(output_dir) do 76 | system("rm -rf #{logfile}") 77 | Shell.sh(%Q(ncverilog #{compile_opts} #{loader_opts} #{runtime_opts} #{cfile})) 78 | sleep 3 unless File.exist?("#{logfile}") #Wait for the file to be written to disk. 79 | puts Shell::parse_verilog_log(logfile); puts; puts 80 | puts Shell.parse_unit_test_result(logfile); puts; puts 81 | system("grep SRUN_TEST_PASS #{logfile}") || 82 | abort(Rainbow("ERROR: Test Failed. String SRUN_TEST_PASS not found in #{logfile}").bright.red) 83 | end 84 | 85 | -------------------------------------------------------------------------------- /unit_fwk/Makefile.erb: -------------------------------------------------------------------------------- 1 | # 2 | # AutoGenerated Makefile 3 | # Generated by <%=$PROGRAM_NAME%> at <%=Time.new%> 4 | # 5 | # 6 | 7 | VCS = vcs -sverilog -timescale=1ns/1ns +acc +vpi \ 8 | $(UVM_HOME)/src/dpi/uvm_dpi.cc -CFLAGS -DVCS 9 | 10 | SIMV = ./simv -l test.log 11 | 12 | FILES = \ 13 | <%@src_files.each do |f|%> 14 | <%=f%> \ 15 | <%end%> 16 | 17 | INCLUDES = \ 18 | <%@src_incdirs.each do |d|%> 19 | +incdir+<%=d%> \ 20 | <%end%> 21 | 22 | # +acc, +vpi is required for examples using backdoor access. 23 | 24 | vcs: 25 | $(VCS) $(INCLUDES) $(FILES) main.sv && $(SIMV) 26 | 27 | -------------------------------------------------------------------------------- /unit_fwk/README.md: -------------------------------------------------------------------------------- 1 | # Test Unit Framework 2 | This is a small test unit framework designed for testing the simple reg model package. 3 | 4 | ## Overview 5 | The test writer creates test cases by creating a derived class from 'srm_unit_test'. The derived test 6 | class then overwrites the 'run' method and registers all the test cases. If required, *setup* and *teardown* methods can also be overwritten. These are invoked by the framework before and after each test case. 7 | 8 | To run the tests, a ruby script file 'gen_unit_tests' is used. This will create a 'main.sv' which instantiates all the tests and a 'Makefile' that will run the simulation. 9 | 10 | ## Assumptions 11 | The framework assumes that each test case is in a file called *test*.sv which has a class of the same name. 12 | -------------------------------------------------------------------------------- /unit_fwk/gen_unit_tests: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'erb' 3 | require_relative 'sim_cfiles' 4 | require 'optparse' 5 | 6 | def main() 7 | options = {} 8 | OptionParser.new do |opts| 9 | opts.banner = "Usage: gen_unit_tests -c " 10 | opts.on("-c", "--cfile ", "sim control file") do |c| 11 | options[:cfile] = c 12 | end 13 | end.parse! 14 | 15 | abort "Must specify the for the sim" unless options[:cfile] 16 | sim = UnitSim.new(options) 17 | sim.render 18 | end 19 | 20 | class UnitSim 21 | def initialize(options={}) 22 | puts "Eval #{options[:cfile]}" 23 | @cfile = SimCfiles.new(options[:cfile]) 24 | end 25 | 26 | 27 | def render 28 | templates = `ls #{File.dirname(__FILE__)}/*.erb`.split 29 | templates.each do |template| 30 | t = File.open(template).read 31 | renderer = ERB.new(t, 0, '>') 32 | out_file = File.basename(template, ".erb") 33 | puts "Creating output file \`#{out_file}`" 34 | File.open(out_file, "w") do |fh| 35 | fh.puts renderer.result(@cfile.get_binding()) 36 | end 37 | end 38 | end 39 | 40 | def hello 41 | end 42 | 43 | end 44 | 45 | main 46 | -------------------------------------------------------------------------------- /unit_fwk/main.sv.erb: -------------------------------------------------------------------------------- 1 | // 2 | // Auto Generated: Test runner. 3 | // Creates a list of all the unit tests. 4 | // 5 | 6 | import srm_unit_test_pkg::*; 7 | import <%=unit_test_pkg%>::*; 8 | 9 | program main; 10 | string unit_test_name; 11 | srm_unit_test test; 12 | 13 | // Instantiate all tests. 14 | <%@src_unit_tests.each_with_index {|t, i|%> 15 | <%=t%> t_<%=i%> = new(); 16 | <%}%> 17 | 18 | initial begin 19 | if($value$plusargs("UNIT_TEST_NAME=%s", unit_test_name)) begin 20 | $display("Running %s test(s)", unit_test_name); 21 | end 22 | 23 | if(unit_test_name == "") begin 24 | foreach(srm_unit_test::test_list[i]) begin 25 | $display("Run Test %s", srm_unit_test::test_list[i].get_name()); 26 | srm_unit_test::test_list[i].run(); 27 | end 28 | end 29 | else begin 30 | test = srm_unit_test::test_list[unit_test_name]; 31 | if(test == null) begin 32 | $display("Could not find test %s", unit_test_name); 33 | 34 | foreach(srm_unit_test::test_list[i]) begin 35 | $display("Dump: TestName %s", srm_unit_test::test_list[i].get_name()); 36 | end 37 | 38 | $fatal(-1); 39 | end 40 | $display("Run Test %s", test.get_name()); 41 | test.run(); 42 | end 43 | 44 | if(srm_unit_test::fail_cnt == 0) begin 45 | $display("SUNIT_TEST_PASS:PassCnt=%0d", srm_unit_test::pass_cnt); 46 | end else begin 47 | $display("SUNIT_TEST_FAIL:PassCnt=%0d,FailCnt=%0d", 48 | srm_unit_test::pass_cnt, srm_unit_test::fail_cnt); 49 | end 50 | end 51 | endprogram 52 | -------------------------------------------------------------------------------- /unit_fwk/sim_cfiles.rb: -------------------------------------------------------------------------------- 1 | require 'pathname' 2 | 3 | class SimCfiles 4 | attr_reader :src_files, :files, :incdirs, :src_incdirs, :unit_tests, :src_unit_tests, 5 | :unit_test_pkg 6 | 7 | def initialize(cfg_file) 8 | @files = [] 9 | @src_files = [] 10 | @incdirs = [] 11 | @src_incdirs = [] 12 | @unit_tests = [] 13 | @src_unit_tests = [] 14 | 15 | # Read the file list treating each entry as a glob pattern. 16 | # Convert the relative path to absolute path. 17 | prefix = File.dirname(cfg_file) 18 | Dir.chdir(prefix) do 19 | eval(File.read(File.basename(cfg_file))) 20 | files.each do |pattern| 21 | Dir.glob(pattern).each do |f| 22 | @src_files << get_absolute_path(f) 23 | end 24 | end 25 | 26 | incdirs.each do |d| 27 | @src_incdirs << get_absolute_path(d) 28 | end 29 | 30 | unit_tests.each do |pattern| 31 | Dir.glob(pattern).each do |f| 32 | @src_unit_tests << File.basename(f, ".*") 33 | end 34 | end 35 | end 36 | abort "Must define the unit test packet" unless unit_test_pkg 37 | end 38 | 39 | def get_absolute_path(fname) 40 | File.expand_path(fname) 41 | end 42 | 43 | def get_binding 44 | binding() 45 | end 46 | 47 | end 48 | 49 | -------------------------------------------------------------------------------- /unit_fwk/srm_unit_test.svh: -------------------------------------------------------------------------------- 1 | `define RUN_TEST(test) \ 2 | do begin \ 3 | setup(); \ 4 | local_fail_cnt = 0; \ 5 | $write("UnitTestRun:%s:Line %0d:%s:", \ 6 | `__FILE__, `__LINE__, `"test`"); \ 7 | test(); \ 8 | if(local_fail_cnt) $write("FAIL:%0d\n", local_fail_cnt); else $write("PASS\n"); \ 9 | test_fail_cnt += local_fail_cnt; \ 10 | test_pass_cnt += local_pass_cnt; \ 11 | teardown(); \ 12 | end while(0) 13 | 14 | `define TEST_VALUE(a, b, msg) \ 15 | do begin \ 16 | if((a) == (b)) begin \ 17 | pass_cnt += 1; \ 18 | local_pass_cnt += 1; \ 19 | end else begin \ 20 | fail_cnt += 1; \ 21 | local_fail_cnt += 1; \ 22 | $display("TestFailed:%s:Expected:%0d(0x%0x), Got %0d(0x%0x)", msg, a, a, b, b); \ 23 | end \ 24 | end while(0) 25 | 26 | `define TEST_STRING(a, b, msg) \ 27 | do begin \ 28 | if((a) == (b)) begin \ 29 | pass_cnt += 1; \ 30 | local_pass_cnt += 1; \ 31 | end else begin \ 32 | fail_cnt += 1; \ 33 | local_fail_cnt += 1; \ 34 | $display("TestFailed:%s:Expected:%s, Got %s", msg, a, b); \ 35 | end \ 36 | end while(0) 37 | 38 | `define TEST_HANDLE(a, b, msg) \ 39 | do begin \ 40 | if((a) == (b)) begin \ 41 | pass_cnt += 1; \ 42 | local_pass_cnt += 1; \ 43 | end else begin \ 44 | fail_cnt += 1; \ 45 | local_fail_cnt += 1; \ 46 | $display("TestFailed:%s:Handle Expected:%p, Got %p", msg, a, b); \ 47 | end \ 48 | end while(0) 49 | 50 | class srm_unit_test; 51 | string name; 52 | static int pass_cnt; 53 | static int fail_cnt; 54 | int logfile; 55 | int test_pass_cnt; 56 | int test_fail_cnt; 57 | int local_pass_cnt; 58 | int local_fail_cnt; 59 | 60 | static srm_unit_test test_list[string]; 61 | 62 | function new(string name); 63 | this.name = name; 64 | srm_unit_test::test_list[name] = this; 65 | endfunction 66 | 67 | function string get_name(); 68 | return name; 69 | endfunction 70 | 71 | virtual function void setup(); 72 | endfunction 73 | 74 | virtual function void teardown(); 75 | endfunction 76 | 77 | function void test_equal(bit expr, string failure_message = ""); 78 | if(expr) begin 79 | pass_cnt += 1; 80 | test_pass_cnt += 1; 81 | local_pass_cnt += 1; 82 | end else begin 83 | fail_cnt += 1; 84 | test_fail_cnt += 1; 85 | local_fail_cnt += 1; 86 | $display("TestFailed:%s", failure_message); 87 | end 88 | endfunction 89 | 90 | function void summary(string name); 91 | $display("=============================================="); 92 | if(test_fail_cnt == 0) begin 93 | $display(" UNIT_TEST_PASS:%s:PassCnt=%0d,FailCnt=%0d", 94 | name, test_pass_cnt, test_fail_cnt); 95 | end 96 | else begin 97 | $display(" UNIT_TEST_FAIL:%s:PassCnt=%0d,FailCnt=%0d", 98 | name, test_pass_cnt, test_fail_cnt); 99 | end 100 | $display("=============================================="); 101 | $display("\n\n"); 102 | 103 | endfunction 104 | 105 | virtual task run(); 106 | assert(!"Derived class must override this"); 107 | endtask 108 | 109 | endclass 110 | 111 | -------------------------------------------------------------------------------- /unit_fwk/srm_unit_test_pkg.sv: -------------------------------------------------------------------------------- 1 | // Package for unit test framework 2 | `ifndef INCLUDED_srm_unit_test_pkg 3 | `define INCLUDED_srm_unit_test_pkg 4 | 5 | package srm_unit_test_pkg; 6 | `include "srm_unit_test.svh" 7 | endpackage 8 | 9 | `endif 10 | -------------------------------------------------------------------------------- /unit_tests/README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | This document describes how to add/run the unit tests for testing out the simple register 3 | package. 4 | 5 | Each unit test is derived from the base class *srm_unit_test*. This has a virtual method *run* 6 | that the derived class must override. 7 | ``` 8 | virtual task run(); 9 | assert(!"Derived class must override this"); 10 | endtask 11 | 12 | ``` 13 | 14 | Also there are 2 other optional methods "setup" and "teardown" that can also be overridden. 15 | ``` 16 | 17 | virtual function void setup(); 18 | endfunction 19 | 20 | virtual function void teardown(); 21 | endfunction 22 | 23 | ``` 24 | 25 | Inside the *run* method, the derived class, runs each of the different tests using the macro 'RUN_TEST'. 26 | By convention, I call each of the test methods as "test_". Before invoking each of the methods, the framework will call the *setup*, and then call *teardown* at the end. 27 | 28 | Currently, I use a script *srun* to run the unit tests. This is written in Ruby and so you 29 | need to have ruby (>2.0) installed in your env. You may need to install additional ruby gem 30 | like "Rainbow" which produces colored console messages. 31 | 32 | # Setup Env 33 | 34 | Neeed to set the envrionment variable *SRM_ROOT* to the current directory and 35 | add the path the to script directory. Note for users with just the distrib 36 | we use the *SRM_HOME* to point to the root directory. 37 | 38 | In bash 39 | ``` 40 | export SRM_ROOT=`pwd` 41 | export PATH=$PATH:$SRM_ROOT/scripts 42 | ``` 43 | 44 | In Csh 45 | ``` 46 | setenv SRM_ROOT `pwd` 47 | set path = ( $path $SRM_ROOT/bin ) 48 | ``` 49 | 50 | Try running. May require additonal ruby packages like "Rainbow". 51 | ``` 52 | srun -h 53 | Usage: srun -f -t 54 | -f, --file SIMFILE Require the path to the simulation control file 55 | -t, --testname TEST Require the name of the uvm top level test to run 56 | -u, --unit_test TEST Optional name of the unit test to run 57 | -o, --out output_dir output directory to create the build and run dir. 58 | -l, --log logfile test.log output file. 59 | 60 | ``` 61 | 62 | # Run Unit Tests 63 | 64 | srun -f unit_tests/sim.cfiles 65 | 66 | This will create the run directory where the stdout.txt and stderr.txt holds the output of command. 67 | 68 | ## Run Individual Test 69 | 70 | srun -f unit_tests/sim.cfiles -u 71 | 72 | 73 | # Generate NaturalDocs 74 | 1. Setup SRM_HOME to the distrib directory. 75 | 2. Run srm_ref/nd/gen_nd 76 | ``` 77 | setenv SRM_HOME `pwd`/distrib 78 | cd srm_ref/nd 79 | ./gen_nd 80 | cd $SRM_HOME 81 | firefox SRM_Reference.html 82 | ``` 83 | 84 | -------------------------------------------------------------------------------- /unit_tests/models/cpu_reg32.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_cpu_reg32_svh 2 | `define INCLUDED_cpu_reg32_svh 3 | 4 | //--------------------------------------------------------- 5 | // CLASS: cpu_reg32 6 | // Cpu register map with multi instances of a 32b RW register. 7 | // 8 | // Offset: Register 9 | //--------------------- 10 | // 'h100 r1 11 | // 'h200 r2 12 | // 'h300 r3 13 | // 'h400 blk4 14 | // | 15 | // \/ 16 | // 'h10 --> r4 17 | // 'h20 --> r5 18 | //--------------------------------------------------------- 19 | 20 | class cpu_reg32 extends srm_node; 21 | 22 | //------------------------------------------------------ 23 | // 32 Bit Register 24 | //------------------------------------------------------ 25 | // Data Type 26 | typedef struct packed { 27 | bit[31:0] field; 28 | } r1_struct_t; 29 | 30 | // Constraint class 31 | class r1_constr extends uvm_object; 32 | `uvm_object_utils(r1_constr) 33 | rand bit [31:0] field; 34 | 35 | function new(string name="r1_constr"); 36 | super.new(name); 37 | endfunction 38 | 39 | function r1_struct_t get_data(); 40 | r1_struct_t d; 41 | d.field = field; 42 | endfunction 43 | endclass 44 | 45 | class r1_reg extends srm_reg#(r1_struct_t); 46 | 47 | srm_field#(bit[31:0]) field; 48 | 49 | function new(string name, srm_node parent); 50 | super.new(name, parent); 51 | field = new(.name("field"), .parent(this), .n_bits(32), .lsb_pos(0), 52 | .volatile(0)); 53 | add_field(field); 54 | endfunction 55 | 56 | endclass 57 | 58 | class blk extends srm_node; 59 | r1_reg r4; 60 | r1_reg r5; 61 | function new(string name, srm_node parent); 62 | super.new(name, parent); 63 | 64 | 65 | r4 = new(.name("r4"), .parent(this)); 66 | add_child(r4); 67 | r4.set_offset("cpu_map", .offset(64'h10)); 68 | 69 | r5 = new(.name("r5"), .parent(this)); 70 | add_child(r5); 71 | r5.set_offset("cpu_map", .offset(64'h20)); 72 | 73 | endfunction 74 | endclass 75 | 76 | //------------------------------------------------------ 77 | // Instantiate all the registers. 78 | //------------------------------------------------------ 79 | r1_reg r1; 80 | r1_reg r2; 81 | r1_reg r3; 82 | blk blk4; 83 | 84 | function new(string name, srm_node parent); 85 | super.new(name, parent); 86 | 87 | r1 = new(.name("r1"), .parent(this)); 88 | add_child(r1); 89 | r1.set_offset("cpu_map", .offset(64'h100)); 90 | 91 | r2 = new(.name("r2"), .parent(this)); 92 | add_child(r2); 93 | r2.set_offset("cpu_map", .offset(64'h200)); 94 | 95 | r3 = new(.name("r3"), .parent(this)); 96 | add_child(r3); 97 | r3.set_offset("cpu_map", .offset(64'h300)); 98 | 99 | blk4 = new(.name("blk4"), .parent(this)); 100 | add_child(blk4); 101 | blk4.set_offset("cpu_map", .offset(64'h400)); 102 | 103 | endfunction 104 | endclass 105 | `endif 106 | 107 | -------------------------------------------------------------------------------- /unit_tests/models/cpu_table32.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_cpu_table32_svh 2 | `define INCLUDED_cpu_table32_svh 3 | 4 | //--------------------------------------------------------- 5 | // CLASS: cpu_table32 6 | // Cpu register map with tables of 10 entries. 7 | // 8 | // Offset: Register 9 | //--------------------- 10 | // 'h100 r1 with 10 entries 11 | // 'h200 r2 with 10 entries 12 | // 'h300 r3 with 10 entries 13 | // 'h400 blk4 14 | // | 15 | // \/ 16 | // 'h10 --> r4 with 10 entries 17 | // 'h40 --> r5 with 10 entries 18 | //--------------------------------------------------------- 19 | 20 | class cpu_table32 extends srm_node; 21 | 22 | //------------------------------------------------------ 23 | // Data type for each entry in the table. 24 | //------------------------------------------------------ 25 | // Data Type 26 | typedef struct packed { 27 | bit[31:0] field; 28 | } r1_struct_t; 29 | 30 | //------------------------------------------------------ 31 | // Table with 10 entries of 4B each. 32 | //------------------------------------------------------ 33 | 34 | class r1_reg_array extends srm_table#(r1_struct_t); 35 | 36 | // Entry in the table. 37 | class r1_reg extends srm_table_entry#(r1_struct_t); 38 | srm_field#(bit[31:0]) field; 39 | 40 | function new(string name, srm_node parent, srm_addr_t index=-1); 41 | super.new(name, parent, index); 42 | field = new(.name("field"), .parent(this), .n_bits(32), .lsb_pos(0), 43 | .volatile(0)); 44 | add_field(field); 45 | endfunction 46 | 47 | virtual function r1_reg clone(srm_addr_t index); 48 | r1_reg obj; 49 | obj = new(.name($psprintf("%s_%0d", get_name(), index)), 50 | .parent(_parent), .index(index)); 51 | __initialize(obj); 52 | return obj; 53 | endfunction 54 | endclass 55 | 56 | function new(string name, srm_node parent); 57 | r1_reg entry; 58 | super.new(name, parent, .num_entries(10)); 59 | entry = new(.name("r1_reg_entry"), .parent(this)); 60 | _prototype = entry; 61 | endfunction 62 | endclass 63 | 64 | class blk extends srm_node; 65 | r1_reg_array r4; 66 | r1_reg_array r5; 67 | 68 | function new(string name, srm_node parent); 69 | super.new(name, parent); 70 | 71 | r4 = new(.name("r4"), .parent(this)); 72 | add_child(r4); 73 | r4.set_offset(.addr_map_name("cpu_map"), .offset(64'h10)); 74 | 75 | r5 = new(.name("r5"), .parent(this)); 76 | add_child(r5); 77 | r5.set_offset(.addr_map_name("cpu_map"), .offset(64'h40)); 78 | endfunction 79 | endclass 80 | 81 | //------------------------------------------------------ 82 | // Instantiate table. 83 | //------------------------------------------------------ 84 | r1_reg_array r1; 85 | r1_reg_array r2; 86 | r1_reg_array r3; 87 | blk blk4; 88 | 89 | function new(string name, srm_node parent); 90 | super.new(name, parent); 91 | 92 | r1 = new(.name("r1"), .parent(this)); 93 | add_child(r1); 94 | r1.set_offset(.addr_map_name("cpu_map"), .offset(64'h100)); 95 | 96 | r2 = new(.name("r2"), .parent(this)); 97 | add_child(r2); 98 | r2.set_offset(.addr_map_name("cpu_map"), .offset(64'h200)); 99 | 100 | r3 = new(.name("r3"), .parent(this)); 101 | add_child(r3); 102 | r3.set_offset(.addr_map_name("cpu_map"), .offset(64'h300)); 103 | 104 | blk4 = new(.name("blk4"), .parent(this)); 105 | add_child(blk4); 106 | blk4.set_offset(.addr_map_name("cpu_map"), .offset(64'h400)); 107 | 108 | endfunction 109 | endclass 110 | `endif 111 | 112 | -------------------------------------------------------------------------------- /unit_tests/models/cpu_top.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_CPU_TOP_SVH 2 | `define INCLUDED_CPU_TOP_SVH 3 | 4 | //--------------------------------------------------- 5 | // CLASS: cpu_top 6 | // Include the 2 submaps. 7 | // Offset Register 8 | // 'h0 cpu_reg32 9 | // 'h1000 cpu_table32 10 | //--------------------------------------------------- 11 | 12 | class cpu_top extends srm_node; 13 | 14 | cpu_reg32 cpu_reg32; 15 | cpu_table32 cpu_table32; 16 | 17 | function new(string name, srm_node parent); 18 | super.new(name, parent); 19 | 20 | cpu_reg32 = new(.name("cpu_reg32"), .parent(this)); 21 | add_child(cpu_reg32); 22 | cpu_reg32.set_offset(.addr_map_name("cpu_map"), .offset('h0)); 23 | 24 | cpu_table32 = new(.name("cpu_table32"), .parent(this)); 25 | add_child(cpu_table32); 26 | cpu_table32.set_offset(.addr_map_name("cpu_map"), .offset('h1000)); 27 | 28 | endfunction 29 | endclass 30 | 31 | `endif 32 | -------------------------------------------------------------------------------- /unit_tests/models/test_models_pkg.sv: -------------------------------------------------------------------------------- 1 | // Package with all the memory models. 2 | `ifndef TEST_MODELS_PKG_SV 3 | `define TEST_MODELS_PKG_SV 4 | 5 | package test_models_pkg; 6 | import uvm_pkg::*; 7 | `include "uvm_macros.svh" 8 | 9 | import srm_pkg::*; 10 | 11 | `include "cpu_reg32.svh" 12 | `include "cpu_table32.svh" 13 | `include "cpu_multi_field.svh" 14 | `include "cpu_volatile_field.svh" 15 | `include "cpu_top.svh" 16 | endpackage 17 | 18 | `endif 19 | -------------------------------------------------------------------------------- /unit_tests/sim.cfiles: -------------------------------------------------------------------------------- 1 | # All the stuff required for verilog compile. 2 | # This Ruby code. So any legal ruby syntax goes. 3 | # 4 | @files = [ 5 | ENV["UVM_HOME"] + "/src/uvm_pkg.sv", 6 | ENV["SRM_ROOT"] + "/distrib/src/srm_pkg.sv", 7 | "../unit_fwk/srm_unit_test_pkg.sv", 8 | "models/*_pkg.sv", 9 | "../unit_fwk/srm_unit_test.sv", 10 | "*_pkg.sv" 11 | ] 12 | 13 | @incdirs = [ ENV['UVM_HOME'] + "/src", 14 | ENV['SRM_ROOT'] + "/distrib/src", 15 | "../unit_fwk", 16 | "models", 17 | "." 18 | ] 19 | 20 | @unit_tests = ["test_*.svh"] 21 | @unit_test_pkg = "unit_tests_pkg" 22 | -------------------------------------------------------------------------------- /unit_tests/test_bus_predictor.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_bus_predictor_svh 2 | `define INCLUDED_test_bus_predictor_svh 3 | 4 | class test_bus_predictor extends srm_unit_test; 5 | cpu_reg32 reg32_model; 6 | cpu_table32 table32_model; 7 | 8 | function new(); 9 | super.new("test_bus_predictor"); 10 | endfunction 11 | 12 | virtual function void setup(); 13 | reg32_model = new(.name("reg32_model"), .parent(null)); 14 | reg32_model.set_offset(.addr_map_name("cpu_map"), .offset('h10000)); 15 | 16 | table32_model = new(.name("table32_model"), .parent(null)); 17 | table32_model.set_offset(.addr_map_name("cpu_map"), .offset('h20000)); 18 | endfunction 19 | 20 | task test_size_reg; 21 | `TEST_VALUE(4, reg32_model.r1.get_size("cpu_map"), "r1 is 32b wide"); 22 | `TEST_VALUE(4, reg32_model.blk4.r4.get_size("cpu_map"), "r4 is 32b wide"); 23 | `TEST_VALUE('h24, reg32_model.blk4.get_size("cpu_map"), "blk4 has 2 registers spaced out"); 24 | endtask 25 | 26 | task test_size_table; 27 | `TEST_VALUE(40, table32_model.r1.get_size("cpu_map"), "table r1 has 10 entries of 4B"); 28 | `TEST_VALUE(40, table32_model.r2.get_size("cpu_map"), "table r2 has 10 entries of 4B"); 29 | `TEST_VALUE(40, table32_model.r3.get_size("cpu_map"), "table r3 has 10 entries of 4B"); 30 | `TEST_VALUE('h40 + 10*4, table32_model.blk4.get_size("cpu_map"), "table blk4 size match"); 31 | endtask 32 | 33 | task test_address_reg; 34 | srm_node r = reg32_model.address_2_instance("cpu_map", 64'h10100); 35 | `TEST_HANDLE(reg32_model.r1, r, "Handle r1 must be the same"); 36 | r = reg32_model.address_2_instance("cpu_map", 64'h10200); 37 | `TEST_HANDLE(reg32_model.r2, r, "Handle r2 must be the same"); 38 | r = reg32_model.address_2_instance("cpu_map", 64'h10300); 39 | `TEST_HANDLE(reg32_model.r3, r, "Handle r3 must be the same"); 40 | r = reg32_model.address_2_instance("cpu_map", 64'h10410); 41 | `TEST_HANDLE(reg32_model.blk4.r4, r, "Handle r4 must be the same"); 42 | r = reg32_model.address_2_instance("cpu_map", 64'h10420); 43 | `TEST_HANDLE(reg32_model.blk4.r5, r, "Handle r5 must be the same"); 44 | endtask 45 | 46 | task test_address_table; 47 | srm_node r; 48 | 49 | `TEST_VALUE(1, table32_model.r1.is_leaf_node(), "Table r1 must be a leaf node"); 50 | 51 | r = table32_model.address_2_instance("cpu_map", 64'h20100); 52 | `TEST_HANDLE(table32_model.r1, r, "Handle r1 must match the start of table r1"); 53 | r = table32_model.address_2_instance("cpu_map", 64'h20128-1); 54 | `TEST_HANDLE(table32_model.r1, r, "Handle r1 must match the end of table r1"); 55 | 56 | r = table32_model.address_2_instance("cpu_map", 64'h20224); 57 | `TEST_HANDLE(table32_model.r2, r, "Handle r2 must match the end of table r2"); 58 | 59 | r = table32_model.address_2_instance("cpu_map", 64'h20410); 60 | `TEST_HANDLE(table32_model.blk4.r4, r, "Handle r4 must match the end of table r4"); 61 | 62 | r = table32_model.address_2_instance("cpu_map", 64'h20440); 63 | `TEST_HANDLE(table32_model.blk4.r5, r, "Handle r5 must match the start of table r5"); 64 | r = table32_model.address_2_instance("cpu_map", 64'h20444); 65 | `TEST_HANDLE(table32_model.blk4.r5, r, "Handle r5 must match the table r5"); 66 | r = table32_model.address_2_instance("cpu_map", 64'h20440 + 9*4); 67 | `TEST_HANDLE(table32_model.blk4.r5, r, "Handle r5 must match the end of table r5"); 68 | 69 | endtask 70 | 71 | virtual task run(); 72 | `RUN_TEST(test_size_reg); 73 | `RUN_TEST(test_size_table); 74 | `RUN_TEST(test_address_reg); 75 | `RUN_TEST(test_address_table); 76 | endtask 77 | 78 | endclass 79 | 80 | `endif 81 | -------------------------------------------------------------------------------- /unit_tests/test_default_offset.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_default_offset 2 | `define INCLUDED_test_default_offset 3 | 4 | 5 | 6 | class test_default_offset extends srm_unit_test; 7 | 8 | cpu_reg32 regmodel; 9 | 10 | function new(); 11 | super.new("test_default_offset"); 12 | endfunction 13 | 14 | virtual function void setup(); 15 | regmodel = new(.name("regmodel"), .parent(null)); 16 | endfunction 17 | 18 | task test_default_root_offset(); 19 | `TEST_VALUE('h0, regmodel.get_offset("cpu_map"), "Default offset of root is 0"); 20 | endtask 21 | 22 | virtual task run(); 23 | `RUN_TEST(test_default_root_offset); 24 | endtask 25 | 26 | endclass 27 | `endif 28 | -------------------------------------------------------------------------------- /unit_tests/test_field_access.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_field_access_sv 2 | `define INCLUDED_test_field_access_sv 3 | 4 | 5 | 6 | class test_field_access extends srm_unit_test; 7 | 8 | cpu_multi_field regmodel; 9 | cpu_multi_field::r1_struct_t wr_data, rd_data; 10 | 11 | function new(); 12 | super.new("test_field_access"); 13 | endfunction 14 | 15 | virtual function void setup(); 16 | regmodel = new(.name("regmodel"), .parent(null)); 17 | endfunction 18 | 19 | 20 | task test_reg_field_set(); 21 | wr_data = 'h0; 22 | regmodel.r1.set(wr_data); // Start with all zeros in reg 23 | 24 | regmodel.r1.f0.set('hef); 25 | rd_data = regmodel.r1.get(); 26 | `TEST_VALUE('hef, rd_data, "Field 0 must match"); 27 | 28 | regmodel.r1.f1.set('hbe); 29 | rd_data = regmodel.r1.get(); 30 | `TEST_VALUE('hbeef, rd_data, "Field 1,0 must match"); 31 | 32 | regmodel.r1.f2.set('had); 33 | rd_data = regmodel.r1.get(); 34 | `TEST_VALUE('hadbeef, rd_data, "Field 2,1,0 must match"); 35 | 36 | regmodel.r1.f3.set('hde); 37 | rd_data = regmodel.r1.get(); 38 | `TEST_VALUE('hdeadbeef, rd_data, "Field 3, 2,1,0 must match"); 39 | endtask 40 | 41 | task test_reg_field_get(); 42 | wr_data = 32'hf00dcafe; 43 | regmodel.r1.set(wr_data); 44 | `TEST_VALUE('hfe, regmodel.r1.f0.get(), "Field 0 get must match"); 45 | `TEST_VALUE('hca, regmodel.r1.f1.get(), "Field 1 get must match"); 46 | `TEST_VALUE('h0d, regmodel.r1.f2.get(), "Field 2 get must match"); 47 | `TEST_VALUE('hf0, regmodel.r1.f3.get(), "Field 3 get must match"); 48 | endtask 49 | 50 | task test_table_field_set(); 51 | cpu_multi_field::r2_table::r2_entry entry; 52 | 53 | entry = regmodel.r2.entry_at(13); 54 | entry.f0.set('h1); 55 | entry = regmodel.r2.entry_at(13); 56 | rd_data = entry.get(); 57 | `TEST_VALUE('h1, rd_data, "Field 0 get must match"); 58 | 59 | entry.f1.set('h3); 60 | entry = regmodel.r2.entry_at(13); 61 | rd_data = entry.get(); 62 | `TEST_VALUE('h7, rd_data, "Field 0,1 get must match"); 63 | 64 | entry.f2.set('h7); 65 | entry = regmodel.r2.entry_at(13); 66 | rd_data = entry.get(); 67 | `TEST_VALUE('h3f, rd_data, "Field 0,1,2 get must match"); 68 | 69 | entry.f3.set('h1); 70 | entry = regmodel.r2.entry_at(13); 71 | rd_data = entry.get(); 72 | `TEST_VALUE('h7f, rd_data, "Field 0,1,2,3 get must match"); 73 | 74 | entry.f4.set('h1); 75 | entry = regmodel.r2.entry_at(13); 76 | rd_data = entry.get(); 77 | `TEST_VALUE('hff, rd_data, "Field 0,1,2,3,4 get must match"); 78 | 79 | endtask 80 | task test_table_field_get(); 81 | cpu_multi_field::r2_table::r2_entry entry; 82 | cpu_multi_field::r2_struct_t exp_data; 83 | bit[7:0] got_data; 84 | 85 | exp_data.f4 = 1; 86 | exp_data.f3 = 0; 87 | exp_data.f2 = 5; 88 | exp_data.f1 = 2; 89 | exp_data.f0 = 0; 90 | 91 | entry = regmodel.r2.entry_at(1); 92 | entry.set(exp_data); 93 | 94 | entry = regmodel.r2.entry_at(1); 95 | `TEST_VALUE(exp_data.f0, entry.f0.get(), "Field 0 get must match"); 96 | `TEST_VALUE(exp_data.f1, entry.f1.get(), "Field 1 get must match"); 97 | `TEST_VALUE(exp_data.f2, entry.f2.get(), "Field 2 get must match"); 98 | `TEST_VALUE(exp_data.f3, entry.f3.get(), "Field 3 get must match"); 99 | `TEST_VALUE(exp_data.f4, entry.f4.get(), "Field 4 get must match"); 100 | 101 | endtask 102 | 103 | virtual task run(); 104 | `RUN_TEST(test_reg_field_set); 105 | `RUN_TEST(test_reg_field_get); 106 | `RUN_TEST(test_table_field_set); 107 | `RUN_TEST(test_table_field_get); 108 | endtask 109 | 110 | endclass 111 | 112 | `endif 113 | -------------------------------------------------------------------------------- /unit_tests/test_field_rw.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_field_rw_sv 2 | `define INCLUDED_test_field_rw_sv 3 | 4 | 5 | //--------------------------------------------- 6 | // Class: test_field_rw 7 | // Test the read and write task to the field. 8 | //--------------------------------------------- 9 | 10 | class test_field_rw extends srm_unit_test; 11 | 12 | cpu_multi_field regmodel; 13 | dummy_adapter adapter; 14 | first_adapter_policy adapter_policy; 15 | srm_base_handle cpu_handle; 16 | 17 | cpu_multi_field::r1_struct_t wr_data, rd_data; 18 | 19 | function new(); 20 | super.new("test_field_rw"); 21 | endfunction 22 | 23 | virtual function void setup(); 24 | regmodel = new(.name("regmodel"), .parent(null)); 25 | regmodel.set_offset(.addr_map_name("cpu_map"), .offset(64'h10000)); 26 | 27 | adapter_policy = new(); 28 | cpu_handle = new(); 29 | cpu_handle.initialize(.search_adapter(adapter_policy), .addr_map_name("cpu_map")); 30 | adapter = new(.name("cpu_map_adapter")); 31 | regmodel.add_adapter(adapter); 32 | endfunction 33 | 34 | task test_reg_field_write(); 35 | regmodel.reset("HARD"); 36 | regmodel.r1.store(cpu_handle); 37 | `TEST_VALUE('h01234567, regmodel.r1.get(), "Setup the register"); 38 | 39 | regmodel.r1.f1.write(cpu_handle, 'h0); 40 | 41 | `TEST_VALUE(4'b0010, adapter.byte_enables, "Byte enable for f1 should be off"); 42 | `TEST_VALUE('h01230067, regmodel.r1.get(), "field 1 must be updated"); 43 | endtask 44 | 45 | task test_reg_field_read(); 46 | bit[7:0] value; 47 | regmodel.reset("HARD"); 48 | regmodel.r1.store(cpu_handle); 49 | 50 | regmodel.r1.f2.read(cpu_handle, value); 51 | 52 | `TEST_VALUE(4'b0100, adapter.byte_enables, "Byte enable for f2 should be off"); 53 | `TEST_VALUE('h01234567, regmodel.r1.get(), "read field should not change the contents"); 54 | `TEST_VALUE('h23, value, "read field should not change the contents"); 55 | endtask 56 | 57 | virtual task run(); 58 | `RUN_TEST(test_reg_field_write); 59 | `RUN_TEST(test_reg_field_read); 60 | endtask 61 | 62 | endclass 63 | `endif 64 | -------------------------------------------------------------------------------- /unit_tests/test_leaf_policies.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_leaf_policies_sv 2 | `define INCLUDED_test_leaf_policies_sv 3 | 4 | 5 | //--------------------------------------------- 6 | // Class: test_leaf_policies 7 | // Test the policies defined on registers and tables 8 | //--------------------------------------------- 9 | 10 | class test_leaf_policies extends srm_unit_test; 11 | 12 | cpu_multi_field regmodel; 13 | dummy_adapter adapter; 14 | first_adapter_policy adapter_policy; 15 | srm_base_handle cpu_handle; 16 | 17 | cpu_multi_field::r1_struct_t wr_data, rd_data; 18 | 19 | function new(); 20 | super.new("test_leaf_policies"); 21 | endfunction 22 | 23 | virtual function void setup(); 24 | regmodel = new(.name("regmodel"), .parent(null)); 25 | regmodel.set_offset(.addr_map_name("cpu_map"), .offset(64'h10000)); 26 | 27 | adapter_policy = new(); 28 | cpu_handle = new(); 29 | cpu_handle.initialize(.search_adapter(adapter_policy), .addr_map_name("cpu_map")); 30 | adapter = new(.name("cpu_map_adapter")); 31 | regmodel.add_adapter(adapter); 32 | endfunction 33 | 34 | 35 | task test_read_only_reg(); 36 | bit[7:0] rd_byte; 37 | 38 | regmodel.reset("HARD"); 39 | `TEST_VALUE('h01234567, regmodel.r1.get(), "Setup the register"); 40 | 41 | regmodel.r1.set_policy("cpu_map", srm_ro_policy::get()); 42 | 43 | regmodel.r1.write(cpu_handle, 'h0); 44 | 45 | `TEST_VALUE('h01234567, regmodel.r1.get(), "reg unchanged since read only"); 46 | endtask 47 | 48 | task test_w0crs_table(); 49 | srm_base_field_policy p; 50 | bit[7:0] temp; 51 | cpu_multi_field::r2_table::r2_entry entry; 52 | 53 | regmodel.r2.set_policy("cpu_map", srm_w0crs_policy::get()); 54 | 55 | entry = regmodel.r2.entry_at(1); 56 | 57 | entry.set(8'ha5); 58 | entry.write(cpu_handle, 8'h24); 59 | // 1- no effect, 0-clears 60 | `TEST_VALUE(8'h24, entry.get(), "entry updated by write policy"); 61 | 62 | adapter.last_data = 'h24; // Model the dut behavior 63 | entry.read(cpu_handle, temp); 64 | `TEST_VALUE('h24, temp, "Read entry returns the rtl data"); 65 | `TEST_VALUE('hff, entry.get(), "Policy must set entry"); 66 | 67 | endtask 68 | 69 | virtual task run(); 70 | `RUN_TEST(test_read_only_reg); 71 | `RUN_TEST(test_w0crs_table); 72 | endtask 73 | 74 | endclass 75 | `endif 76 | -------------------------------------------------------------------------------- /unit_tests/test_model_coverage.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_model_coverage_sv 2 | `define INCLUDED_test_model_coverage_sv 3 | 4 | 5 | 6 | // 7 | // Class: test_model_coverage 8 | // Create a functional coverage model attached to the root node. 9 | // Use the callback routine to update the coverage as different registers 10 | // are accessed. 11 | // 12 | class test_model_coverage extends srm_unit_test; 13 | 14 | // 15 | // Class: functional coverage model of dut. 16 | // 17 | class fcov_model extends srm_base_coverage; 18 | cpu_reg32 _regmodel; 19 | cpu_reg32::r1_struct_t r1_data; 20 | 21 | covergroup reg32_covergroup; 22 | coverpoint {r1_data.field == 32'hdeadbeef }; 23 | endgroup 24 | 25 | function new(cpu_reg32 regmodel); 26 | super.new("fcov_model"); 27 | reg32_covergroup = new; 28 | _regmodel = regmodel; 29 | endfunction 30 | 31 | virtual function void post_write(srm_base_reg entry); 32 | srm_data_t bytes = entry.get_bytes(); 33 | 34 | // Coverage for r1 35 | if(entry == _regmodel.r1) begin 36 | r1_data = 'h0; 37 | for(int i = 0; i < bytes.size(); i++) begin 38 | r1_data[i*8 +: 8] = bytes[i]; 39 | end 40 | reg32_covergroup.sample(); 41 | end 42 | 43 | endfunction 44 | 45 | endclass 46 | 47 | cpu_reg32 regmodel; 48 | dummy_adapter adapter; 49 | first_adapter_policy adapter_policy; 50 | 51 | srm_base_handle cpu_handle; 52 | fcov_model fcov_inst; 53 | cpu_reg32::r1_struct_t wr_data, rd_data; 54 | 55 | function new(); 56 | super.new("test_model_coverage"); 57 | endfunction 58 | 59 | 60 | virtual function void setup(); 61 | regmodel = new(.name("regmodel"), .parent(null)); 62 | fcov_inst = new(regmodel); 63 | adapter_policy = new(); 64 | cpu_handle = new("cpu_handle"); 65 | cpu_handle.initialize(.search_adapter(adapter_policy), .addr_map_name("cpu_map")); 66 | adapter = new(.name("cpu_map_adapter")); 67 | regmodel.add_adapter(adapter); 68 | endfunction 69 | 70 | task test_model_coverage; 71 | // Attach the observer to the root node. 72 | regmodel.attach(fcov_inst); 73 | cpu_handle.enable_functional_coverage = 1; 74 | wr_data.field = 32'h0; 75 | regmodel.r1.write(cpu_handle, wr_data); 76 | `TEST_VALUE(50, $rtoi(fcov_inst.reg32_covergroup.get_coverage()), "false coverage expected."); 77 | 78 | wr_data.field = 32'hdeadbeef; 79 | regmodel.r1.write(cpu_handle, wr_data); 80 | `TEST_VALUE(100, $rtoi(fcov_inst.reg32_covergroup.get_coverage()), "false + true coverage expected"); 81 | endtask 82 | 83 | virtual task run(); 84 | `RUN_TEST(test_model_coverage); 85 | endtask 86 | 87 | endclass 88 | `endif 89 | -------------------------------------------------------------------------------- /unit_tests/test_reg32.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_reg32_sv 2 | `define INCLUDED_test_reg32_sv 3 | 4 | class test_reg32 extends srm_unit_test; 5 | 6 | cpu_reg32 regmodel; 7 | 8 | cpu_reg32::r1_struct_t wr_data, rd_data; 9 | 10 | function new(); 11 | super.new("test_reg32"); 12 | endfunction 13 | 14 | virtual function void setup(); 15 | regmodel = new(.name("regmodel"), .parent(null)); 16 | regmodel.set_offset(.addr_map_name("cpu_map"), .offset(64'h10000)); 17 | 18 | endfunction 19 | 20 | task test_set_get_r1; 21 | wr_data.field = 32'hdeadbeef; 22 | regmodel.r1.set(wr_data); 23 | rd_data = regmodel.r1.get(); 24 | `TEST_VALUE(32'hdeadbeef, rd_data.field, "get data matches the set data"); 25 | endtask 26 | 27 | task test_tree; 28 | srm_node leaves[$]; 29 | regmodel.get_leaf_nodes(leaves); 30 | `TEST_VALUE(1, regmodel.is_root_node(), "Root node match"); 31 | `TEST_VALUE(4, regmodel.num_children(), "Root node has 4 children"); 32 | `TEST_VALUE(5, leaves.size(), "r1 to r5 children"); 33 | `TEST_STRING("regmodel.r1", leaves[0].get_full_name(), "Full name r1 must match"); 34 | `TEST_STRING("regmodel.r2", leaves[1].get_full_name(), "Full name r2 must match"); 35 | `TEST_STRING("regmodel.r3", leaves[2].get_full_name(), "Full name r3 must match"); 36 | `TEST_STRING("regmodel.blk4.r4", leaves[3].get_full_name(), "Full name r4 must match"); 37 | `TEST_STRING("regmodel.blk4.r5", leaves[4].get_full_name(), "Full name r5 must match"); 38 | endtask 39 | 40 | task test_address_map; 41 | `TEST_VALUE(32'h10000, regmodel.get_offset("cpu_map"), "Base addr of cpu must match"); 42 | `TEST_VALUE(32'h10100, regmodel.r1.get_offset("cpu_map"), "Start addr of r1 must match"); 43 | `TEST_VALUE(32'h10200, regmodel.r2.get_offset("cpu_map"), "Start addr of r2 must match"); 44 | `TEST_VALUE(32'h10300, regmodel.r3.get_offset("cpu_map"), "Start addr of r3 must match"); 45 | `TEST_VALUE(32'h10400, regmodel.blk4.get_offset("cpu_map"), "Start addr of blk4 must match"); 46 | `TEST_VALUE(32'h10410, regmodel.blk4.r4.get_offset("cpu_map"), "Start addr of r4 must match"); 47 | `TEST_VALUE(32'h10420, regmodel.blk4.r5.get_offset("cpu_map"), "Start addr of r5 must match"); 48 | endtask 49 | 50 | virtual task run(); 51 | `RUN_TEST(test_set_get_r1); 52 | `RUN_TEST(test_tree); 53 | `RUN_TEST(test_address_map); 54 | endtask 55 | 56 | endclass 57 | `endif 58 | -------------------------------------------------------------------------------- /unit_tests/test_reg32_rand.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_reg32_rand_sv 2 | `define INCLUDED_test_reg32_rand_sv 3 | 4 | 5 | class test_reg32_rand extends srm_unit_test; 6 | 7 | cpu_reg32 regmodel; 8 | 9 | cpu_reg32::r1_struct_t wr_data, rd_data; 10 | 11 | function new(); 12 | super.new("test_reg32_rand"); 13 | endfunction 14 | 15 | virtual function void setup(); 16 | regmodel = new(.name("regmodel"), .parent(null)); 17 | regmodel.set_offset(.addr_map_name("cpu_map"), .offset(64'h10000)); 18 | 19 | endfunction 20 | 21 | task test_set_get_r1; 22 | cpu_reg32::r1_constr c1; 23 | c1 = cpu_reg32::r1_constr::type_id::create("r1_constr"); 24 | assert(c1.randomize()); 25 | wr_data = c1.get_data(); 26 | 27 | regmodel.r1.set(wr_data); 28 | rd_data = regmodel.r1.get(); 29 | `TEST_VALUE(wr_data.field, rd_data.field, "get data matches the set data"); 30 | endtask 31 | 32 | virtual task run(); 33 | `RUN_TEST(test_set_get_r1); 34 | endtask 35 | 36 | endclass 37 | `endif 38 | -------------------------------------------------------------------------------- /unit_tests/test_reg_reset.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_reg_reset 2 | `define INCLUDED_test_reg_reset 3 | 4 | 5 | 6 | class test_reg_reset extends srm_unit_test; 7 | 8 | cpu_multi_field regmodel; 9 | 10 | function new(); 11 | super.new("test_reg_reset"); 12 | endfunction 13 | 14 | virtual function void setup(); 15 | regmodel = new(.name("regmodel"), .parent(null)); 16 | endfunction 17 | 18 | task test_get_reset_value(); 19 | `TEST_VALUE(1, regmodel.r1.is_resettable("HARD"), "R1 must be resettable"); 20 | `TEST_VALUE(1, regmodel.r1.is_resettable("HARD"), "R1 must have reset"); 21 | `TEST_VALUE('h01234567, regmodel.r1.get(), "read out hard value"); 22 | endtask 23 | 24 | task test_reset_set_value(); 25 | cpu_multi_field::r1_struct_t wr_data = 32'hf00dcafe; 26 | regmodel.r1.set(wr_data); 27 | `TEST_VALUE('hf00dcafe, regmodel.r1.get(), "read out set value"); 28 | regmodel.r1.reset("BIST"); 29 | `TEST_VALUE('h89abcdef, regmodel.r1.get(), "read out bist value"); 30 | endtask 31 | 32 | task test_multi_reset(); 33 | regmodel.r1.reset("BIST"); 34 | `TEST_VALUE('h89abcdef, regmodel.r1.get(), "read out bist value"); 35 | regmodel.r1.reset("HARD"); 36 | `TEST_VALUE('h01234567, regmodel.r1.get(), "read out hard value"); 37 | endtask 38 | 39 | task test_top_multi_reset(); 40 | regmodel.reset("BIST"); 41 | `TEST_VALUE('h89abcdef, regmodel.r1.get(), "read out bist value"); 42 | regmodel.reset("HARD"); 43 | `TEST_VALUE('h01234567, regmodel.r1.get(), "read out hard value"); 44 | endtask 45 | 46 | virtual task run(); 47 | `RUN_TEST(test_get_reset_value); 48 | `RUN_TEST(test_reset_set_value); 49 | `RUN_TEST(test_multi_reset); 50 | `RUN_TEST(test_top_multi_reset); 51 | endtask 52 | 53 | endclass 54 | `endif 55 | -------------------------------------------------------------------------------- /unit_tests/test_reg_rw.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_reg_rw_sv 2 | `define INCLUDED_test_reg_rw_sv 3 | 4 | 5 | //--------------------------------------------- 6 | // Class: test_reg_rw 7 | // Test the read and write task to the register 8 | //--------------------------------------------- 9 | 10 | class test_reg_rw extends srm_unit_test; 11 | 12 | cpu_reg32 regmodel; 13 | dummy_adapter adapter; 14 | first_adapter_policy adapter_policy; 15 | srm_base_handle cpu_handle; 16 | 17 | cpu_reg32::r1_struct_t wr_data, rd_data; 18 | 19 | function new(); 20 | super.new("test_reg_rw"); 21 | endfunction 22 | 23 | virtual function void setup(); 24 | regmodel = new(.name("regmodel"), .parent(null)); 25 | regmodel.set_offset(.addr_map_name("cpu_map"), .offset(64'h10000)); 26 | 27 | adapter_policy = new(); 28 | cpu_handle = new("cpu_handle"); 29 | cpu_handle.initialize(.search_adapter(adapter_policy), .addr_map_name("cpu_map")); 30 | adapter = new(.name("cpu_map_adapter")); 31 | regmodel.add_adapter(adapter); 32 | endfunction 33 | 34 | task test_write_r1; 35 | wr_data.field = 32'hdeadbeef; 36 | cpu_handle.generic_xact_status = SRM_NOT_OK; // Just for testing overwrite 37 | regmodel.r1.write(cpu_handle, wr_data); 38 | rd_data = regmodel.r1.get(); 39 | `TEST_VALUE(32'hdeadbeef, rd_data.field, "written data must match"); 40 | `TEST_VALUE(SRM_IS_OK, cpu_handle.generic_xact_status, "write status must be ok"); 41 | endtask 42 | 43 | task test_field_write_r1; 44 | cpu_handle.generic_xact_status = SRM_NOT_OK; // Just for testing overwrite 45 | regmodel.r1.write(cpu_handle, 'h0); 46 | regmodel.r1.field.write(cpu_handle, 'h01234567); 47 | rd_data = regmodel.r1.get(); 48 | `TEST_VALUE(32'h01234567, rd_data.field, "written data must match"); 49 | `TEST_VALUE(SRM_IS_OK, cpu_handle.generic_xact_status, "write status must be ok"); 50 | endtask 51 | 52 | task test_read_r1; 53 | wr_data.field = 32'h01234567; 54 | cpu_handle.generic_xact_status = SRM_NOT_OK; // Just for testing overwrite 55 | 56 | // Ensure that the model and design have the same data. 57 | regmodel.r1.set(wr_data); 58 | adapter.last_data = wr_data.field; 59 | 60 | regmodel.r1.read(cpu_handle, rd_data); 61 | `TEST_VALUE(32'h01234567, rd_data.field, "read data must match"); 62 | `TEST_VALUE(SRM_IS_OK, cpu_handle.generic_xact_status, "read status must be ok"); 63 | endtask 64 | 65 | task test_field_read_r1; 66 | adapter.last_data = 'h01234567; 67 | regmodel.r1.set('h01234567); 68 | regmodel.r1.field.read(cpu_handle, rd_data); 69 | `TEST_VALUE(32'h01234567, regmodel.r1.field.get(), "written data must match"); 70 | `TEST_VALUE(SRM_IS_OK, cpu_handle.generic_xact_status, "write status must be ok"); 71 | endtask 72 | 73 | task test_mismatch_read_r1; 74 | cpu_reg32::r1_struct_t temp_data; 75 | wr_data.field = 32'h01234567; 76 | cpu_handle.generic_xact_status = SRM_NOT_OK; // Just for testing overwrite 77 | 78 | // Ensure that the model and design have DIFFERENT data. 79 | temp_data.field = 32'h0; 80 | regmodel.r1.set(temp_data); 81 | adapter.last_data = wr_data.field; 82 | cpu_handle.skip_read_error_msg = 1; 83 | 84 | regmodel.r1.read(cpu_handle, rd_data); 85 | `TEST_VALUE(32'h01234567, regmodel.r1.field.get(), "read data must return the RTL data"); 86 | `TEST_VALUE(SRM_READ_DATA_MISMATCH, cpu_handle.generic_xact_status, "read status must mismatch"); 87 | `TEST_VALUE(1, cpu_handle.error_msgs.size(), "Error must be generated"); 88 | endtask 89 | 90 | task test_load_r1; 91 | cpu_reg32::r1_struct_t temp_data; 92 | wr_data.field = 32'h01234567; 93 | 94 | // Ensure that the model and design have DIFFERENT data. 95 | temp_data.field = 32'h0; 96 | regmodel.r1.set(temp_data); 97 | adapter.last_data = wr_data.field; 98 | 99 | regmodel.r1.load(cpu_handle); 100 | rd_data = regmodel.r1.get(); 101 | `TEST_VALUE(32'h01234567, rd_data.field, "load data must return the RTL data"); 102 | endtask 103 | 104 | task test_store_r1; 105 | wr_data.field = 32'h01234567; 106 | 107 | regmodel.r1.set(wr_data); 108 | regmodel.r1.store(cpu_handle); 109 | `TEST_VALUE(32'h01234567, adapter.last_data, "store must write data"); 110 | endtask 111 | 112 | virtual task run(); 113 | `RUN_TEST(test_write_r1); 114 | `RUN_TEST(test_field_write_r1); 115 | `RUN_TEST(test_read_r1); 116 | `RUN_TEST(test_field_read_r1); 117 | `RUN_TEST(test_mismatch_read_r1); 118 | `RUN_TEST(test_load_r1); 119 | `RUN_TEST(test_store_r1); 120 | endtask 121 | 122 | endclass 123 | `endif 124 | -------------------------------------------------------------------------------- /unit_tests/test_srm_utils_1.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_srm_utils_1_sv 2 | `define INCLUDED_test_srm_utils_1_sv 3 | 4 | 5 | class test_srm_utils_1 extends srm_unit_test; 6 | 7 | function new(); 8 | super.new("test_srm_utils_1"); 9 | endfunction 10 | 11 | task test_byte_mask; 12 | `TEST_VALUE(8'h0, srm_utils::create_byte_mask(8'hff, 0, 8), "Mask the entire byte"); 13 | `TEST_VALUE(8'h1, srm_utils::create_byte_mask(8'hff, 1, 7), "Mask the entire byte"); 14 | `TEST_VALUE(8'hf, srm_utils::create_byte_mask(8'hff, 4, 4), "Mask the entire byte"); 15 | `TEST_VALUE(8'he7, srm_utils::create_byte_mask(8'hff, 3, 2), "Mask the entire byte"); 16 | `TEST_VALUE(8'hc1, srm_utils::create_byte_mask(8'hff, 1, 5), "Mask the entire byte"); 17 | endtask 18 | 19 | task test_get_num_bits; 20 | `TEST_VALUE(3, srm_utils::get_left_bits(.start_idx(4), .n_bits(3)), "start_idx=4, len=3"); 21 | `TEST_VALUE(8, srm_utils::get_left_bits(.start_idx(0), .n_bits(9)), "start_idx=0, len=9"); 22 | `TEST_VALUE(4, srm_utils::get_left_bits(.start_idx(4), .n_bits(7)), "start_idx=4, len=7"); 23 | `TEST_VALUE(1, srm_utils::get_left_bits(.start_idx(7), .n_bits(8)), "start_idx=7, len=8"); 24 | endtask 25 | 26 | task test_get_num_bytes; 27 | `TEST_VALUE(4, srm_utils::get_num_bytes(.lsb_pos(17), .n_bits(31)), "lsb=17, len=31"); 28 | `TEST_VALUE(1, srm_utils::get_num_bytes(.lsb_pos(12), .n_bits(2)), "lsb=12, len=2"); 29 | `TEST_VALUE(4, srm_utils::get_num_bytes(.lsb_pos(1), .n_bits(24)), "lsb=1, len=24"); 30 | endtask 31 | 32 | task test_extract_byte; 33 | `TEST_VALUE(8'ha5, srm_utils::extract_byte_from(8'ha5, .lsb(0)), 34 | "zero lsb is no change"); 35 | `TEST_VALUE(8'ha, srm_utils::extract_byte_from(8'ha5, .lsb(4)), 36 | "extract uppper nibble"); 37 | `TEST_VALUE(8'h2, srm_utils::extract_byte_from(8'ha5, .lsb(6)), 38 | "extract upper 2 bits"); 39 | `TEST_VALUE(8'h1, srm_utils::extract_byte_from(8'ha5, .lsb(7)), 40 | "extract from lsb"); 41 | endtask 42 | 43 | task test_bytes_2_hex_1; 44 | srm_data_t bytes = {8'h5}; 45 | `TEST_STRING("0x05", srm_utils::bytes_2_hex(bytes), "Single byte display"); 46 | endtask 47 | 48 | task test_bytes_2_hex_16; 49 | srm_data_t bytes; 50 | bytes = new[16]; 51 | for(int i = 0; i < 16; i++) bytes[i] = i; 52 | `TEST_STRING("0x0f0e0d0c0b0a09080706050403020100", srm_utils::bytes_2_hex(bytes), "16 byte display"); 53 | endtask 54 | 55 | task test_extract_byte_enables; 56 | srm_byte_enable_t field_enables; 57 | srm_byte_enable_t byte_enables; 58 | byte_enables = new[4]; 59 | 60 | for(int i = 0; i < 4; i++) byte_enables[i] = 1; 61 | field_enables = srm_utils::extract_field_enables(byte_enables, 12, 5); 62 | `TEST_VALUE(2, field_enables.size(), "size of field enables 12:16 match"); 63 | `TEST_STRING("11", srm_utils::bits_2_str(field_enables), "Byte enables must match"); 64 | endtask 65 | 66 | task test_set_byte_enables; 67 | srm_byte_enable_t byte_enables; 68 | byte_enables = new[3]; 69 | for(int i = 0; i < 3; i++) byte_enables[i] = 0; 70 | srm_utils::set_field_enables(byte_enables, 12, 4); 71 | `TEST_STRING("010", srm_utils::bits_2_str(byte_enables), "set bit 12:15 match"); 72 | srm_utils::set_field_enables(byte_enables, 20, 4); 73 | `TEST_STRING("110", srm_utils::bits_2_str(byte_enables), "set bit 20:23 match"); 74 | srm_utils::set_field_enables(byte_enables, 1, 1); 75 | `TEST_STRING("111", srm_utils::bits_2_str(byte_enables), "set bit 1 match"); 76 | endtask 77 | 78 | task test_set_byte_enables_2; 79 | srm_byte_enable_t byte_enables; 80 | byte_enables = new[4]; 81 | for(int i = 0; i < 3; i++) byte_enables[i] = 0; 82 | srm_utils::set_field_enables(byte_enables, 8, 1); 83 | `TEST_STRING("0010", srm_utils::bits_2_str(byte_enables), "set bit byte1 match"); 84 | srm_utils::set_field_enables(byte_enables, 23, 2); 85 | `TEST_STRING("1110", srm_utils::bits_2_str(byte_enables), "set bit byte2-3 match"); 86 | endtask 87 | 88 | virtual task run(); 89 | `RUN_TEST(test_byte_mask); 90 | `RUN_TEST(test_get_num_bits); 91 | `RUN_TEST(test_get_num_bytes); 92 | `RUN_TEST(test_extract_byte); 93 | `RUN_TEST(test_bytes_2_hex_1); 94 | `RUN_TEST(test_bytes_2_hex_16); 95 | `RUN_TEST(test_extract_byte_enables); 96 | `RUN_TEST(test_set_byte_enables); 97 | `RUN_TEST(test_set_byte_enables_2); 98 | endtask 99 | endclass 100 | 101 | `endif 102 | -------------------------------------------------------------------------------- /unit_tests/test_srm_utils_2.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_srm_utils_2_sv 2 | `define INCLUDED_test_srm_utils_2_sv 3 | 4 | 5 | class test_srm_utils_2 extends srm_unit_test; 6 | function bit[31:0] bytes_2_bits(srm_data_t bytes); 7 | reg[31:0] out_bits; 8 | for(int i = 0; i < 32/8; i++) begin 9 | for(int j = 0; j < 8; j++) begin 10 | out_bits[i*8 + j] = bytes[i] >> j; 11 | end 12 | end 13 | return out_bits; 14 | endfunction 15 | 16 | function srm_data_t bits_2_bytes(bit[31:0] d); 17 | bit[7:0] temp; 18 | srm_data_t bytes = new[4]; 19 | for(int i = 0; i < 4; i++) begin 20 | bytes[i] = 0; 21 | temp = 'h0; 22 | for(int j = 8; j > 0; j--) begin 23 | temp = temp << 1; 24 | temp |= d[i*8+j-1]; 25 | end 26 | bytes[i] = temp; 27 | end 28 | return bytes; 29 | endfunction 30 | 31 | function new(); 32 | super.new("test_srm_utils_2"); 33 | endfunction 34 | 35 | task test_bytes_2_bits; 36 | bit[31:0] bits; 37 | srm_data_t bytes = new[4]; 38 | for(int i = 0; i < 4; i++) bytes[i] = i; 39 | bits = bytes_2_bits(bytes); 40 | `TEST_VALUE(32'h03020100, bits, "Bits must match byte3-0"); 41 | endtask 42 | 43 | task test_bits_2_bytes; 44 | bit[31:0] bits; 45 | srm_data_t bytes; 46 | bits = 32'hdeadbeef; 47 | bytes = bits_2_bytes(bits); 48 | 49 | `TEST_VALUE(8'hef, bytes[0], "byte 0 must match"); 50 | `TEST_VALUE(8'hbe, bytes[1], "byte 1 must match"); 51 | `TEST_VALUE(8'had, bytes[2], "byte 2 must match"); 52 | `TEST_VALUE(8'hde, bytes[3], "byte 3 must match"); 53 | endtask 54 | 55 | task test_byte_merge; 56 | srm_data_t in_bytes, out_bytes, exp_bytes, fbytes; 57 | bit[31:0] bits; 58 | int lsb_pos; 59 | fbytes = new[1]; 60 | lsb_pos = 0; 61 | 62 | while(lsb_pos != 7) begin 63 | for(int n_bits = 1; (n_bits + lsb_pos) < 8; n_bits++) begin 64 | fbytes[0] = 'h0; 65 | bits = 32'hffffffff; 66 | in_bytes = bits_2_bytes(bits); 67 | 68 | for(int offset = 0; offset < 4; offset++) begin 69 | for(int i = lsb_pos; i < (lsb_pos + n_bits); i++) begin 70 | bits[offset*8+i] = fbytes[i-lsb_pos]; 71 | end 72 | exp_bytes = bits_2_bytes(bits); 73 | srm_utils::merge_field(.reg_bytes(in_bytes), 74 | .field_bytes(fbytes), 75 | .lsb_pos(offset*8+lsb_pos), .n_bits(n_bits)); 76 | `TEST_VALUE(exp_bytes[offset], in_bytes[offset], 77 | $psprintf("Offset=%0d,LsbPos=%0d,n_bits=%0d", offset,lsb_pos, n_bits)); 78 | end 79 | end 80 | lsb_pos += 1; 81 | end 82 | 83 | endtask 84 | 85 | virtual task run(); 86 | `RUN_TEST(test_bytes_2_bits); 87 | `RUN_TEST(test_bits_2_bytes); 88 | //FIXME `RUN_TEST(test_byte_merge); 89 | endtask 90 | endclass 91 | 92 | `endif 93 | -------------------------------------------------------------------------------- /unit_tests/test_table32.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_table32_sv 2 | `define INCLUDED_test_table32_sv 3 | 4 | 5 | class test_table32 extends srm_unit_test; 6 | 7 | cpu_table32 regmodel; 8 | cpu_table32::r1_struct_t wr_data, rd_data; 9 | 10 | function new(); 11 | super.new("test_table32"); 12 | endfunction 13 | 14 | virtual function void setup(); 15 | regmodel = new(.name("regmodel"), .parent(null)); 16 | regmodel.set_offset("cpu_map", 64'h10000); 17 | endfunction 18 | 19 | task test_set_get; 20 | srm_node leaves[$]; 21 | // NC verilog has a issue with function chaining. Works for vcs. 22 | srm_reg#(cpu_table32::r1_struct_t) entry; 23 | wr_data.field = 'ha5; 24 | entry = regmodel.r1.entry_at(8); 25 | entry.set(wr_data); 26 | 27 | rd_data = entry.get(); 28 | `TEST_VALUE('ha5, rd_data.field, "get data matches the set data"); 29 | 30 | entry = regmodel.r1.entry_at(8); 31 | rd_data = entry.get(); 32 | `TEST_VALUE('ha5, rd_data.field, "get data matches the set data"); 33 | 34 | endtask 35 | 36 | task test_tree; 37 | srm_node leaves[$]; 38 | regmodel.get_leaf_nodes(leaves); 39 | `TEST_VALUE(1, regmodel.is_root_node(), "Root node match"); 40 | `TEST_VALUE(4, regmodel.num_children(), "Root node has 4 children"); 41 | `TEST_VALUE(5, leaves.size(), "Number of leaves must match"); 42 | `TEST_STRING("regmodel.r1", leaves[0].get_full_name(), "Name of r1 must match"); 43 | `TEST_STRING("regmodel.r2", leaves[1].get_full_name(), "Name of r2 must match"); 44 | `TEST_STRING("regmodel.r3", leaves[2].get_full_name(), "Name of r3 must match"); 45 | `TEST_STRING("regmodel.blk4.r4", leaves[3].get_full_name(), "Full name r4 must match"); 46 | `TEST_STRING("regmodel.blk4.r5", leaves[4].get_full_name(), "Full name r5 must match"); 47 | endtask 48 | 49 | task test_address_nodes; 50 | `TEST_VALUE(32'h10000, regmodel.get_offset("cpu_map"), "Start addr of cpu must match"); 51 | `TEST_VALUE(32'h10100, regmodel.r1.get_offset("cpu_map"), "Start addr of r1 match"); 52 | `TEST_VALUE(32'h10200, regmodel.r2.get_offset("cpu_map"), "Start addr of r2 match"); 53 | `TEST_VALUE(32'h10300, regmodel.r3.get_offset("cpu_map"), "Start addr of r3 match"); 54 | `TEST_VALUE(32'h10400, regmodel.blk4.get_offset("cpu_map"), "Start addr of blk4 must match"); 55 | `TEST_VALUE(32'h10410, regmodel.blk4.r4.get_offset("cpu_map"), "Start addr of r4 must match"); 56 | `TEST_VALUE(32'h10440, regmodel.blk4.r5.get_offset("cpu_map"), "Start addr of r5 must match"); 57 | endtask 58 | 59 | task test_address_entries; 60 | srm_reg#(cpu_table32::r1_struct_t) entry; 61 | entry = regmodel.r1.entry_at(0); 62 | `TEST_VALUE(32'h10100, entry.get_offset("cpu_map"), "Addr of r1.entry#0 must match"); 63 | entry = regmodel.r1.entry_at(9); 64 | `TEST_VALUE(32'h10124, entry.get_offset("cpu_map"), "Addr of r1.entry#9 must match"); 65 | 66 | entry = regmodel.r2.entry_at(0); 67 | `TEST_VALUE(32'h10200, entry.get_offset("cpu_map"), "Addr of r2.entry#0 must match"); 68 | entry = regmodel.r2.entry_at(9); 69 | `TEST_VALUE(32'h10224, entry.get_offset("cpu_map"), "Addr of r2.entry#9 must match"); 70 | endtask 71 | 72 | task test_address_blk4_entries; 73 | srm_reg#(cpu_table32::r1_struct_t) entry; 74 | entry = regmodel.blk4.r4.entry_at(0); 75 | `TEST_VALUE(32'h10410, entry.get_offset("cpu_map"), "Addr of blk4.r4.entry#0 must match"); 76 | entry = regmodel.blk4.r4.entry_at(9); 77 | `TEST_VALUE(32'h10434, entry.get_offset("cpu_map"), "Addr of blk4.r4.entry#9 must match"); 78 | endtask 79 | 80 | virtual task run(); 81 | `RUN_TEST(test_set_get); 82 | `RUN_TEST(test_tree); 83 | `RUN_TEST(test_address_nodes); 84 | `RUN_TEST(test_address_entries); 85 | `RUN_TEST(test_address_blk4_entries); 86 | endtask 87 | 88 | endclass 89 | `endif 90 | -------------------------------------------------------------------------------- /unit_tests/test_table_coverage.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_table_coverage_sv 2 | `define INCLUDED_test_table_coverage_sv 3 | 4 | class test_table_coverage extends srm_unit_test; 5 | 6 | // Define a custom coverage model. 7 | class r1_fcov_model extends srm_base_coverage; 8 | cpu_table32::r1_struct_t data; 9 | srm_addr_t index; 10 | srm_addr_t xact_addr; 11 | 12 | covergroup r1_data_cg; 13 | coverpoint {data.field == 32'hdeadbeef }; 14 | endgroup 15 | 16 | covergroup r1_index_cg; 17 | coverpoint {index == 9}; 18 | endgroup 19 | 20 | 21 | virtual function void post_write(srm_base_reg entry); 22 | srm_data_t bytes = entry.get_bytes(); 23 | data = 'h0; 24 | for(int i = 0; i < bytes.size(); i++) begin 25 | data[i*8 +: 8] = bytes[i]; 26 | end 27 | index = entry.get_index(); 28 | r1_data_cg.sample(); 29 | r1_index_cg.sample(); 30 | endfunction 31 | 32 | covergroup r1_addr_cg; 33 | coverpoint {xact_addr == 'h100}; 34 | endgroup 35 | 36 | virtual function void sample_xact(const ref srm_generic_xact_t xact); 37 | xact_addr = xact.addr; 38 | r1_addr_cg.sample(); 39 | endfunction 40 | 41 | function new(); 42 | super.new("r1_fcov_model"); 43 | r1_data_cg = new; 44 | r1_index_cg = new; 45 | r1_addr_cg = new; 46 | endfunction 47 | endclass 48 | 49 | cpu_table32 regmodel; 50 | dummy_adapter adapter; 51 | first_adapter_policy adapter_policy; 52 | 53 | srm_base_handle cpu_handle; 54 | r1_fcov_model fcov_inst; 55 | cpu_table32::r1_struct_t wr_data, rd_data; 56 | 57 | function new(); 58 | super.new("test_table_coverage"); 59 | endfunction 60 | 61 | 62 | virtual function void setup(); 63 | regmodel = new(.name("regmodel"), .parent(null)); 64 | fcov_inst = new(); 65 | adapter_policy = new(); 66 | cpu_handle = new("cpu_handle"); 67 | cpu_handle.initialize(.search_adapter(adapter_policy), .addr_map_name("cpu_map")); 68 | adapter = new(.name("cpu_map_adapter")); 69 | regmodel.add_adapter(adapter); 70 | endfunction 71 | 72 | task test_attach_observer; 73 | regmodel.attach(fcov_inst); 74 | `TEST_VALUE(0, regmodel.get_num_coverage_cbs(), "Observer only at leaf node"); 75 | `TEST_VALUE(1, regmodel.r1.get_num_coverage_cbs(), "r1 must have 1 observer"); 76 | `TEST_VALUE(1, regmodel.r2.get_num_coverage_cbs(), "r2 must have 1 observer"); 77 | `TEST_VALUE(1, regmodel.r3.get_num_coverage_cbs(), "r3 must have 1 observer"); 78 | `TEST_VALUE(1, regmodel.blk4.r4.get_num_coverage_cbs(), "r4 must have 1 observer"); 79 | `TEST_VALUE(1, regmodel.blk4.r5.get_num_coverage_cbs(), "r5 must have 1 observer"); 80 | endtask 81 | 82 | task test_detach_observer; 83 | regmodel.attach(fcov_inst); 84 | `TEST_VALUE(1, regmodel.blk4.r5.get_num_coverage_cbs(), "r5 must have 1 observer"); 85 | regmodel.detach(fcov_inst); 86 | `TEST_VALUE(0, regmodel.get_num_coverage_cbs(), "Observer only at leaf node"); 87 | `TEST_VALUE(0, regmodel.r1.get_num_coverage_cbs(), "r1 must have 0 observer"); 88 | `TEST_VALUE(0, regmodel.r2.get_num_coverage_cbs(), "r2 must have 0 observer"); 89 | `TEST_VALUE(0, regmodel.r3.get_num_coverage_cbs(), "r3 must have 0 observer"); 90 | `TEST_VALUE(0, regmodel.blk4.r4.get_num_coverage_cbs(), "r4 must have 0 observer"); 91 | `TEST_VALUE(0, regmodel.blk4.r5.get_num_coverage_cbs(), "r5 must have 0 observer"); 92 | endtask 93 | 94 | task test_detach_all; 95 | regmodel.attach(fcov_inst); 96 | `TEST_VALUE(1, regmodel.blk4.r5.get_num_coverage_cbs(), "r5 must have 1 observer"); 97 | regmodel.detach_all(); 98 | `TEST_VALUE(0, regmodel.blk4.r4.get_num_coverage_cbs(), "r4 must have 0 observer"); 99 | `TEST_VALUE(0, regmodel.blk4.r5.get_num_coverage_cbs(), "r5 must have 0 observer"); 100 | endtask 101 | 102 | task test_r1_write_sample; 103 | srm_reg#(cpu_table32::r1_struct_t) entry; 104 | 105 | cpu_handle.enable_functional_coverage = 1; 106 | regmodel.r1.attach(fcov_inst); 107 | `TEST_VALUE(1, regmodel.r1.get_num_coverage_cbs(), "r1 must have 1 observer"); 108 | 109 | entry = regmodel.r1.entry_at(0); 110 | wr_data.field = 32'h0; 111 | entry.write(cpu_handle, wr_data); 112 | `TEST_VALUE(50, $rtoi(fcov_inst.r1_addr_cg.get_coverage()), "r1 addr coverage achieved"); 113 | `TEST_VALUE(50, $rtoi(fcov_inst.r1_data_cg.get_coverage()), "false data coverage achieved"); 114 | `TEST_VALUE(50, $rtoi(fcov_inst.r1_index_cg.get_coverage()), "false addr coverage achieved"); 115 | 116 | entry = regmodel.r1.entry_at(9); 117 | wr_data.field = 32'hdeadbeef; 118 | entry.write(cpu_handle, wr_data); 119 | `TEST_VALUE(100, $rtoi(fcov_inst.r1_data_cg.get_coverage()), "data coverage achieved"); 120 | `TEST_VALUE(100, $rtoi(fcov_inst.r1_index_cg.get_coverage()), "addr coverage achieved"); 121 | endtask 122 | 123 | virtual task run(); 124 | `RUN_TEST(test_attach_observer); 125 | `RUN_TEST(test_detach_observer); 126 | `RUN_TEST(test_detach_all); 127 | `RUN_TEST(test_r1_write_sample); 128 | endtask 129 | 130 | endclass 131 | `endif 132 | -------------------------------------------------------------------------------- /unit_tests/test_table_reset.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_table_reset 2 | `define INCLUDED_test_table_reset 3 | 4 | 5 | 6 | class test_table_reset extends srm_unit_test; 7 | 8 | cpu_multi_field regmodel; 9 | srm_reg#(cpu_multi_field::r2_struct_t) entry; 10 | 11 | function new(); 12 | super.new("test_table_reset"); 13 | endfunction 14 | 15 | virtual function void setup(); 16 | regmodel = new(.name("regmodel"), .parent(null)); 17 | endfunction 18 | 19 | task test_get_reset_value(); 20 | `TEST_VALUE(1, regmodel.r2.is_resettable("HARD"), "Table must be resettable"); 21 | `TEST_VALUE(1, regmodel.r2.is_resettable("HARD"), "Table must have reset"); 22 | entry = regmodel.r2.entry_at(8); 23 | `TEST_VALUE('h0, entry.get(), "read out hard value"); 24 | regmodel.reset("BIST"); 25 | entry = regmodel.r2.entry_at(8); 26 | `TEST_VALUE('hff, entry.get(), "read out bist value"); 27 | endtask 28 | 29 | 30 | task test_reset_set_value(); 31 | cpu_multi_field::r2_struct_t wr_data = 8'ha5; 32 | entry = regmodel.r2.entry_at(13); 33 | entry.set(wr_data); 34 | `TEST_VALUE(1, regmodel.r2.get_num_active_entries(), "set entry allocated"); 35 | `TEST_VALUE('ha5, entry.get(), "read out set value"); 36 | regmodel.r2.reset("BIST"); 37 | `TEST_VALUE('hff, entry.get(), "read out reset value"); 38 | endtask 39 | 40 | task test_top_multi_reset(); 41 | regmodel.reset("BIST"); 42 | entry = regmodel.r2.entry_at(1); 43 | `TEST_VALUE('hff, entry.get(), "read out bist value"); 44 | regmodel.reset("HARD"); 45 | `TEST_VALUE('h0, entry.get(), "read out hard value"); 46 | endtask 47 | 48 | virtual task run(); 49 | `RUN_TEST(test_get_reset_value); 50 | `RUN_TEST(test_reset_set_value); 51 | `RUN_TEST(test_top_multi_reset); 52 | endtask 53 | 54 | endclass 55 | `endif 56 | -------------------------------------------------------------------------------- /unit_tests/test_table_rw.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_table_rw_sv 2 | `define INCLUDED_test_table_rw_sv 3 | 4 | 5 | //--------------------------------------------- 6 | // Class: test_table_rw 7 | // Test the read and write task to the table 8 | //--------------------------------------------- 9 | 10 | class test_table_rw extends srm_unit_test; 11 | 12 | cpu_table32 regmodel; 13 | dummy_adapter adapter; 14 | first_adapter_policy adapter_policy; 15 | srm_base_handle cpu_handle; 16 | 17 | cpu_table32::r1_struct_t wr_data, rd_data; 18 | srm_reg#(cpu_table32::r1_struct_t) entry; 19 | 20 | function new(); 21 | super.new("test_table_rw"); 22 | endfunction 23 | 24 | virtual function void setup(); 25 | regmodel = new(.name("regmodel"), .parent(null)); 26 | regmodel.set_offset(.addr_map_name("cpu_map"), .offset(64'h10000)); 27 | 28 | adapter_policy = new(); 29 | cpu_handle = new("cpu_handle"); 30 | cpu_handle.initialize(.search_adapter(adapter_policy), .addr_map_name("cpu_map")); 31 | adapter = new(.name("cpu_map_adapter")); 32 | regmodel.add_adapter(adapter); 33 | endfunction 34 | 35 | task test_write_r1; 36 | 37 | cpu_handle.generic_xact_status = SRM_NOT_OK; // Just for testing overwrite 38 | wr_data.field = 32'hdeadbeef; 39 | entry = regmodel.r1.entry_at(9); 40 | entry.write(cpu_handle, wr_data); 41 | `TEST_VALUE(SRM_IS_OK, cpu_handle.generic_xact_status, "read status must be ok"); 42 | `TEST_VALUE(wr_data.field, adapter.last_data, "adapter write data must match"); 43 | `TEST_VALUE('h10100 + 9*4, adapter.last_addr, "adapter write addr must match"); 44 | rd_data = entry.get(); 45 | `TEST_VALUE(wr_data.field, rd_data.field, "model data must match"); 46 | endtask 47 | 48 | task test_write_r1_incr; 49 | 50 | for(int i = 0; i < regmodel.r1.get_num_entries(); i++) begin 51 | cpu_handle.generic_xact_status = SRM_NOT_OK; // Just for testing overwrite 52 | wr_data.field = i; 53 | entry = regmodel.r1.entry_at(i); 54 | entry.write(cpu_handle, wr_data); 55 | `TEST_VALUE(i, adapter.last_data, "adapter write data must match"); 56 | `TEST_VALUE('h10100 + i*4, adapter.last_addr, "adapter write addr must match"); 57 | end 58 | 59 | for(int i = 0; i < regmodel.r1.get_num_entries(); i++) begin 60 | entry = regmodel.r1.entry_at(i); 61 | rd_data = entry.get(); 62 | `TEST_VALUE(i, rd_data.field, "model must get updated correctly"); 63 | end 64 | endtask 65 | 66 | task test_load_r4; 67 | adapter.last_data = 32'h01234567; 68 | regmodel.blk4.r4.load(cpu_handle); 69 | `TEST_VALUE(10, regmodel.blk4.r4.get_num_active_entries(), "all entries must be loaded"); 70 | for(int i = 0; i < regmodel.blk4.r4.get_num_entries(); i++) begin 71 | entry = regmodel.blk4.r4.entry_at(i); 72 | `TEST_VALUE(32'h01234567, entry.get(), "All entries must be initialized"); 73 | end 74 | endtask 75 | 76 | task test_store_r4; 77 | // Initialize the table. 78 | for(int i = 0; i < regmodel.blk4.r4.get_num_entries(); i++) begin 79 | wr_data.field = i; 80 | entry = regmodel.blk4.r4.entry_at(i); 81 | entry.set(wr_data); 82 | end 83 | // Overwrite the last entry for checking. 84 | wr_data.field = 32'hf00dcafe; 85 | entry = regmodel.blk4.r4.entry_at(9); 86 | entry.set(wr_data); 87 | 88 | regmodel.blk4.r4.store(cpu_handle); 89 | `TEST_VALUE(10, regmodel.blk4.r4.get_num_active_entries(), "all entries must be stored"); 90 | `TEST_VALUE(32'hf00dcafe, adapter.last_data, "model data must be written out"); 91 | `TEST_VALUE(32'h10410 + 9*4, adapter.last_addr, "last model addr must match"); 92 | endtask 93 | 94 | virtual task run(); 95 | `RUN_TEST(test_write_r1); 96 | `RUN_TEST(test_write_r1_incr); 97 | `RUN_TEST(test_load_r4); 98 | `RUN_TEST(test_store_r4); 99 | endtask 100 | 101 | endclass 102 | `endif 103 | -------------------------------------------------------------------------------- /unit_tests/test_top.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_top_sv 2 | `define INCLUDED_test_top_sv 3 | 4 | 5 | class test_top extends srm_unit_test; 6 | 7 | cpu_top regmodel; 8 | 9 | function new(); 10 | super.new("test_top"); 11 | endfunction 12 | 13 | virtual function void setup(); 14 | regmodel = new(.name("regmodel"), .parent(null)); 15 | regmodel.set_offset("cpu_map", 64'hA0000); 16 | endfunction 17 | 18 | task test_tree; 19 | srm_node leaves[$]; 20 | regmodel.get_leaf_nodes(leaves); 21 | `TEST_VALUE(1, regmodel.is_root_node(), "Root node match"); 22 | `TEST_VALUE(2, regmodel.num_children(), "Root node has 2 children"); 23 | `TEST_VALUE(10, leaves.size(), "r1 to r5 children on register and table."); 24 | 25 | `TEST_STRING("regmodel.cpu_reg32.r1", leaves[0].get_full_name(), "name r1 must match"); 26 | `TEST_STRING("regmodel.cpu_reg32.r2", leaves[1].get_full_name(), "name r2 must match"); 27 | `TEST_STRING("regmodel.cpu_reg32.r3", leaves[2].get_full_name(), "name r3 must match"); 28 | `TEST_STRING("regmodel.cpu_reg32.blk4.r4", leaves[3].get_full_name(), "name r4 must match"); 29 | `TEST_STRING("regmodel.cpu_reg32.blk4.r5", leaves[4].get_full_name(), "name r5 must match"); 30 | 31 | `TEST_STRING("regmodel.cpu_table32.r1", leaves[5].get_full_name(), "name r1 must match"); 32 | `TEST_STRING("regmodel.cpu_table32.r2", leaves[6].get_full_name(), "name r2 must match"); 33 | `TEST_STRING("regmodel.cpu_table32.r3", leaves[7].get_full_name(), "name r3 must match"); 34 | `TEST_STRING("regmodel.cpu_table32.blk4.r4", leaves[8].get_full_name(), 35 | "name r4 must match"); 36 | `TEST_STRING("regmodel.cpu_table32.blk4.r5", leaves[9].get_full_name(), 37 | "name r5 must match"); 38 | endtask 39 | 40 | task test_address_map; 41 | `TEST_VALUE(32'hA0000, regmodel.get_offset("cpu_map"), "Base addr of cpu must match"); 42 | `TEST_VALUE(32'hA0000, regmodel.cpu_reg32.get_offset("cpu_map"), 43 | "Start addr of reg32 must match"); 44 | `TEST_VALUE(32'hA1000, regmodel.cpu_table32.get_offset("cpu_map"), 45 | "Start addr of table32 must match"); 46 | endtask 47 | 48 | task test_r1_address; 49 | `TEST_VALUE(32'hA0100, regmodel.cpu_reg32.r1.get_offset("cpu_map"), 50 | "Addr of reg32.r1 must match"); 51 | endtask 52 | 53 | virtual task run(); 54 | `RUN_TEST(test_tree); 55 | `RUN_TEST(test_address_map); 56 | `RUN_TEST(test_r1_address); 57 | endtask 58 | 59 | endclass 60 | `endif 61 | -------------------------------------------------------------------------------- /unit_tests/test_volatile_field.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_volatile_field_sv 2 | `define INCLUDED_test_volatile_field_sv 3 | 4 | 5 | 6 | //---------------------------------------------------- 7 | // CLASS: test_volatile_field 8 | // Test volatile field in both register and table. 9 | //---------------------------------------------------- 10 | 11 | class test_volatile_field extends srm_unit_test; 12 | 13 | cpu_volatile_field regmodel; 14 | 15 | dummy_adapter adapter; 16 | first_adapter_policy adapter_policy; 17 | srm_base_handle cpu_handle; 18 | cpu_volatile_field::r1_struct_t wr_data, rd_data; 19 | 20 | function new(); 21 | super.new("test_volatile_field"); 22 | endfunction 23 | 24 | virtual function void setup(); 25 | regmodel = new(.name("regmodel"), .parent(null)); 26 | adapter_policy = new(); 27 | cpu_handle = new(); 28 | cpu_handle.initialize(.search_adapter(adapter_policy), .addr_map_name("cpu_map")); 29 | adapter = new(.name("cpu_map_adapter")); 30 | regmodel.add_adapter(adapter); 31 | endfunction 32 | 33 | task test_reg_volatile; 34 | regmodel.reset("BIST"); 35 | regmodel.r1.store(cpu_handle); 36 | `TEST_VALUE(32'h89abcdef, adapter.last_data, "ensure that reg data is written"); 37 | 38 | regmodel.r1.f0.set('h0); 39 | regmodel.r1.f2.set('h0); 40 | `TEST_VALUE(32'h8900cd00, regmodel.r1.get(), "ensure model data is different"); 41 | 42 | regmodel.r1.read(cpu_handle, rd_data); 43 | `TEST_VALUE(SRM_IS_OK, cpu_handle.generic_xact_status, "read status must be ok"); 44 | `TEST_VALUE(32'h89abcdef, regmodel.r1.get(), "read data must be updated in model"); 45 | endtask 46 | 47 | task test_table_volatile; 48 | cpu_volatile_field::r2_table::r2_entry entry; 49 | cpu_volatile_field::r2_struct_t rd_data; 50 | 51 | regmodel.reset("BIST"); 52 | regmodel.r2.store(cpu_handle); 53 | `TEST_VALUE(8'hff, adapter.last_data, "ensure that table data is written"); 54 | 55 | entry = regmodel.r2.entry_at(13); 56 | entry.f2.set('h0); 57 | entry.f4.set('h0); 58 | `TEST_VALUE(8'h47, entry.get(), "ensure table model data is different"); 59 | 60 | entry.read(cpu_handle, rd_data); 61 | `TEST_VALUE(SRM_IS_OK, cpu_handle.generic_xact_status, "read status must be ok"); 62 | `TEST_VALUE(8'hff, entry.get(), "read table data must be updated in model"); 63 | endtask 64 | 65 | 66 | task test_table_debug; 67 | cpu_volatile_field::r2_table::r2_entry entry; 68 | cpu_volatile_field::r2_struct_t rd_data; 69 | regmodel.reset("BIST"); 70 | regmodel.r2.store(cpu_handle); 71 | `TEST_VALUE(8'hff, adapter.last_data, "ensure that table data is written"); 72 | endtask 73 | 74 | virtual task run(); 75 | //`RUN_TEST(test_reg_volatile); 76 | //`RUN_TEST(test_table_volatile); 77 | `RUN_TEST(test_table_debug); 78 | endtask 79 | 80 | endclass 81 | 82 | `endif 83 | -------------------------------------------------------------------------------- /unit_tests/unit_test_pkg.sv: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_unit_tests_svh 2 | `define INCLUDED_unit_tests_svh 3 | 4 | package unit_tests_pkg; 5 | import uvm_pkg::*; 6 | `include "uvm_macros.svh" 7 | 8 | import srm_pkg::*; 9 | import test_models_pkg::*; 10 | 11 | import srm_unit_test_pkg::*; 12 | `include "utils.svh" 13 | `include "test_reg32.svh" 14 | `include "test_reg32_rand.svh" 15 | `include "test_table32.svh" 16 | `include "test_top.svh" 17 | `include "test_default_offset.svh" 18 | `include "test_field_access.svh" 19 | `include "test_reg_reset.svh" 20 | `include "test_table_reset.svh" 21 | `include "test_reg_rw.svh" 22 | `include "test_table_rw.svh" 23 | `include "test_field_rw.svh" 24 | `include "test_field_policies.svh" 25 | `include "test_leaf_policies.svh" 26 | `include "test_srm_utils_1.svh" 27 | `include "test_srm_utils_2.svh" 28 | `include "test_volatile_field.svh" 29 | `include "test_bus_predictor.svh" 30 | `include "test_reg_coverage.svh" 31 | `include "test_model_coverage.svh" 32 | `include "test_table_coverage.svh" 33 | endpackage 34 | 35 | `endif 36 | -------------------------------------------------------------------------------- /unit_tests/utils.svh: -------------------------------------------------------------------------------- 1 | `ifndef INCLUDED_test_utils_sv 2 | `define INCLUDED_test_utils_sv 3 | 4 | // A dummy adapter that remembers the last 32b of written data. 5 | class dummy_adapter extends srm_bus_adapter; 6 | reg [31:0] last_data; 7 | reg [31:0] bus_data; 8 | reg [3:0] byte_enables; 9 | srm_addr_t last_addr; 10 | 11 | function new(string name); 12 | super.new(name); 13 | endfunction 14 | 15 | virtual task execute(ref srm_generic_xact_t generic_xact, int seq_priority); 16 | reg[31:0] temp; 17 | 18 | if(generic_xact.kind == srm_pkg::SRM_WRITE) begin 19 | last_data = 'd0; 20 | bus_data = 'd0; 21 | byte_enables = 'd0; 22 | // [31:0] = {byte3, byte2, byte1, byte0} 23 | for(int i = generic_xact.data.size()-1; i >= 0; i--) begin 24 | last_data <<= 8; 25 | bus_data <<= 8; 26 | if(generic_xact.byte_enables[i]) last_data[7:0] = generic_xact.data[i]; 27 | bus_data[7:0] = generic_xact.data[i]; 28 | end 29 | last_addr = generic_xact.addr; 30 | end else begin 31 | // CHEAT HERE: return a hardwired data instead of actually doing a wr sequence. 32 | temp = last_data; 33 | // {byte3, byte2, byte1, byte0} = [31:0] 34 | foreach(generic_xact.data[i]) begin 35 | if(generic_xact.byte_enables[i]) begin 36 | generic_xact.data[i] = temp[7:0]; 37 | end else begin 38 | generic_xact.data[i] = 8'hff; 39 | end 40 | temp >>= 8; 41 | end 42 | end 43 | foreach(generic_xact.byte_enables[i]) begin 44 | byte_enables[i] = generic_xact.byte_enables[i]; 45 | end 46 | generic_xact.status = srm_pkg::SRM_IS_OK; 47 | endtask 48 | 49 | endclass 50 | 51 | // Adapter policy that chooses the first adapter found. 52 | class first_adapter_policy extends srm_search_adapter; 53 | function bit is_correct_adapter(srm_bus_adapter adapter); 54 | return 1; 55 | endfunction 56 | endclass 57 | 58 | `endif 59 | --------------------------------------------------------------------------------