├── .gitignore ├── LICENSE ├── README.md ├── decoratorpattern ├── application │ ├── dut.sv │ ├── output │ ├── run_cadence.sh │ ├── run_mentor.sh │ └── run_synopsys.sh ├── application_parm │ ├── dut.sv │ ├── run_cadence.sh │ ├── run_mentor.sh │ └── run_synopsys.sh └── example │ ├── Beverage.sv │ ├── CondimentDecorator.sv │ ├── DarkRoast.sv │ ├── Decaf.sv │ ├── Espresso.sv │ ├── HouseBlend.sv │ ├── Milk.sv │ ├── Mocha.sv │ ├── SR_MENTOR_TYPED_NAME │ ├── run_mentor.sh │ └── starbuzz.sv │ ├── Soy.sv │ ├── Whip.sv │ ├── output │ ├── run_cadence.sh │ ├── run_mentor.sh │ ├── run_synopsys.sh │ └── starbuzz.sv ├── observer └── example │ ├── CurrentConditionsDisplay.sv │ ├── DisplayElement.sv │ ├── ForecastDisplay.sv │ ├── Observer.sv │ ├── SR_SYNOPSYS_INTERFACE_CLASS_LOCAL │ ├── DisplayElement.sv │ ├── Observer.sv │ └── run_synopsys.sh │ ├── StatisticsDisplay.sv │ ├── Subject.sv │ ├── WeatherData.sv │ ├── WeatherStation.sv │ ├── output │ ├── run_cadence.sh │ ├── run_mentor.sh │ └── run_synopsys.sh ├── singleton └── example │ ├── classic │ ├── Singleton.sv │ ├── output │ ├── run_cadence.sh │ ├── run_mentor.sh │ └── run_synopsys.sh │ └── threadsafe │ ├── Singleton.sv │ ├── output │ ├── run_cadence.sh │ ├── run_mentor.sh │ └── run_synopsys.sh ├── state └── example │ └── gumballstatewinner │ ├── GumballMachine.sv │ ├── GumballMachineTestDrive.sv │ ├── HasQuarterState.sv │ ├── NoQuarterState.sv │ ├── SoldOutState.sv │ ├── SoldState.sv │ ├── State.sv │ ├── WinnerState.sv │ ├── output │ ├── run_cadence.sh │ ├── run_mentor.sh │ └── run_synopsys.sh └── strategypattern ├── application ├── dut.sv ├── output ├── run_cadence.sh ├── run_mentor.sh └── run_synopsys.sh └── example ├── DecoyDuck.sv ├── Duck.sv ├── FlyBehavior.sv ├── FlyNoWay.sv ├── FlyWithWings.sv ├── MallardDuck.sv ├── MiniDuckSimulator.sv ├── ModelDuck.sv ├── MuteQuack.sv ├── Quack.sv ├── QuackBehavior.sv ├── README.md ├── RubberDuck.sv ├── Squeak.sv ├── compile_vcs.sh ├── output ├── run_cadence.sh ├── run_mentor.sh └── run_synopsys.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *INCA_libs 2 | *csrc 3 | *.log 4 | *.diff 5 | *.gz 6 | log 7 | simv 8 | simv.daidir 9 | simv.cst 10 | transcript 11 | ucli.key 12 | work 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # systemverilog-design-patterns 2 | -------------------------------------------------------------------------------- /decoratorpattern/application/dut.sv: -------------------------------------------------------------------------------- 1 | package layer; 2 | 3 | class addr_txn; 4 | rand bit [31:0] addr; 5 | rand int size; 6 | 7 | constraint c_size { size inside {1,2,4}; } 8 | 9 | function void rprint(); 10 | this.randomize(); 11 | print(); 12 | endfunction 13 | 14 | virtual function void print(); 15 | $display(" addr=%h size=%0d", this.addr, this.size); 16 | endfunction 17 | 18 | endclass 19 | 20 | virtual class addr_txnDecorator extends addr_txn; 21 | endclass 22 | 23 | class addr_permit extends addr_txnDecorator; 24 | rand addr_txn txn; 25 | 26 | function new(addr_txn txn); 27 | this.txn = txn; 28 | endfunction 29 | 30 | constraint c_addr_permit { 31 | addr inside {['h00000000 : 'h0000FFFF - txn.size]} || 32 | addr inside {['h10000000 : 'h1FFFFFFF - txn.size]}; 33 | 34 | txn.addr == addr; 35 | txn.size == size; 36 | 37 | // for debug 38 | // addr inside {['h0 : 'hF]}; 39 | } 40 | 41 | endclass 42 | 43 | class addr_prohibit extends addr_txnDecorator; 44 | rand addr_txn txn; 45 | 46 | function new(addr_txn txn); 47 | this.txn = txn; 48 | endfunction 49 | 50 | constraint c_addr_prohibit { 51 | !(addr inside {['h00000000 : 'h00000FFF - txn.size]}); 52 | 53 | txn.addr == addr; 54 | txn.size == size; 55 | 56 | // size == 4; 57 | 58 | // debug constraint very strict 59 | // !(addr inside {['h00000000 : 'h1FFFFFF0 - txn.size]}); 60 | 61 | // for debug 62 | // !(addr inside {['hF : 'hFF]}); 63 | } 64 | endclass 65 | 66 | endpackage 67 | 68 | module top; 69 | 70 | import layer::*; 71 | 72 | layer::addr_txn txn; 73 | layer::addr_permit addr_permit; 74 | layer::addr_prohibit addr_prohibit; 75 | 76 | initial begin 77 | 78 | `ifdef PREFERRED 79 | 80 | $display("RUNNING PREFERRED"); 81 | 82 | $display("addr_txn randomization"); 83 | txn = layer::addr_txn::new; txn.rprint(); 84 | 85 | $display("addr_txn randomization with addr_permit added"); 86 | txn = layer::addr_permit::new(txn); txn.rprint(); 87 | 88 | $display("addr_txn randomization with addr_prohibit and addr_permit added"); 89 | txn = layer::addr_prohibit::new(txn); txn.rprint(); 90 | 91 | // DOES NOT WORK NOT SURE IF IT SHOULD ANYWAYS 92 | // $display("ALTERNATIVE"); 93 | // txn = layer::addr_permit::new(layer::addr_prohibit::new(layer::addr_txn::new)); 94 | // txn.rprint(); 95 | 96 | `else 97 | 98 | // synopsys / cadence has yet to implement "Typed Constructor Calls" 99 | // synopsys STAR NUMBER issue 100 | // the below is functionally equivalent to the above 101 | $display("RUNNING COMPATIBILITY"); 102 | 103 | $display("addr_txn randomization"); 104 | txn = new; 105 | txn.rprint(); 106 | 107 | $display("addr_txn randomization with addr_permit added"); 108 | addr_permit = new(txn); 109 | txn = new addr_permit; 110 | txn.rprint(); 111 | 112 | $display("addr_txn randomization with addr_prohibit and addr_permit added"); 113 | addr_prohibit = new(txn); 114 | txn = new addr_prohibit; 115 | txn.rprint(); 116 | 117 | `endif 118 | 119 | #1; 120 | $finish(); 121 | end 122 | 123 | endmodule 124 | -------------------------------------------------------------------------------- /decoratorpattern/application/output: -------------------------------------------------------------------------------- 1 | RUNNING COMPATIBILITY 2 | addr_txn randomization 3 | addr=74d000c5 size=1 4 | addr_txn randomization with addr_prohibit added 5 | addr=15a0f1dd size=4 6 | addr_txn randomization with addr_prohibit and addr_permit added 7 | addr=11cc212e size=1 8 | -------------------------------------------------------------------------------- /decoratorpattern/application/run_cadence.sh: -------------------------------------------------------------------------------- 1 | irun \ 2 | -clean \ 3 | -access rw \ 4 | -svseed random \ 5 | dut.sv 6 | 7 | # +define+PREFERRED \ 8 | -------------------------------------------------------------------------------- /decoratorpattern/application/run_mentor.sh: -------------------------------------------------------------------------------- 1 | rm -rf work 2 | vlib work 3 | 4 | vlog -sv -pedanticerrors \ 5 | +define+PREFERRED \ 6 | dut.sv 7 | 8 | vsim -c top -do "run -all" -sv_seed random -solvefaildebug 9 | # -solveverbose 10 | -------------------------------------------------------------------------------- /decoratorpattern/application/run_synopsys.sh: -------------------------------------------------------------------------------- 1 | rm -rf simv* csrc simv.daidir 2 | 3 | vcs \ 4 | -sverilog \ 5 | -timescale="1ns/1ns" \ 6 | dut.sv 7 | 8 | simv +ntb_random_seed_automatic 9 | -------------------------------------------------------------------------------- /decoratorpattern/application_parm/dut.sv: -------------------------------------------------------------------------------- 1 | package layer; 2 | 3 | typedef enum {READ, WRITE} rw_t; 4 | 5 | class addr_txn; 6 | rand bit [31:0] addr; 7 | rand int size; 8 | 9 | constraint c_size { size inside {1,2,4}; } 10 | 11 | function void rprint(); 12 | this.randomize(); 13 | print(); 14 | endfunction 15 | 16 | virtual function void print(); 17 | $display(" addr=%h size=%0d", this.addr, this.size); 18 | endfunction 19 | 20 | endclass 21 | 22 | class rw_txn extends addr_txn; 23 | 24 | rand rw_t op; 25 | 26 | virtual function void print(); 27 | $display("rw_txn addr=%h size=%0d", this.addr, this.size); 28 | endfunction 29 | 30 | endclass 31 | 32 | virtual class addr_txnDecorator#(type P = addr_txn) extends P; 33 | endclass 34 | 35 | class addr_permit#(type P = addr_txnDecorator, type T = addr_txn) extends P; 36 | rand T txn; 37 | 38 | function new(T txn); 39 | this.txn = txn; 40 | endfunction 41 | 42 | constraint c_addr_permit { 43 | // addr inside {['h00000000 : 'h0000FFFF - size]} || 44 | // addr inside {['h10000000 : 'h1FFFFFFF - size]}; 45 | addr inside {['h0 : 'hF]}; 46 | } 47 | constraint addr_permit_c { 48 | txn.addr == addr; 49 | } 50 | 51 | endclass 52 | 53 | class addr_prohibit#(type P = addr_txnDecorator, type T = addr_txn) extends P; 54 | rand T txn; 55 | 56 | function new(T txn); 57 | this.txn = txn; 58 | endfunction 59 | 60 | constraint c_addr_prohibit { 61 | addr inside {['hF : 'hFF]}; 62 | // !(addr inside {['h0 : 'h5]}); 63 | // !(addr inside {['h00000000 : 'h00000FFF - size]}); 64 | } 65 | constraint addr_prohibit_c { 66 | txn.addr == addr; 67 | } 68 | endclass 69 | 70 | endpackage 71 | 72 | module top; 73 | 74 | import layer::*; 75 | 76 | layer::addr_txn txn; 77 | layer::addr_permit addr_permit; 78 | layer::addr_prohibit addr_prohibit; 79 | 80 | layer::rw_txn rwtxn; 81 | layer::addr_permit#(.P(layer::addr_txnDecorator#(layer::rw_txn)) , .T(layer::rw_txn)) addr_permit_rw_txn; 82 | layer::addr_prohibit#(.P(layer::addr_txnDecorator#(layer::rw_txn)) , .T(layer::rw_txn)) addr_prohibit_rw_txn; 83 | 84 | 85 | // type P = addr_txnDecorator, type T = addr_txn 86 | 87 | initial begin 88 | 89 | `ifdef PREFERRED 90 | 91 | // TODO why is virtual not working or are we killing it? 92 | $display("RUNNING PREFERRED"); 93 | txn = layer::addr_txn::new; txn.rprint(); 94 | txn = layer::addr_prohibit#()::new(txn); txn.rprint(); 95 | txn = layer::addr_permit#()::new(txn); txn.rprint(); 96 | 97 | rwtxn = layer::rw_txn::new; rwtxn.rprint(); 98 | rwtxn = layer::addr_prohibit#(.P(layer::addr_txnDecorator#(layer::rw_txn)) , .T(layer::rw_txn))::new(rwtxn); 99 | // rwtxn.rprint(); 100 | // rwtxn = layer::addr_permit#(.P(layer::addr_txnDecorator#(layer::rw_txn)) , .T(layer::rw_txn))::new(rwtxn); rwtxn.rprint(); 101 | 102 | // DOES NOT WORK NOT SURE IF IT SHOULD ANYWAYS 103 | // $display("ALTERNATIVE"); 104 | // txn = layer::addr_permit::new(layer::addr_prohibit::new(layer::addr_txn::new)); 105 | // txn.rprint(); 106 | 107 | `else 108 | 109 | // synopsys / cadence has yet to implement "Typed Constructor Calls" 110 | // synopsys STAR NUMBER issue 111 | // the below is functionally equivalent to the above 112 | $display("RUNNING COMPATIBILITY"); 113 | 114 | txn = new; 115 | txn.rprint(); 116 | 117 | addr_permit = new(txn); 118 | txn = new addr_permit; 119 | txn.rprint(); 120 | 121 | addr_prohibit = new(txn); 122 | txn = new addr_prohibit; 123 | txn.rprint(); 124 | 125 | $display("rw_txn"); 126 | 127 | rwtxn = new; 128 | rwtxn.rprint(); 129 | 130 | addr_permit_rw_txn = new(rwtxn); 131 | rwtxn = new addr_permit_rw_txn; 132 | rwtxn.rprint(); 133 | 134 | addr_prohibit_rw_txn = new(rwtxn); 135 | rwtxn = new addr_prohibit_rw_txn; 136 | rwtxn.rprint(); 137 | 138 | 139 | `endif 140 | 141 | #1; 142 | $finish(); 143 | end 144 | 145 | endmodule 146 | -------------------------------------------------------------------------------- /decoratorpattern/application_parm/run_cadence.sh: -------------------------------------------------------------------------------- 1 | irun \ 2 | -clean \ 3 | -access rw \ 4 | -svseed random \ 5 | dut.sv 6 | 7 | # +define+PREFERRED \ 8 | -------------------------------------------------------------------------------- /decoratorpattern/application_parm/run_mentor.sh: -------------------------------------------------------------------------------- 1 | rm -rf work 2 | vlib work 3 | 4 | vlog -sv -pedanticerrors \ 5 | dut.sv 6 | # +define+PREFERRED \ 7 | 8 | 9 | vsim -c top -do "run -all" -sv_seed random -solvefaildebug 10 | # -solveverbose 11 | -------------------------------------------------------------------------------- /decoratorpattern/application_parm/run_synopsys.sh: -------------------------------------------------------------------------------- 1 | rm -rf simv* csrc simv.daidir 2 | 3 | vcs \ 4 | -sverilog \ 5 | -timescale="1ns/1ns" \ 6 | dut.sv 7 | 8 | simv +ntb_random_seed_automatic 9 | -------------------------------------------------------------------------------- /decoratorpattern/example/Beverage.sv: -------------------------------------------------------------------------------- 1 | virtual class Beverage; 2 | string description = "Unknown Beverage"; 3 | 4 | virtual function string getDescription(); 5 | return description; 6 | endfunction 7 | 8 | virtual function real cost(); 9 | endfunction 10 | 11 | endclass 12 | 13 | -------------------------------------------------------------------------------- /decoratorpattern/example/CondimentDecorator.sv: -------------------------------------------------------------------------------- 1 | virtual class CondimentDecorator extends Beverage; 2 | pure virtual function string getDescription(); 3 | endclass 4 | -------------------------------------------------------------------------------- /decoratorpattern/example/DarkRoast.sv: -------------------------------------------------------------------------------- 1 | class DarkRoast extends Beverage; 2 | 3 | function new(); 4 | description = "Dark Roast Coffee"; 5 | endfunction 6 | 7 | virtual function real cost(); 8 | return 0.99; 9 | endfunction 10 | 11 | endclass 12 | 13 | -------------------------------------------------------------------------------- /decoratorpattern/example/Decaf.sv: -------------------------------------------------------------------------------- 1 | class Decaf extends Beverage; 2 | 3 | function new(); 4 | description = "Decaf Coffee"; 5 | endfunction 6 | 7 | virtual function real cost(); 8 | return 1.05; 9 | endfunction 10 | 11 | endclass 12 | -------------------------------------------------------------------------------- /decoratorpattern/example/Espresso.sv: -------------------------------------------------------------------------------- 1 | class Espresso extends Beverage; 2 | 3 | function new(); 4 | description = "Espresso"; 5 | endfunction 6 | 7 | virtual function real cost(); 8 | return 1.99; 9 | endfunction 10 | 11 | endclass 12 | 13 | 14 | -------------------------------------------------------------------------------- /decoratorpattern/example/HouseBlend.sv: -------------------------------------------------------------------------------- 1 | class HouseBlend extends Beverage; 2 | 3 | function new(); 4 | description = "House Blend Coffee"; 5 | endfunction 6 | 7 | virtual function real cost(); 8 | return 0.89; 9 | endfunction 10 | 11 | endclass 12 | -------------------------------------------------------------------------------- /decoratorpattern/example/Milk.sv: -------------------------------------------------------------------------------- 1 | class Milk extends CondimentDecorator; 2 | 3 | Beverage beverage; 4 | 5 | function new(Beverage beverage); 6 | this.beverage = beverage; 7 | endfunction 8 | 9 | virtual function string getDescription(); 10 | return {beverage.getDescription(), ", Milk"}; 11 | endfunction 12 | 13 | virtual function real cost(); 14 | return (0.10 + beverage.cost()); 15 | endfunction 16 | 17 | endclass 18 | -------------------------------------------------------------------------------- /decoratorpattern/example/Mocha.sv: -------------------------------------------------------------------------------- 1 | class Mocha extends CondimentDecorator; 2 | 3 | Beverage beverage; 4 | 5 | function new(Beverage beverage); 6 | this.beverage = beverage; 7 | endfunction 8 | 9 | virtual function string getDescription(); 10 | return {beverage.getDescription(), ", Mocha"}; 11 | endfunction 12 | 13 | virtual function real cost(); 14 | return (0.20 + beverage.cost()); 15 | endfunction 16 | 17 | endclass 18 | -------------------------------------------------------------------------------- /decoratorpattern/example/SR_MENTOR_TYPED_NAME/run_mentor.sh: -------------------------------------------------------------------------------- 1 | rm -rf work 2 | vlib work 3 | 4 | vlog -sv -pedanticerrors \ 5 | +define+PREFERRED \ 6 | +incdir+"./../" \ 7 | starbuzz.sv 8 | 9 | vsim -c top -do "run -all" -sv_seed random -solvefaildebug 10 | # -solveverbose 11 | -------------------------------------------------------------------------------- /decoratorpattern/example/SR_MENTOR_TYPED_NAME/starbuzz.sv: -------------------------------------------------------------------------------- 1 | package starbuzz; 2 | 3 | `include "Beverage.sv" 4 | `include "DarkRoast.sv" 5 | `include "HouseBlend.sv" 6 | `include "Espresso.sv" 7 | `include "Decaf.sv" 8 | `include "CondimentDecorator.sv" 9 | `include "Whip.sv" 10 | `include "Mocha.sv" 11 | `include "Milk.sv" 12 | `include "Soy.sv" 13 | 14 | endpackage 15 | 16 | 17 | module top; 18 | 19 | import starbuzz::*; 20 | 21 | Beverage beverage; 22 | // there is something weird with using Mentor and PREFERRED METHOD and using any other var name than beverage 23 | Beverage beverage2; 24 | Beverage beverage3; 25 | 26 | DarkRoast darkroast; 27 | Espresso espresso; 28 | HouseBlend houseblend; 29 | 30 | string str; 31 | 32 | `ifdef PREFERRED 33 | `else 34 | Mocha mocha; 35 | Whip whip; 36 | Soy soy; 37 | `endif 38 | 39 | 40 | initial begin 41 | `ifdef PREFERRED 42 | beverage = Espresso::new; 43 | str.realtoa(beverage.cost()); 44 | $display({beverage.getDescription(), " $", str}); 45 | 46 | beverage2 = DarkRoast::new; 47 | beverage2 = Mocha::new(beverage2); 48 | beverage2 = Mocha::new(beverage2); 49 | beverage2 = Whip::new(beverage2); 50 | str.realtoa(beverage2.cost()); 51 | $display({beverage2.getDescription(), " $", str}); 52 | 53 | beverage = HouseBlend::new; 54 | beverage = Soy::new(beverage); 55 | beverage = Mocha::new(beverage); 56 | beverage = Whip::new(beverage); 57 | str.realtoa(beverage.cost()); 58 | $display({beverage.getDescription(), " $", str}); 59 | `else 60 | espresso = new; 61 | beverage = new espresso; 62 | str.realtoa(beverage.cost()); 63 | $display({beverage.getDescription(), " $", str}); 64 | 65 | darkroast = new; 66 | beverage2 = new darkroast; 67 | mocha = new(beverage2); 68 | beverage2 = new mocha; 69 | 70 | mocha = new(beverage2); 71 | beverage2 = new mocha; 72 | 73 | whip = new(beverage2); 74 | beverage2 = new whip; 75 | str.realtoa(beverage2.cost()); 76 | $display({beverage2.getDescription(), " $", str}); 77 | 78 | houseblend = new; 79 | beverage3 = new houseblend; 80 | // $display({"P1", beverage3.getDescription()}); 81 | 82 | soy = new(beverage3); 83 | beverage3 = new soy; 84 | // $display({"P2", beverage3.getDescription()}); 85 | 86 | mocha = new(beverage3); 87 | beverage3 = new mocha; 88 | // $display({"P3", beverage3.getDescription()}); 89 | 90 | whip = new(beverage3); 91 | beverage3 = whip; 92 | // $display({"P4", beverage3.getDescription()}); 93 | 94 | str.realtoa(beverage3.cost()); 95 | $display({beverage3.getDescription(), " $", str}); 96 | `endif 97 | 98 | #1; 99 | $finish(); 100 | end 101 | 102 | endmodule // top 103 | -------------------------------------------------------------------------------- /decoratorpattern/example/Soy.sv: -------------------------------------------------------------------------------- 1 | class Soy extends CondimentDecorator; 2 | 3 | Beverage beverage; 4 | 5 | function new(Beverage beverage); 6 | this.beverage = beverage; 7 | // $display({"DEBUG SOY: ", getDescription()}); 8 | endfunction 9 | 10 | virtual function string getDescription(); 11 | return {beverage.getDescription(), ", Soy"}; 12 | endfunction 13 | 14 | virtual function real cost(); 15 | return (0.15 + beverage.cost()); 16 | endfunction 17 | 18 | endclass 19 | -------------------------------------------------------------------------------- /decoratorpattern/example/Whip.sv: -------------------------------------------------------------------------------- 1 | class Whip extends CondimentDecorator; 2 | 3 | Beverage beverage; 4 | 5 | function new(Beverage beverage); 6 | this.beverage = beverage; 7 | endfunction 8 | 9 | virtual function string getDescription(); 10 | return {beverage.getDescription(), ", Whip"}; 11 | endfunction 12 | 13 | virtual function real cost(); 14 | return (0.10 + beverage.cost()); 15 | endfunction 16 | 17 | endclass 18 | -------------------------------------------------------------------------------- /decoratorpattern/example/output: -------------------------------------------------------------------------------- 1 | Espresso $1.99 2 | Dark Roast Coffee, Mocha, Mocha, Whip $1.49 3 | House Blend Coffee, Soy, Mocha, Whip $1.34 4 | -------------------------------------------------------------------------------- /decoratorpattern/example/run_cadence.sh: -------------------------------------------------------------------------------- 1 | irun \ 2 | -clean \ 3 | -access rw \ 4 | -svseed random \ 5 | starbuzz.sv 6 | 7 | # +define+PREFERRED \ 8 | -------------------------------------------------------------------------------- /decoratorpattern/example/run_mentor.sh: -------------------------------------------------------------------------------- 1 | rm -rf work 2 | vlib work 3 | 4 | vlog -sv -pedanticerrors \ 5 | +define+PREFERRED \ 6 | starbuzz.sv 7 | 8 | vsim -c top -do "run -all" -sv_seed random -solvefaildebug 9 | # -solveverbose 10 | -------------------------------------------------------------------------------- /decoratorpattern/example/run_synopsys.sh: -------------------------------------------------------------------------------- 1 | rm -rf simv* csrc simv.daidir 2 | 3 | vcs \ 4 | -sverilog \ 5 | -timescale="1ns/1ns" \ 6 | starbuzz.sv 7 | 8 | simv +ntb_random_seed_automatic 9 | -------------------------------------------------------------------------------- /decoratorpattern/example/starbuzz.sv: -------------------------------------------------------------------------------- 1 | package starbuzz; 2 | 3 | `include "Beverage.sv" 4 | `include "DarkRoast.sv" 5 | `include "HouseBlend.sv" 6 | `include "Espresso.sv" 7 | `include "Decaf.sv" 8 | `include "CondimentDecorator.sv" 9 | `include "Whip.sv" 10 | `include "Mocha.sv" 11 | `include "Milk.sv" 12 | `include "Soy.sv" 13 | 14 | endpackage 15 | 16 | 17 | module top; 18 | 19 | import starbuzz::*; 20 | 21 | Beverage beverage; 22 | // there is something weird with using Mentor and PREFERRED METHOD and using any other var name than beverage 23 | Beverage beverage2; 24 | Beverage beverage3; 25 | 26 | DarkRoast darkroast; 27 | Espresso espresso; 28 | HouseBlend houseblend; 29 | 30 | string str; 31 | 32 | `ifdef PREFERRED 33 | `else 34 | Mocha mocha; 35 | Whip whip; 36 | Soy soy; 37 | `endif 38 | 39 | 40 | initial begin 41 | `ifdef PREFERRED 42 | beverage = Espresso::new; 43 | str.realtoa(beverage.cost()); 44 | $display({beverage.getDescription(), " $", str}); 45 | 46 | beverage = DarkRoast::new; 47 | beverage = Mocha::new(beverage); 48 | beverage = Mocha::new(beverage); 49 | beverage = Whip::new(beverage); 50 | str.realtoa(beverage.cost()); 51 | $display({beverage.getDescription(), " $", str}); 52 | 53 | beverage = HouseBlend::new; 54 | beverage = Soy::new(beverage); 55 | beverage = Mocha::new(beverage); 56 | beverage = Whip::new(beverage); 57 | str.realtoa(beverage.cost()); 58 | $display({beverage.getDescription(), " $", str}); 59 | `else 60 | espresso = new; 61 | beverage = new espresso; 62 | str.realtoa(beverage.cost()); 63 | $display({beverage.getDescription(), " $", str}); 64 | 65 | darkroast = new; 66 | beverage2 = new darkroast; 67 | mocha = new(beverage2); 68 | beverage2 = new mocha; 69 | 70 | mocha = new(beverage2); 71 | beverage2 = new mocha; 72 | 73 | whip = new(beverage2); 74 | beverage2 = new whip; 75 | str.realtoa(beverage2.cost()); 76 | $display({beverage2.getDescription(), " $", str}); 77 | 78 | houseblend = new; 79 | beverage3 = new houseblend; 80 | // $display({"P1", beverage3.getDescription()}); 81 | 82 | soy = new(beverage3); 83 | beverage3 = new soy; 84 | // $display({"P2", beverage3.getDescription()}); 85 | 86 | mocha = new(beverage3); 87 | beverage3 = new mocha; 88 | // $display({"P3", beverage3.getDescription()}); 89 | 90 | whip = new(beverage3); 91 | beverage3 = whip; 92 | // $display({"P4", beverage3.getDescription()}); 93 | 94 | str.realtoa(beverage3.cost()); 95 | $display({beverage3.getDescription(), " $", str}); 96 | `endif 97 | 98 | #1; 99 | $finish(); 100 | end 101 | 102 | endmodule // top 103 | -------------------------------------------------------------------------------- /observer/example/CurrentConditionsDisplay.sv: -------------------------------------------------------------------------------- 1 | class CurrentConditionsDisplay implements Observer, DisplayElement; 2 | 3 | protected shortreal temperature; 4 | protected shortreal humidity; 5 | protected Subject weatherData; 6 | 7 | // TODO: why is this Subject instead of WeatherData? 8 | function new(Subject weatherData); 9 | this.weatherData = weatherData; 10 | weatherData.registerObserver(this); 11 | endfunction // new 12 | 13 | virtual function void update(shortreal temperature, shortreal humidity, shortreal pressure); 14 | this.temperature = temperature; 15 | this.humidity = humidity; 16 | display(); 17 | endfunction // update 18 | 19 | virtual function void display(); 20 | $display("Current conditions: %0d F degrees and %0d humidity", temperature, humidity); 21 | endfunction // display 22 | 23 | endclass // CurrentConditionsDisplay 24 | -------------------------------------------------------------------------------- /observer/example/DisplayElement.sv: -------------------------------------------------------------------------------- 1 | interface class DisplayElement; 2 | // TODO this was a local function in the JAVA version 3 | // Mentor was okay - Synopsys Not 4 | pure virtual function void display(); 5 | endclass // DisplayElement 6 | 7 | -------------------------------------------------------------------------------- /observer/example/ForecastDisplay.sv: -------------------------------------------------------------------------------- 1 | class ForecastDisplay implements Observer, DisplayElement; 2 | 3 | protected shortreal currentPressure = 29.92; 4 | protected shortreal lastPressure; 5 | protected WeatherData weatherData; 6 | 7 | function new(WeatherData weatherData); 8 | this.weatherData = weatherData; 9 | weatherData.registerObserver(this); 10 | endfunction // new 11 | 12 | virtual function void update(shortreal temperature, shortreal humidity, shortreal pressure); 13 | lastPressure = currentPressure; 14 | currentPressure = pressure; 15 | 16 | display(); 17 | endfunction // update 18 | 19 | virtual function void display(); 20 | $display("Forecast:"); 21 | 22 | if (currentPressure > lastPressure) begin 23 | $display("Improving weather on the way!"); 24 | end else if (currentPressure == lastPressure) begin 25 | $display("More of the same"); 26 | end else if (currentPressure < lastPressure) begin 27 | $display("Watch out for cooler, rainy weather"); 28 | end 29 | endfunction // display 30 | 31 | endclass // ForecastDisplay 32 | -------------------------------------------------------------------------------- /observer/example/Observer.sv: -------------------------------------------------------------------------------- 1 | interface class Observer; 2 | pure virtual function void update(shortreal temperature, shortreal humidity, shortreal pressure); 3 | endclass // Observer 4 | 5 | -------------------------------------------------------------------------------- /observer/example/SR_SYNOPSYS_INTERFACE_CLASS_LOCAL/DisplayElement.sv: -------------------------------------------------------------------------------- 1 | interface class DisplayElement; 2 | // TODO this was a local function in the JAVA version 3 | // Mentor was okay - Synopsys Not 4 | pure virtual local function void display(); 5 | endclass // DisplayElement 6 | 7 | -------------------------------------------------------------------------------- /observer/example/SR_SYNOPSYS_INTERFACE_CLASS_LOCAL/Observer.sv: -------------------------------------------------------------------------------- 1 | interface class Observer; 2 | pure virtual local function void update(shortreal temperature, shortreal humidity, shortreal pressure); 3 | endclass // Observer 4 | 5 | -------------------------------------------------------------------------------- /observer/example/SR_SYNOPSYS_INTERFACE_CLASS_LOCAL/run_synopsys.sh: -------------------------------------------------------------------------------- 1 | rm -rf simv* csrc simv.daidir 2 | 3 | vcs \ 4 | -sverilog \ 5 | -timescale="1ns/1ns" \ 6 | DisplayElement.sv \ 7 | Observer.sv \ 8 | ../Subject.sv \ 9 | ../WeatherData.sv \ 10 | ../CurrentConditionsDisplay.sv \ 11 | ../StatisticsDisplay.sv \ 12 | ../ForecastDisplay.sv \ 13 | ../WeatherStation.sv 14 | 15 | simv +ntb_random_seed_automatic 16 | -------------------------------------------------------------------------------- /observer/example/StatisticsDisplay.sv: -------------------------------------------------------------------------------- 1 | class StatisticsDisplay implements Observer, DisplayElement; 2 | 3 | protected shortreal maxTemp = 0.0; 4 | protected shortreal minTemp = 200; 5 | protected shortreal tempSum = 0.0; 6 | protected int numReadings; 7 | protected WeatherData weatherData; 8 | 9 | function new(WeatherData weatherData); 10 | this.weatherData = weatherData; 11 | weatherData.registerObserver(this); 12 | endfunction // new 13 | 14 | virtual function void update(shortreal temperature, shortreal humidity, shortreal pressure); 15 | tempSum += temperature; 16 | numReadings++; 17 | 18 | if (temperature > maxTemp) begin 19 | maxTemp = temperature; 20 | end 21 | 22 | if (temperature < minTemp) begin 23 | minTemp = temperature; 24 | end 25 | 26 | display(); 27 | endfunction // update 28 | 29 | virtual function void display(); 30 | $display("Avg/Max/Min temperature = %0d / %0d / %0d", (tempSum / numReadings), maxTemp, minTemp); 31 | endfunction // display 32 | 33 | endclass // StatisticsDisplay 34 | -------------------------------------------------------------------------------- /observer/example/Subject.sv: -------------------------------------------------------------------------------- 1 | interface class Subject; 2 | pure virtual function void registerObserver(Observer o); 3 | pure virtual function void removeObserver(Observer o); 4 | pure virtual function void notifyObservers(); 5 | endclass // Subject 6 | -------------------------------------------------------------------------------- /observer/example/WeatherData.sv: -------------------------------------------------------------------------------- 1 | class WeatherData implements Subject; 2 | protected Observer observers[$] = {}; 3 | protected real temperature; 4 | protected real humidity; 5 | protected real pressure; 6 | 7 | virtual function void registerObserver(Observer o); 8 | observers.push_back(o); 9 | endfunction // registerObserver 10 | 11 | virtual function void removeObserver(Observer o); 12 | int ix[$]; 13 | ix = observers.find_index with ( item == o); 14 | 15 | foreach (ix[i]) begin 16 | observers.delete(ix[i]); 17 | end 18 | endfunction // removeObserver 19 | 20 | virtual function void notifyObservers(); 21 | foreach (observers[i]) begin 22 | observers[i].update(temperature, humidity, pressure); 23 | end 24 | endfunction // notifyObserver 25 | 26 | function void measurementsChanged(); 27 | notifyObservers(); 28 | endfunction // measurementsChanged 29 | 30 | function void setMeasurements(real temperature, real humidity, real pressure); 31 | this.temperature = temperature; 32 | this.humidity = humidity; 33 | this.pressure = pressure; 34 | measurementsChanged(); 35 | endfunction // setMeasurments 36 | 37 | function real getTemperature(); 38 | return temperature; 39 | endfunction // getTemperature 40 | 41 | function real getHumidity(); 42 | return humidity; 43 | endfunction // getHumidity 44 | 45 | function real getPressure(); 46 | return pressure; 47 | endfunction // getPressure 48 | 49 | endclass // WeatherData 50 | -------------------------------------------------------------------------------- /observer/example/WeatherStation.sv: -------------------------------------------------------------------------------- 1 | class WeatherStation; 2 | WeatherData weatherData; 3 | CurrentConditionsDisplay currentDisplay; 4 | StatisticsDisplay statisticsDisplay; 5 | ForecastDisplay forecastDisplay; 6 | 7 | function void main; 8 | weatherData = new(); 9 | currentDisplay = new(weatherData); 10 | statisticsDisplay = new(weatherData); 11 | forecastDisplay = new(weatherData); 12 | 13 | weatherData.setMeasurements(80, 65, 30.4); $display(""); 14 | weatherData.setMeasurements(82, 70, 29.2); $display(""); 15 | weatherData.setMeasurements(78, 90, 29.2); $display(""); 16 | 17 | weatherData.removeObserver(forecastDisplay); 18 | weatherData.removeObserver(statisticsDisplay); 19 | weatherData.setMeasurements(99, 99, 22); $display(""); 20 | 21 | weatherData.registerObserver(statisticsDisplay); 22 | weatherData.setMeasurements(100, 101, 23); $display(""); 23 | 24 | endfunction 25 | 26 | endclass // WeatherStation 27 | 28 | module tb; 29 | WeatherStation ws; 30 | 31 | initial begin 32 | ws = new(); 33 | ws.main(); 34 | #1; 35 | $finish(); 36 | end 37 | 38 | endmodule // tb 39 | -------------------------------------------------------------------------------- /observer/example/output: -------------------------------------------------------------------------------- 1 | Current conditions: 80 F degrees and 65 humidity 2 | Avg/Max/Min temperature = 80 / 80 / 80 3 | Forecast: 4 | Improving weather on the way! 5 | 6 | Current conditions: 82 F degrees and 70 humidity 7 | Avg/Max/Min temperature = 81 / 82 / 80 8 | Forecast: 9 | Watch out for cooler, rainy weather 10 | 11 | Current conditions: 78 F degrees and 90 humidity 12 | Avg/Max/Min temperature = 80 / 82 / 78 13 | Forecast: 14 | More of the same 15 | 16 | Current conditions: 99 F degrees and 99 humidity 17 | 18 | Current conditions: 100 F degrees and 101 humidity 19 | Avg/Max/Min temperature = 85 / 100 / 78 20 | -------------------------------------------------------------------------------- /observer/example/run_cadence.sh: -------------------------------------------------------------------------------- 1 | irun \ 2 | -clean \ 3 | -access rw \ 4 | -svseed random \ 5 | DisplayElement.sv \ 6 | Observer.sv \ 7 | Subject.sv \ 8 | WeatherData.sv \ 9 | CurrentConditionsDisplay.sv \ 10 | StatisticsDisplay.sv \ 11 | ForecastDisplay.sv \ 12 | WeatherStation.sv 13 | 14 | echo "Cadence at this time cannot to class interface" 15 | 16 | # +define+PREFERRED \ 17 | -------------------------------------------------------------------------------- /observer/example/run_mentor.sh: -------------------------------------------------------------------------------- 1 | rm -rf work 2 | vlib work 3 | 4 | vlog -sv -mfcu \ 5 | DisplayElement.sv \ 6 | Observer.sv \ 7 | Subject.sv \ 8 | WeatherData.sv \ 9 | CurrentConditionsDisplay.sv \ 10 | StatisticsDisplay.sv \ 11 | ForecastDisplay.sv \ 12 | WeatherStation.sv 13 | 14 | vsim -c tb -do "run -all" 15 | -------------------------------------------------------------------------------- /observer/example/run_synopsys.sh: -------------------------------------------------------------------------------- 1 | rm -rf simv* csrc simv.daidir 2 | 3 | vcs \ 4 | -sverilog \ 5 | -timescale="1ns/1ns" \ 6 | DisplayElement.sv \ 7 | Observer.sv \ 8 | Subject.sv \ 9 | WeatherData.sv \ 10 | CurrentConditionsDisplay.sv \ 11 | StatisticsDisplay.sv \ 12 | ForecastDisplay.sv \ 13 | WeatherStation.sv 14 | 15 | simv +ntb_random_seed_automatic 16 | -------------------------------------------------------------------------------- /singleton/example/classic/Singleton.sv: -------------------------------------------------------------------------------- 1 | package classic; 2 | // NOTE: This is not thread safe! 3 | 4 | class Singleton; 5 | local static Singleton uniqueInstance; 6 | 7 | local function new(); 8 | endfunction 9 | 10 | // static here 11 | static function Singleton getInstance(); 12 | if (uniqueInstance == null) begin 13 | uniqueInstance = new(); 14 | $display("making new!"); 15 | end 16 | return uniqueInstance; 17 | endfunction 18 | 19 | function string getDescription(); 20 | $display("I'm a classic Singleton!"); 21 | endfunction 22 | 23 | endclass 24 | 25 | endpackage 26 | 27 | module top; 28 | 29 | import classic::*; 30 | Singleton singleton; 31 | 32 | initial begin 33 | $display("HELLO"); 34 | 35 | // Error-[SV-ICMA] Illegal class method access 36 | // Singleton.sv, 41 37 | // Local method 'new' of class 'Singleton' is not visible to scope 'top'. 38 | // Please make sure that the above method is called only from its own class 39 | // properties as it is declared as local. 40 | // singleton = new(); 41 | // GREAT ERROR - WORKS GREAT 42 | 43 | // running from this fork 44 | // this twice shows the "making new" message only showed up once! yes 45 | fork 46 | singleton = Singleton::getInstance(); 47 | singleton = Singleton::getInstance(); 48 | singleton = Singleton::getInstance(); 49 | singleton = Singleton::getInstance(); 50 | singleton = Singleton::getInstance(); 51 | singleton = Singleton::getInstance(); 52 | singleton = Singleton::getInstance(); 53 | singleton = Singleton::getInstance(); 54 | join 55 | singleton.getDescription(); 56 | #1; 57 | $finish(); 58 | end 59 | 60 | endmodule 61 | 62 | -------------------------------------------------------------------------------- /singleton/example/classic/output: -------------------------------------------------------------------------------- 1 | HELLO 2 | making new! 3 | I'm a classic Singleton! 4 | -------------------------------------------------------------------------------- /singleton/example/classic/run_cadence.sh: -------------------------------------------------------------------------------- 1 | irun \ 2 | -clean \ 3 | -access rw \ 4 | -svseed random \ 5 | Singleton.sv 6 | 7 | # +define+PREFERRED \ 8 | -------------------------------------------------------------------------------- /singleton/example/classic/run_mentor.sh: -------------------------------------------------------------------------------- 1 | rm -rf work 2 | vlib work 3 | 4 | vlog -sv -pedanticerrors \ 5 | Singleton.sv 6 | # +define+PREFERRED \ 7 | 8 | vsim -c top -do "run -all" -sv_seed random -solvefaildebug 9 | # -solveverbose 10 | -------------------------------------------------------------------------------- /singleton/example/classic/run_synopsys.sh: -------------------------------------------------------------------------------- 1 | rm -rf simv* csrc simv.daidir 2 | 3 | vcs \ 4 | -sverilog \ 5 | -timescale="1ns/1ns" \ 6 | Singleton.sv 7 | 8 | simv +ntb_random_seed_automatic 9 | -------------------------------------------------------------------------------- /singleton/example/threadsafe/Singleton.sv: -------------------------------------------------------------------------------- 1 | package classic; 2 | // NOTE: This is not thread safe! 3 | 4 | class Singleton; 5 | local static Singleton uniqueInstance; 6 | local static semaphore synchronized = new(1); 7 | 8 | local function new(); 9 | endfunction 10 | 11 | // static here 12 | static function Singleton getInstance(); 13 | if (uniqueInstance == null) begin 14 | while (!synchronized.try_get()) begin; 15 | $display("SOMEONE GOT THE SEMAPHORE"); 16 | if (uniqueInstance == null) begin 17 | uniqueInstance = new(); 18 | $display("making new!"); 19 | synchronized.put(); 20 | $display("SOMEONE RETURNED THE SEMAPHORE"); 21 | break; 22 | end 23 | end 24 | end 25 | return uniqueInstance; 26 | endfunction 27 | 28 | function string getDescription(); 29 | $display("I'm a classic Singleton!"); 30 | endfunction 31 | 32 | endclass 33 | 34 | endpackage 35 | 36 | module top; 37 | 38 | import classic::*; 39 | Singleton singleton; 40 | 41 | initial begin 42 | $display("HELLO"); 43 | 44 | // Error-[SV-ICMA] Illegal class method access 45 | // Singleton.sv, 41 46 | // Local method 'new' of class 'Singleton' is not visible to scope 'top'. 47 | // Please make sure that the above method is called only from its own class 48 | // properties as it is declared as local. 49 | // singleton = new(); 50 | // GREAT ERROR - WORKS GREAT 51 | 52 | // running from this fork 53 | // this twice shows the "making new" message only showed up once! yes 54 | fork 55 | singleton = Singleton::getInstance(); 56 | singleton = Singleton::getInstance(); 57 | singleton = Singleton::getInstance(); 58 | singleton = Singleton::getInstance(); 59 | singleton = Singleton::getInstance(); 60 | singleton = Singleton::getInstance(); 61 | singleton = Singleton::getInstance(); 62 | singleton = Singleton::getInstance(); 63 | join 64 | singleton.getDescription(); 65 | #1; 66 | $finish(); 67 | end 68 | 69 | endmodule 70 | 71 | -------------------------------------------------------------------------------- /singleton/example/threadsafe/output: -------------------------------------------------------------------------------- 1 | HELLO 2 | SOMEONE GOT THE SEMAPHORE 3 | making new! 4 | SOMEONE RETURNED THE SEMAPHORE 5 | I'm a classic Singleton! 6 | -------------------------------------------------------------------------------- /singleton/example/threadsafe/run_cadence.sh: -------------------------------------------------------------------------------- 1 | irun \ 2 | -clean \ 3 | -access rw \ 4 | -svseed random \ 5 | Singleton.sv 6 | 7 | # +define+PREFERRED \ 8 | -------------------------------------------------------------------------------- /singleton/example/threadsafe/run_mentor.sh: -------------------------------------------------------------------------------- 1 | rm -rf work 2 | vlib work 3 | 4 | vlog -sv -pedanticerrors \ 5 | Singleton.sv 6 | # +define+PREFERRED \ 7 | 8 | vsim -c top -do "run -all" -sv_seed random -solvefaildebug 9 | # -solveverbose 10 | -------------------------------------------------------------------------------- /singleton/example/threadsafe/run_synopsys.sh: -------------------------------------------------------------------------------- 1 | rm -rf simv* csrc simv.daidir 2 | 3 | vcs \ 4 | -sverilog \ 5 | -timescale="1ns/1ns" \ 6 | Singleton.sv 7 | 8 | simv +ntb_random_seed_automatic 9 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/GumballMachine.sv: -------------------------------------------------------------------------------- 1 | class GumballMachine; 2 | 3 | // TODO THIS IS NOT NEEDED WITH ::new syntax 4 | SoldOutState sOS; 5 | NoQuarterState nQS; 6 | HasQuarterState hQS; 7 | SoldState sS; 8 | WinnerState wS; 9 | 10 | State soldOutState; 11 | State noQuarterState; 12 | State hasQuarterState; 13 | State soldState; 14 | State winnerState; 15 | 16 | // State state = soldOutState; 17 | State state; 18 | 19 | int count = 0; 20 | 21 | function new(int numberGumballs); 22 | // Error-[SV-IIOIC] Illegal instantiation of interface class 23 | // GumballMachine.sv, 15 24 | // gumballstatewinner, "this.soldOutState = new();" 25 | // Instantiation of the object 'soldOutState' can not be done because its type 26 | // 'State' is an interface class. 27 | // Like abstract classes, an object of an interface class type shall not be 28 | // constructed. 29 | 30 | // this is valid syntax but doesn't work in VCS? would make the below much shorter 31 | // OPENED SYNOPSYS CASE: 8000857354 32 | // State s = SoldOutState::new(this); 33 | 34 | sOS = new(this); 35 | nQS = new(this); 36 | hQS = new(this); 37 | sS = new(this); 38 | wS = new(this); 39 | 40 | soldOutState = sOS; 41 | noQuarterState = nQS; 42 | hasQuarterState = hQS; 43 | soldState = sS; 44 | winnerState = wS; 45 | 46 | this.count = numberGumballs; 47 | if (numberGumballs > 0) begin 48 | state = noQuarterState; 49 | end 50 | endfunction 51 | 52 | function void insertQuarter(); 53 | state.insertQuarter(); 54 | endfunction 55 | 56 | function void ejectQuarter(); 57 | state.ejectQuarter(); 58 | endfunction 59 | 60 | function void turnCrank(); 61 | state.turnCrank(); 62 | state.dispense(); 63 | endfunction 64 | 65 | function void setState(State state); 66 | this.state = state; 67 | endfunction 68 | 69 | function void releaseBall(); 70 | $display("A gumball comes rolling out the slot..."); 71 | if (count != 0) begin 72 | count = count - 1; 73 | end 74 | endfunction 75 | 76 | function int getCount(); 77 | return count; 78 | endfunction 79 | 80 | function void refill(int count); 81 | this.count += count; 82 | $display("The gumball machine was just refilled; it's new count is: %d", this.count); 83 | state.refill(); 84 | endfunction 85 | 86 | function State getState(); 87 | return state; 88 | endfunction 89 | 90 | function State getSoldOutState(); 91 | return soldOutState; 92 | endfunction 93 | 94 | function State getNoQuarterState(); 95 | return noQuarterState; 96 | endfunction 97 | 98 | function State getHasQuarterState(); 99 | return hasQuarterState; 100 | endfunction 101 | 102 | function State getSoldState(); 103 | return soldState; 104 | endfunction 105 | 106 | function State getWinnerState(); 107 | return winnerState; 108 | endfunction 109 | 110 | function string toString(); 111 | string result = ""; 112 | string t; 113 | 114 | result = {result, "\nMighty Gumball, Inc."}; 115 | result = {result, "\nJava-enabled Standing Gumball Model #2004"}; 116 | t.itoa(count); 117 | result = {result, "\nInventory: ", t, " gumball"}; 118 | if (count != 1) begin 119 | result = {result, "s"}; 120 | end 121 | result = {result, "\n"}; 122 | t = state.toString(); 123 | result = {result, "Machine is ", t, "\n"}; 124 | return result; 125 | endfunction 126 | endclass 127 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/GumballMachineTestDrive.sv: -------------------------------------------------------------------------------- 1 | package gumballstatewinner; 2 | // TODO had to declare these classes early 3 | typedef class SoldOutState; 4 | typedef class NoQuarterState; 5 | typedef class HasQuarterState; 6 | typedef class SoldState; 7 | typedef class WinnerState; 8 | 9 | `include "State.sv" 10 | `include "GumballMachine.sv" 11 | `include "HasQuarterState.sv" 12 | `include "NoQuarterState.sv" 13 | `include "WinnerState.sv" 14 | `include "SoldOutState.sv" 15 | `include "SoldState.sv" 16 | endpackage 17 | 18 | module top; 19 | 20 | import gumballstatewinner::*; 21 | GumballMachine gumballMachine; 22 | 23 | initial begin 24 | $display("HELLO"); 25 | 26 | gumballMachine = new(10); 27 | 28 | $display(gumballMachine.toString()); 29 | 30 | gumballMachine.insertQuarter(); 31 | gumballMachine.turnCrank(); 32 | gumballMachine.insertQuarter(); 33 | gumballMachine.turnCrank(); 34 | 35 | $display(gumballMachine.toString()); 36 | gumballMachine.insertQuarter(); 37 | gumballMachine.turnCrank(); 38 | gumballMachine.insertQuarter(); 39 | gumballMachine.turnCrank(); 40 | 41 | $display(gumballMachine.toString()); 42 | gumballMachine.insertQuarter(); 43 | gumballMachine.turnCrank(); 44 | gumballMachine.insertQuarter(); 45 | gumballMachine.turnCrank(); 46 | 47 | $display(gumballMachine.toString()); 48 | gumballMachine.insertQuarter(); 49 | gumballMachine.turnCrank(); 50 | gumballMachine.insertQuarter(); 51 | gumballMachine.turnCrank(); 52 | 53 | $display(gumballMachine.toString()); 54 | gumballMachine.insertQuarter(); 55 | gumballMachine.turnCrank(); 56 | gumballMachine.insertQuarter(); 57 | gumballMachine.turnCrank(); 58 | 59 | $display(gumballMachine.toString()); 60 | 61 | #1; 62 | $finish(); 63 | end 64 | 65 | endmodule 66 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/HasQuarterState.sv: -------------------------------------------------------------------------------- 1 | class HasQuarterState implements State; 2 | GumballMachine gumballMachine; 3 | 4 | function new(GumballMachine gumballMachine); 5 | this.gumballMachine = gumballMachine; 6 | endfunction 7 | 8 | virtual function void insertQuarter(); 9 | $display("You can't insert another quarter"); 10 | endfunction 11 | 12 | virtual function void ejectQuarter(); 13 | $display("Quarter returned"); 14 | gumballMachine.setState(gumballMachine.getNoQuarterState()); 15 | endfunction 16 | 17 | virtual function void turnCrank(); 18 | int winner; 19 | $display("You turned..."); 20 | winner = $urandom % 10; 21 | if ((winner == 0) && (gumballMachine.getCount() > 1)) begin 22 | gumballMachine.setState(gumballMachine.getWinnerState()); 23 | end else begin 24 | gumballMachine.setState(gumballMachine.getSoldState()); 25 | end 26 | endfunction 27 | 28 | virtual function void dispense(); 29 | $display("No gumball dispensed"); 30 | endfunction 31 | 32 | virtual function void refill(); 33 | endfunction 34 | 35 | virtual function string toString(); 36 | return "waiting for turn of crank"; 37 | endfunction 38 | 39 | endclass 40 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/NoQuarterState.sv: -------------------------------------------------------------------------------- 1 | class NoQuarterState implements State; 2 | GumballMachine gumballMachine; 3 | 4 | function new(GumballMachine gumballMachine); 5 | this.gumballMachine = gumballMachine; 6 | endfunction 7 | 8 | virtual function void insertQuarter(); 9 | $display("You inserted a quarter"); 10 | gumballMachine.setState(gumballMachine.getHasQuarterState()); 11 | endfunction 12 | 13 | virtual function void ejectQuarter(); 14 | $display("You haven't inserted a quarter"); 15 | endfunction 16 | 17 | virtual function void turnCrank(); 18 | $display("You turned, but there's no quarter"); 19 | endfunction 20 | 21 | virtual function void dispense(); 22 | $display("You need to pay first"); 23 | endfunction 24 | 25 | virtual function void refill(); 26 | endfunction 27 | 28 | virtual function string toString(); 29 | return "waiting for quarter"; 30 | endfunction 31 | 32 | endclass 33 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/SoldOutState.sv: -------------------------------------------------------------------------------- 1 | class SoldOutState implements State; 2 | GumballMachine gumballMachine; 3 | 4 | function new(GumballMachine gumballMachine); 5 | this.gumballMachine = gumballMachine; 6 | endfunction 7 | 8 | virtual function void insertQuarter(); 9 | $display("You can't insert a quarter, the machine is sold out"); 10 | endfunction 11 | 12 | virtual function void ejectQuarter(); 13 | $display("You can't eject, you haven't inserted a quarter yet"); 14 | endfunction 15 | 16 | virtual function void turnCrank(); 17 | $display("You turned, but there are no gumballs"); 18 | endfunction 19 | 20 | virtual function void dispense(); 21 | $display("No gumball dispensed"); 22 | endfunction 23 | 24 | virtual function void refill(); 25 | gumballMachine.setState(gumballMachine.getNoQuarterState()); 26 | endfunction 27 | 28 | virtual function string toString(); 29 | return "sold out"; 30 | endfunction 31 | endclass 32 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/SoldState.sv: -------------------------------------------------------------------------------- 1 | class SoldState implements State; 2 | GumballMachine gumballMachine; 3 | 4 | function new(GumballMachine gumballMachine); 5 | this.gumballMachine = gumballMachine; 6 | endfunction 7 | 8 | virtual function void insertQuarter(); 9 | $display("Please wait, we're already giving you a gumball"); 10 | endfunction 11 | 12 | virtual function void ejectQuarter(); 13 | $display("Sorry, you already turned the crank"); 14 | endfunction 15 | 16 | virtual function void turnCrank(); 17 | $display("Turning twice doesn't get you another gumball!"); 18 | endfunction 19 | 20 | virtual function void dispense(); 21 | gumballMachine.releaseBall(); 22 | if (gumballMachine.getCount() > 0) begin 23 | gumballMachine.setState(gumballMachine.getNoQuarterState()); 24 | end else begin 25 | $display("Oops, out of gumballs!"); 26 | gumballMachine.setState(gumballMachine.getSoldOutState()); 27 | end 28 | endfunction 29 | 30 | virtual function void refill(); 31 | endfunction 32 | 33 | virtual function string toString(); 34 | return "dispensing a gumball"; 35 | endfunction 36 | 37 | endclass 38 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/State.sv: -------------------------------------------------------------------------------- 1 | interface class State; 2 | // TODO CANT DO THIS 3 | // pure virtual function new(GumballMachine gumballMachine); 4 | pure virtual function void insertQuarter(); 5 | pure virtual function void ejectQuarter(); 6 | pure virtual function void turnCrank(); 7 | pure virtual function void dispense(); 8 | pure virtual function void refill(); 9 | // TODO ADDED THIS 10 | pure virtual function string toString(); 11 | endclass 12 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/WinnerState.sv: -------------------------------------------------------------------------------- 1 | class WinnerState implements State; 2 | GumballMachine gumballMachine; 3 | 4 | function new(GumballMachine gumballMachine); 5 | this.gumballMachine = gumballMachine; 6 | endfunction 7 | 8 | virtual function void insertQuarter(); 9 | $display("Please wait, we're already giving you a Gumball"); 10 | endfunction 11 | 12 | virtual function void ejectQuarter(); 13 | $display("Please wait, we're already giving you a Gumball"); 14 | endfunction 15 | 16 | virtual function void turnCrank(); 17 | $display("Turning again doesn't get you another gumball!"); 18 | endfunction 19 | 20 | virtual function void dispense(); 21 | gumballMachine.releaseBall(); 22 | if (gumballMachine.getCount() == 0) begin 23 | gumballMachine.setState(gumballMachine.getSoldOutState()); 24 | end else begin 25 | gumballMachine.releaseBall(); 26 | $display("YOU'RE A WINNER! You got two gumballs for your quarter"); 27 | if (gumballMachine.getCount() > 0) begin 28 | gumballMachine.setState(gumballMachine.getNoQuarterState()); 29 | end else begin 30 | $display("Oops, out of gumballs!"); 31 | gumballMachine.setState(gumballMachine.getSoldOutState()); 32 | end 33 | end 34 | endfunction 35 | 36 | virtual function void refill(); 37 | endfunction 38 | 39 | virtual function string toString(); 40 | return "despensing two gumballs for your quarter, because YOU'RE A WINNER!"; 41 | endfunction 42 | 43 | endclass 44 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/output: -------------------------------------------------------------------------------- 1 | HELLO 2 | 3 | Mighty Gumball, Inc. 4 | Java-enabled Standing Gumball Model #2004 5 | Inventory: 10 gumballs 6 | Machine is waiting for quarter 7 | 8 | You inserted a quarter 9 | You turned... 10 | A gumball comes rolling out the slot... 11 | A gumball comes rolling out the slot... 12 | YOU'RE A WINNER! You got two gumballs for your quarter 13 | You inserted a quarter 14 | You turned... 15 | A gumball comes rolling out the slot... 16 | 17 | Mighty Gumball, Inc. 18 | Java-enabled Standing Gumball Model #2004 19 | Inventory: 7 gumballs 20 | Machine is waiting for quarter 21 | 22 | You inserted a quarter 23 | You turned... 24 | A gumball comes rolling out the slot... 25 | You inserted a quarter 26 | You turned... 27 | A gumball comes rolling out the slot... 28 | 29 | Mighty Gumball, Inc. 30 | Java-enabled Standing Gumball Model #2004 31 | Inventory: 5 gumballs 32 | Machine is waiting for quarter 33 | 34 | You inserted a quarter 35 | You turned... 36 | A gumball comes rolling out the slot... 37 | You inserted a quarter 38 | You turned... 39 | A gumball comes rolling out the slot... 40 | 41 | Mighty Gumball, Inc. 42 | Java-enabled Standing Gumball Model #2004 43 | Inventory: 3 gumballs 44 | Machine is waiting for quarter 45 | 46 | You inserted a quarter 47 | You turned... 48 | A gumball comes rolling out the slot... 49 | You inserted a quarter 50 | You turned... 51 | A gumball comes rolling out the slot... 52 | 53 | Mighty Gumball, Inc. 54 | Java-enabled Standing Gumball Model #2004 55 | Inventory: 1 gumball 56 | Machine is waiting for quarter 57 | 58 | You inserted a quarter 59 | You turned... 60 | A gumball comes rolling out the slot... 61 | Oops, out of gumballs! 62 | You can't insert a quarter, the machine is sold out 63 | You turned, but there are no gumballs 64 | No gumball dispensed 65 | 66 | Mighty Gumball, Inc. 67 | Java-enabled Standing Gumball Model #2004 68 | Inventory: 0 gumballs 69 | Machine is sold out 70 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/run_cadence.sh: -------------------------------------------------------------------------------- 1 | irun \ 2 | -clean \ 3 | -access rw \ 4 | -svseed random \ 5 | GumballMachineTestDrive.sv 6 | 7 | echo "Cadence cannot handle interface classes at this time" 8 | 9 | # +define+PREFERRED \ 10 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/run_mentor.sh: -------------------------------------------------------------------------------- 1 | rm -rf work 2 | vlib work 3 | 4 | vlog -sv -pedanticerrors \ 5 | +define+PREFERRED \ 6 | GumballMachineTestDrive.sv 7 | 8 | vsim -c top -do "run -all" -sv_seed random -solvefaildebug 9 | # -solveverbose 10 | -------------------------------------------------------------------------------- /state/example/gumballstatewinner/run_synopsys.sh: -------------------------------------------------------------------------------- 1 | rm -rf simv* csrc simv.daidir 2 | 3 | vcs \ 4 | -sverilog \ 5 | -timescale="1ns/1ns" \ 6 | GumballMachineTestDrive.sv 7 | 8 | simv +ntb_random_seed_automatic 9 | -------------------------------------------------------------------------------- /strategypattern/application/dut.sv: -------------------------------------------------------------------------------- 1 | package packet; 2 | 3 | class Fields; 4 | rand logic [3:0] addr; 5 | rand logic [3:0] data; 6 | rand logic [2:0] cmd; 7 | rand logic reserved; 8 | endclass 9 | 10 | class Fields_V3 extends Fields; 11 | rand logic [4:0] addr; 12 | endclass 13 | 14 | interface class PackBehavior#(type F = Fields); 15 | pure virtual function logic [13:0] pack(F f); 16 | pure virtual function F unpack(logic [13:0] raw); 17 | endclass 18 | 19 | interface class CheckBehavior; 20 | pure virtual function logic [13:0] pack(logic [13:0] raw); 21 | pure virtual function bit unpack(logic [13:0] raw); 22 | endclass 23 | 24 | class Parity implements CheckBehavior; 25 | virtual function logic [13:0] pack(logic [13:0] raw); 26 | logic [13:0] a; 27 | a[13:12] = 2'b00; 28 | a[11:0] = raw[11:0]; 29 | return a; 30 | endfunction 31 | 32 | virtual function bit unpack(logic [13:0] raw); 33 | return 1; 34 | endfunction 35 | endclass 36 | 37 | class Crc implements CheckBehavior; 38 | virtual function logic [13:0] pack(logic [13:0] raw); 39 | logic [13:0] a; 40 | a[13:12] = 2'b10; 41 | a[11:0] = raw[11:0]; 42 | return a; 43 | endfunction 44 | 45 | virtual function bit unpack(logic [13:0] raw); 46 | return 1; 47 | endfunction 48 | endclass 49 | 50 | 51 | class base_packet#( 52 | type TPackBehavior = PackBehavior, 53 | type F = Fields 54 | ); 55 | 56 | rand F fields; 57 | TPackBehavior packBehavior; 58 | CheckBehavior checkBehavior; 59 | 60 | function new(); 61 | fields = new; 62 | endfunction 63 | 64 | function bit performUnpack(logic [13:0] raw); 65 | fields = packBehavior.unpack(raw); 66 | return checkBehavior.unpack(raw); 67 | endfunction 68 | 69 | function logic [13:0] performPack(); 70 | return checkBehavior.pack((packBehavior.pack(fields))); 71 | endfunction 72 | 73 | function void print(); 74 | $display(" unpacked addr=%b data=%b cmd=%b", this.fields.addr, this.fields.data, this.fields.cmd); 75 | endfunction 76 | 77 | function void setPackBehavior(TPackBehavior pb); 78 | packBehavior = pb; 79 | endfunction 80 | 81 | function void setCheckBehavior(CheckBehavior cb); 82 | checkBehavior = cb; 83 | endfunction 84 | 85 | endclass 86 | 87 | class v1_pack implements PackBehavior; 88 | virtual function logic [13:0] pack(Fields f); 89 | logic [13:0] a; 90 | a[13:12] = 2'bxx; 91 | a[11] = f.reserved; 92 | a[10:7] = f.addr; 93 | a[6:3] = f.data; 94 | a[2:0] = f.cmd; 95 | return a; 96 | endfunction 97 | 98 | virtual function Fields unpack(logic [13:0] raw); 99 | Fields fields = new; 100 | fields.reserved = raw[11]; 101 | fields.addr = raw[10:7]; 102 | fields.data = raw[6:3]; 103 | fields.cmd = raw[2:0]; 104 | return fields; 105 | 106 | endfunction 107 | endclass 108 | 109 | class v1_packet extends base_packet; 110 | 111 | function new(); 112 | v1_pack p = new(); 113 | Crc c = new(); 114 | 115 | setPackBehavior(p); 116 | setCheckBehavior(c); 117 | endfunction 118 | endclass 119 | 120 | class v2_pack implements PackBehavior; 121 | virtual function logic [13:0] pack(Fields f); 122 | logic [13:0] a; 123 | a[11] = f.reserved; 124 | a[10:7] = f.data; 125 | a[6:3] = f.addr; 126 | a[2:0] = f.cmd; 127 | return a; 128 | endfunction 129 | 130 | virtual function Fields unpack(logic [13:0] raw); 131 | Fields fields = new; 132 | fields.reserved = raw[11]; 133 | fields.data = raw[10:7]; 134 | fields.addr = raw[6:3]; 135 | fields.cmd = raw[2:0]; 136 | return fields; 137 | endfunction 138 | 139 | endclass 140 | 141 | class v2_packet extends base_packet; 142 | 143 | function new(); 144 | v2_pack p = new(); 145 | Parity c = new(); 146 | 147 | setPackBehavior(p); 148 | setCheckBehavior(c); 149 | endfunction 150 | endclass 151 | 152 | class v3_pack implements PackBehavior#(.F(Fields_V3)); 153 | virtual function logic [13:0] pack(Fields_V3 f); 154 | logic [13:0] a; 155 | a[13:12] = 2'bxx; 156 | a[11:8] = f.data; 157 | a[7:3] = f.addr; 158 | a[2:0] = f.cmd; 159 | return a; 160 | endfunction 161 | 162 | virtual function Fields_V3 unpack(logic [13:0] raw); 163 | Fields_V3 fields = new; 164 | 165 | fields.data = raw[11:8]; 166 | fields.addr = raw[7:3]; 167 | fields.cmd = raw[2:0]; 168 | return fields; 169 | 170 | endfunction 171 | 172 | endclass 173 | 174 | class v3_packet extends base_packet#( 175 | .TPackBehavior(PackBehavior#(.F(Fields_V3))), 176 | .F(Fields_V3) 177 | ); 178 | 179 | function new(); 180 | v3_pack p = new(); 181 | Crc c = new(); 182 | setPackBehavior(p); 183 | setCheckBehavior(c); 184 | endfunction 185 | endclass 186 | 187 | endpackage 188 | 189 | module top; 190 | 191 | initial begin 192 | 193 | `ifdef PREFERRED 194 | 195 | automatic packet::v1_packet v1p = new(); 196 | automatic packet::v2_packet v2p = new(); 197 | automatic packet::v3_packet v3p = new(); 198 | 199 | $display("RUNNING PREFERRED"); 200 | 201 | $display(""); 202 | $display("STARTING V1"); 203 | void'(v1p.performUnpack(14'b00_0_0101_1111_010)); 204 | v1p.print(); 205 | v1p.fields.addr = 0; 206 | v1p.print(); 207 | $display(" packed=%b", v1p.performPack()); 208 | // can be randomized like the below 209 | // v1p.randomize(); 210 | // v1p.print(); 211 | 212 | $display(""); 213 | $display("STARTING V2"); 214 | void'(v2p.performUnpack(14'b00_0_0101_1111_010)); 215 | v2p.print(); 216 | v2p.fields.addr = 0; 217 | v2p.print(); 218 | $display(" packed=%b", v2p.performPack()); 219 | 220 | $display(""); 221 | $display("STARTING V3"); 222 | void'(v3p.performUnpack(14'b00_1111_11111_110)); 223 | v3p.print(); 224 | v3p.fields.addr = 0; 225 | v3p.print(); 226 | $display(" packed=%b", v3p.performPack()); 227 | 228 | `else 229 | 230 | `endif 231 | 232 | #1; 233 | $finish(); 234 | end 235 | 236 | endmodule 237 | -------------------------------------------------------------------------------- /strategypattern/application/output: -------------------------------------------------------------------------------- 1 | RUNNING PREFERRED 2 | 3 | STARTING V1 4 | unpacked addr=0101 data=1111 cmd=010 5 | unpacked addr=0000 data=1111 cmd=010 6 | packed=10000001111010 7 | 8 | STARTING V2 9 | unpacked addr=1111 data=0101 cmd=010 10 | unpacked addr=0000 data=0101 cmd=010 11 | packed=00001010000010 12 | 13 | STARTING V3 14 | unpacked addr=11111 data=1111 cmd=110 15 | unpacked addr=00000 data=1111 cmd=110 16 | packed=10111100000110 17 | -------------------------------------------------------------------------------- /strategypattern/application/run_cadence.sh: -------------------------------------------------------------------------------- 1 | irun \ 2 | -clean \ 3 | -access rw \ 4 | -svseed random \ 5 | dut.sv 6 | 7 | echo "Cadence cannot use interface classes at this time" 8 | -------------------------------------------------------------------------------- /strategypattern/application/run_mentor.sh: -------------------------------------------------------------------------------- 1 | rm -rf work 2 | vlib work 3 | 4 | vlog -sv -pedanticerrors \ 5 | +define+PREFERRED \ 6 | dut.sv 7 | 8 | vsim -c top -do "run -all" -sv_seed random -solvefaildebug 9 | 10 | # -solveverbose 11 | -------------------------------------------------------------------------------- /strategypattern/application/run_synopsys.sh: -------------------------------------------------------------------------------- 1 | rm -rf simv* csrc simv.daidir 2 | 3 | vcs \ 4 | -sverilog \ 5 | -timescale="1ns/1ns" \ 6 | +define+PREFERRED \ 7 | dut.sv 8 | 9 | simv +ntb_random_seed_automatic 10 | -------------------------------------------------------------------------------- /strategypattern/example/DecoyDuck.sv: -------------------------------------------------------------------------------- 1 | class DecoyDuck extends Duck; 2 | function new(); 3 | FlyNoWay f = new(); 4 | MuteQuack q = new(); 5 | setFlyBehavior(f); 6 | setQuackBehavior(q); 7 | endfunction // DecoyDuck 8 | 9 | virtual function void display(); 10 | $display("I'm a duck Decoy"); 11 | endfunction // display 12 | 13 | endclass // DecoyDuck 14 | -------------------------------------------------------------------------------- /strategypattern/example/Duck.sv: -------------------------------------------------------------------------------- 1 | virtual class Duck; 2 | FlyBehavior flyBehavior; 3 | QuackBehavior quackBehavior; 4 | 5 | function void setFlyBehavior(FlyBehavior fb); 6 | flyBehavior = fb; 7 | endfunction // setFlyBehavior 8 | 9 | function void setQuackBehavior(QuackBehavior qb); 10 | quackBehavior = qb; 11 | endfunction // setQuackBehavior 12 | 13 | virtual function void display(); 14 | endfunction // display 15 | 16 | function void performFly(); 17 | flyBehavior.fly(); 18 | endfunction // performFly 19 | 20 | function void performQuack(); 21 | quackBehavior.quack(); 22 | endfunction // performQuack 23 | 24 | function void swim(); 25 | $display("All ducks float, even decoys!"); 26 | endfunction // swim 27 | 28 | endclass // Duck 29 | -------------------------------------------------------------------------------- /strategypattern/example/FlyBehavior.sv: -------------------------------------------------------------------------------- 1 | interface class FlyBehavior; 2 | pure virtual function void fly(); 3 | endclass // FlyBehavior 4 | 5 | -------------------------------------------------------------------------------- /strategypattern/example/FlyNoWay.sv: -------------------------------------------------------------------------------- 1 | class FlyNoWay implements FlyBehavior; 2 | virtual function void fly(); 3 | $display("I can't fly"); 4 | endfunction // fly 5 | endclass // FlyNoWay 6 | -------------------------------------------------------------------------------- /strategypattern/example/FlyWithWings.sv: -------------------------------------------------------------------------------- 1 | class FlyWithWings implements FlyBehavior; 2 | virtual function void fly(); 3 | $display("I'm flying"); 4 | endfunction // fly 5 | endclass // FlyWithWings 6 | -------------------------------------------------------------------------------- /strategypattern/example/MallardDuck.sv: -------------------------------------------------------------------------------- 1 | class MallardDuck extends Duck; 2 | function new(); 3 | FlyWithWings f = new(); 4 | Quack q = new(); 5 | setFlyBehavior(f); 6 | setQuackBehavior(q); 7 | endfunction 8 | 9 | virtual function void display(); 10 | $display("I'm a real Mallard duck"); 11 | endfunction // display 12 | 13 | endclass // MallardDuck 14 | -------------------------------------------------------------------------------- /strategypattern/example/MiniDuckSimulator.sv: -------------------------------------------------------------------------------- 1 | class MiniDuckSimulator; 2 | static function void main(); 3 | MallardDuck mallard = new(); 4 | RubberDuck rubberDuckie = new(); 5 | DecoyDuck decoy = new(); 6 | ModelDuck model = new(); 7 | 8 | $display("\nmallard:"); 9 | mallard.display(); 10 | mallard.performFly(); 11 | mallard.performQuack(); 12 | $display("\ndecoy:"); 13 | decoy.display(); 14 | decoy.performFly(); 15 | decoy.performQuack(); 16 | $display("\nrubberDuckie:"); 17 | rubberDuckie.display(); 18 | rubberDuckie.performFly(); 19 | rubberDuckie.performQuack(); 20 | $display("\nmodel:"); 21 | model.display(); 22 | model.performFly(); 23 | model.performQuack(); 24 | 25 | endfunction // main 26 | endclass // MiniDuckSimulator 27 | 28 | module top; 29 | MiniDuckSimulator mds; 30 | 31 | initial begin 32 | mds = new(); 33 | mds.main(); 34 | #1; 35 | $finish(); 36 | end 37 | 38 | endmodule // tb 39 | -------------------------------------------------------------------------------- /strategypattern/example/ModelDuck.sv: -------------------------------------------------------------------------------- 1 | class ModelDuck extends Duck; 2 | function new(); 3 | FlyNoWay f = new(); 4 | Quack q = new(); 5 | setFlyBehavior(f); 6 | setQuackBehavior(q); 7 | endfunction 8 | 9 | virtual function void display(); 10 | $display("I'm a model duck"); 11 | endfunction // display 12 | 13 | endclass // ModelDuck 14 | -------------------------------------------------------------------------------- /strategypattern/example/MuteQuack.sv: -------------------------------------------------------------------------------- 1 | class MuteQuack implements QuackBehavior; 2 | virtual function void quack(); 3 | $display("<< Silence >>"); 4 | endfunction // quack 5 | endclass // MuteQuack 6 | -------------------------------------------------------------------------------- /strategypattern/example/Quack.sv: -------------------------------------------------------------------------------- 1 | class Quack implements QuackBehavior; 2 | virtual function void quack(); 3 | $display("Quack"); 4 | endfunction // quack 5 | endclass // Quack 6 | -------------------------------------------------------------------------------- /strategypattern/example/QuackBehavior.sv: -------------------------------------------------------------------------------- 1 | interface class QuackBehavior; 2 | pure virtual function void quack(); 3 | endclass // interface 4 | 5 | -------------------------------------------------------------------------------- /strategypattern/example/README.md: -------------------------------------------------------------------------------- 1 | ## Strategy Pattern implemented in SystemVerilog Example 2 | 3 | See the URL for more 4 | 5 | 6 | There is a wonderful tutorial on Lynda.com on Design Patterns. 7 | 8 | [Foundations of Programming: Design Patterns] 9 | (http://www.lynda.com/Developer-Programming-Foundations-tutorials/Foundations-Programming-Design-Patterns/135365-2.html) 10 | by Elisabeth Robson and Eric Freeman 11 | 12 | From that link, you may download the example code of their Design Patterns tutorial from Lynda.com. 13 | 14 | The examples are done in Java and since I am programming in SystemVerilog, this was good opportunity to follow along. The ability to do this in SystemVerilog is only part of the 2012 IEEE specifictaion and is implemented in Mentor Questa 10.3a. 15 | 16 | This my is implementation of their example of the Strategy Pattern from Chapter 2 (CH02). I tried to be as close as possible to the Java implementation to make it easier to follow along. In the main program I do extend it to fully test out all of the functions of the classes used. 17 | 18 | I wrote a short shell script that will run the tutorial code. 19 | 20 | ## Command Lines for Mentor Questa to Run 21 | ```shell 22 | > ./compile.sh 23 | ``` 24 | 25 | The final log for what comes out of the sim is in the file called "log". 26 | 27 | ## Authors 28 | * Original Source by Elisabeth Robson and Eric Freeman 29 | * Translation from Java to SystemVerilog done by Eldon Nelson 30 | -------------------------------------------------------------------------------- /strategypattern/example/RubberDuck.sv: -------------------------------------------------------------------------------- 1 | class RubberDuck extends Duck; 2 | function new(); 3 | FlyNoWay f = new(); 4 | Squeak q = new(); 5 | setFlyBehavior(f); 6 | setQuackBehavior(q); 7 | endfunction 8 | 9 | virtual function void display(); 10 | $display("I'm a rubber duckie"); 11 | endfunction // display 12 | 13 | endclass // RubberDuck 14 | -------------------------------------------------------------------------------- /strategypattern/example/Squeak.sv: -------------------------------------------------------------------------------- 1 | class Squeak implements QuackBehavior; 2 | virtual function void quack(); 3 | $display("Squeak"); 4 | endfunction // quack 5 | endclass // Squeak 6 | -------------------------------------------------------------------------------- /strategypattern/example/compile_vcs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # mfcu is needed! 4 | vcs \ 5 | FlyBehavior.sv \ 6 | FlyWithWings.sv \ 7 | FlyNoWay.sv \ 8 | QuackBehavior.sv \ 9 | Quack.sv \ 10 | MuteQuack.sv \ 11 | Squeak.sv \ 12 | Duck.sv \ 13 | MallardDuck.sv \ 14 | DecoyDuck.sv \ 15 | RubberDuck.sv \ 16 | ModelDuck.sv \ 17 | MiniDuckSimulator.sv 18 | -------------------------------------------------------------------------------- /strategypattern/example/output: -------------------------------------------------------------------------------- 1 | mallard: 2 | I'm a real Mallard duck 3 | I'm flying 4 | Quack 5 | 6 | decoy: 7 | I'm a duck Decoy 8 | I can't fly 9 | << Silence >> 10 | 11 | rubberDuckie: 12 | I'm a rubber duckie 13 | I can't fly 14 | Squeak 15 | 16 | model: 17 | I'm a model duck 18 | I can't fly 19 | Quack 20 | -------------------------------------------------------------------------------- /strategypattern/example/run_cadence.sh: -------------------------------------------------------------------------------- 1 | irun \ 2 | -clean \ 3 | -access rw \ 4 | -svseed random \ 5 | FlyBehavior.sv \ 6 | FlyWithWings.sv \ 7 | FlyNoWay.sv \ 8 | QuackBehavior.sv \ 9 | Quack.sv \ 10 | MuteQuack.sv \ 11 | Squeak.sv \ 12 | Duck.sv \ 13 | MallardDuck.sv \ 14 | DecoyDuck.sv \ 15 | RubberDuck.sv \ 16 | ModelDuck.sv \ 17 | MiniDuckSimulator.sv 18 | 19 | echo "Cadence cannot handle class interface at this time" 20 | 21 | # +define+PREFERRED \ 22 | -------------------------------------------------------------------------------- /strategypattern/example/run_mentor.sh: -------------------------------------------------------------------------------- 1 | rm -rf work 2 | vlib work 3 | 4 | vlog -sv -mfcu -pedanticerrors \ 5 | FlyBehavior.sv \ 6 | FlyWithWings.sv \ 7 | FlyNoWay.sv \ 8 | QuackBehavior.sv \ 9 | Quack.sv \ 10 | MuteQuack.sv \ 11 | Squeak.sv \ 12 | Duck.sv \ 13 | MallardDuck.sv \ 14 | DecoyDuck.sv \ 15 | RubberDuck.sv \ 16 | ModelDuck.sv \ 17 | MiniDuckSimulator.sv 18 | # +define+PREFERRED \ 19 | 20 | vsim -c top -do "run -all" -sv_seed random -solvefaildebug 21 | # -solveverbose 22 | -------------------------------------------------------------------------------- /strategypattern/example/run_synopsys.sh: -------------------------------------------------------------------------------- 1 | rm -rf simv* csrc simv.daidir 2 | 3 | vcs \ 4 | -sverilog \ 5 | -timescale="1ns/1ns" \ 6 | FlyBehavior.sv \ 7 | FlyWithWings.sv \ 8 | FlyNoWay.sv \ 9 | QuackBehavior.sv \ 10 | Quack.sv \ 11 | MuteQuack.sv \ 12 | Squeak.sv \ 13 | Duck.sv \ 14 | MallardDuck.sv \ 15 | DecoyDuck.sv \ 16 | RubberDuck.sv \ 17 | ModelDuck.sv \ 18 | MiniDuckSimulator.sv 19 | 20 | simv +ntb_random_seed_automatic 21 | --------------------------------------------------------------------------------