├── .gitignore ├── chat.rapidgpt ├── solutions ├── lab_pipeline.tlv └── demo_distance.tlv ├── LICENSE.md ├── calculator_shell.tlv ├── student_projects.md ├── risc-v_shell.tlv ├── reference_solutions.tlv ├── README.md └── tlv_lib ├── calculator_shell_lib.tlv └── risc-v_shell_lib.tlv /.gitignore: -------------------------------------------------------------------------------- 1 | *.bak 2 | -------------------------------------------------------------------------------- /chat.rapidgpt: -------------------------------------------------------------------------------- 1 | { 2 | "uuid": "bc68ae6e-c908-446c-84da-3d2ce1f1d55f" 3 | } -------------------------------------------------------------------------------- /solutions/lab_pipeline.tlv: -------------------------------------------------------------------------------- 1 | \m5_TLV_version 1d: tl-x.org 2 | \SV 3 | m5_makerchip_module 4 | \TLV 5 | |comp 6 | @1 7 | $err1 = $bad_input || $illegal_op; 8 | @3 9 | $err2 = $err1 || $over_flow; 10 | @6 11 | $err3 = $err2 || $div_by_zero; 12 | 13 | // Assert these to end simulation (before Makerchip cycle limit). 14 | *passed = *cyc_cnt > 40; 15 | *failed = 1'b0; 16 | \SV 17 | endmodule 18 | -------------------------------------------------------------------------------- /solutions/demo_distance.tlv: -------------------------------------------------------------------------------- 1 | \m4_TLV_version 1d: tl-x.org 2 | \SV 3 | `include "sqrt32.v"; 4 | m4_makerchip_module 5 | \TLV 6 | |calc 7 | @1 8 | $aa_sq[7:0] = $aa[3:0] * $aa; 9 | $bb_sq[7:0] = $bb[3:0] * $bb; 10 | @2 11 | $cc_sq[8:0] = $aa_sq + $bb_sq; 12 | @3 13 | $cc[4:0] = sqrt($cc_sq); 14 | 15 | 16 | ! *passed = *cyc_cnt > 16'd30; 17 | 18 | \SV 19 | endmodule 20 | 21 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /calculator_shell.tlv: -------------------------------------------------------------------------------- 1 | \m4_TLV_version 1d: tl-x.org 2 | \SV 3 | // This code can be found in: https://github.com/stevehoover/RISC-V_MYTH_Workshop 4 | 5 | m4_include_lib(['https://raw.githubusercontent.com/stevehoover/RISC-V_MYTH_Workshop/ecba3769fff373ef6b8f66b3347e8940c859792d/tlv_lib/calculator_shell_lib.tlv']) 6 | 7 | \SV 8 | m4_makerchip_module // (Expanded in Nav-TLV pane.) 9 | 10 | \TLV 11 | |calc 12 | @0 13 | $reset = *reset; 14 | 15 | 16 | // YOUR CODE HERE 17 | // ... 18 | 19 | 20 | // Macro instantiations for calculator visualization(disabled by default). 21 | // Uncomment to enable visualisation, and also, 22 | // NOTE: If visualization is enabled, $op must be defined to the proper width using the expression below. 23 | // (Any signals other than $rand1, $rand2 that are not explicitly assigned will result in strange errors.) 24 | // You can, however, safely use these specific random signals as described in the videos: 25 | // o $rand1[3:0] 26 | // o $rand2[3:0] 27 | // o $op[x:0] 28 | 29 | //m4+cal_viz(@3) // Arg: Pipeline stage represented by viz, should be atleast equal to last stage of CALCULATOR logic. 30 | 31 | 32 | // Assert these to end simulation (before Makerchip cycle limit). 33 | *passed = *cyc_cnt > 40; 34 | *failed = 1'b0; 35 | 36 | 37 | \SV 38 | endmodule 39 | -------------------------------------------------------------------------------- /student_projects.md: -------------------------------------------------------------------------------- 1 | # MYTH RISC-V (RV32I) CPU Cores 2 | 3 | Many students who have taken part in this MYTH Workshop have released their work as open-source cores. These are some good ones: 4 | - [Abhinand Amarnath](https://github.com/abhierao/RISCV_CORE_4_Stage) 5 | - [Amit Roy](https://github.com/AMITROY71/risc-v-myth-workshop-august-AMITROY71) 6 | - [Anurag Sharma](https://github.com/designerguy13-photonics/risc-v-myth-workshop-august-designerguy13-photonics) 7 | - [Ashutosh Sahoo](https://github.com/RISCV-MYTH-WORKSHOP/RISC-V-CPU-Core-using-TL-Verilog) 8 | - [Harinarayan Rajgopal](https://github.com/RISCV-MYTH-WORKSHOP/risc-v-myth-workshop-august-harinarayan18) 9 | - [Manjunathveeraiah Kalmath](https://github.com/ManjunathKalmath/risc-v-myth-workshop) 10 | - [Rohit Kankal](https://github.com/iamrk-vlsi/risc-v-myth-workshop-august-iamrk-vlsi) 11 | - [Shivani Shah](https://github.com/shivanishah269/risc-v-core) 12 | - [Vibhor Singh](https://github.com/vibhor68/risc-v-myth-workshop-august-vibhor68) 13 | - [Kubiran Karakaran](https://github.com/kuby1412/RISC-V-MYTH-Workshop) 14 | - [Mukul Javadekar](https://github.com/RISCV-MYTH-WORKSHOP/risc-v-myth-workshop-august-mukuljava) 15 | - [Joseph Aronson](https://github.com/aronsonj52/riscv_myth_workshop) 16 | - [Akil M.](https://github.com/akilm/MYTH-RV32I-core-akilm) <-- Added support for byte/word loads! 17 | - [Harishwar Reddy](https://github.com/RISCV-MYTH-WORKSHOP/RISC-V-Core) 18 | - [Razvan Ionescu](https://github.com/RISCV-MYTH-WORKSHOP/riscv_myth_workshop_dec20-razvanionescu-77) 19 | - [Karthik K](https://github.com/RISCV-MYTH-WORKSHOP/riscv_myth_workshop_dec20-karthikvnit) 20 | - [Shon Taware](https://github.com/ShonTaware/RISC-V_Core_4_Stage) <-- Added support for compressed instructions (C extension)! 21 | - [Ninad Jangle](https://github.com/ninja3011/riscv-cpu-core) 22 | 23 | These cores are significant in that: 24 | - They were created by students with limited logic design experience in a 5-day Workshop. 25 | - They implement a 4-stage pipelined RV32I in < 200 lines of code. 26 | - They are documented to help others create cores of their own. 27 | 28 | All these cores can be compiled and simulated by cut-n-pasting into the [makerchip.com](makerchip.com) IDE. 29 | 30 | [Workshop info, including slides](https://github.com/stevehoover/RISC-V_MYTH_Workshop). 31 | -------------------------------------------------------------------------------- /risc-v_shell.tlv: -------------------------------------------------------------------------------- 1 | \m4_TLV_version 1d: tl-x.org 2 | \SV 3 | // This code can be found in: https://github.com/stevehoover/RISC-V_MYTH_Workshop 4 | 5 | m4_include_lib(['https://raw.githubusercontent.com/BalaDhinesh/RISC-V_MYTH_Workshop/master/tlv_lib/risc-v_shell_lib.tlv']) 6 | 7 | \SV 8 | m4_makerchip_module // (Expanded in Nav-TLV pane.) 9 | \TLV 10 | 11 | // /====================\ 12 | // | Sum 1 to 9 Program | 13 | // \====================/ 14 | // 15 | // Program for MYTH Workshop to test RV32I 16 | // Add 1,2,3,...,9 (in that order). 17 | // 18 | // Regs: 19 | // r10 (a0): In: 0, Out: final sum 20 | // r12 (a2): 10 21 | // r13 (a3): 1..10 22 | // r14 (a4): Sum 23 | // 24 | // External to function: 25 | m4_asm(ADD, r10, r0, r0) // Initialize r10 (a0) to 0. 26 | // Function: 27 | m4_asm(ADD, r14, r10, r0) // Initialize sum register a4 with 0x0 28 | m4_asm(ADDI, r12, r10, 1010) // Store count of 10 in register a2. 29 | m4_asm(ADD, r13, r10, r0) // Initialize intermediate sum register a3 with 0 30 | // Loop: 31 | m4_asm(ADD, r14, r13, r14) // Incremental addition 32 | m4_asm(ADDI, r13, r13, 1) // Increment intermediate register by 1 33 | m4_asm(BLT, r13, r12, 1111111111000) // If a3 is less than a2, branch to label named 34 | m4_asm(ADD, r10, r14, r0) // Store final result to register a0 so that it can be read by main program 35 | 36 | // Optional: 37 | // m4_asm(JAL, r7, 00000000000000000000) // Done. Jump to itself (infinite loop). (Up to 20-bit signed immediate plus implicit 0 bit (unlike JALR) provides byte address; last immediate bit should also be 0) 38 | m4_define_hier(['M4_IMEM'], M4_NUM_INSTRS) 39 | 40 | |cpu 41 | @0 42 | $reset = *reset; 43 | 44 | 45 | 46 | // YOUR CODE HERE 47 | // ... 48 | 49 | // Note: Because of the magic we are using for visualisation, if visualisation is enabled below, 50 | // be sure to avoid having unassigned signals (which you might be using for random inputs) 51 | // other than those specifically expected in the labs. You'll get strange errors for these. 52 | 53 | 54 | // Assert these to end simulation (before Makerchip cycle limit). 55 | *passed = *cyc_cnt > 40; 56 | *failed = 1'b0; 57 | 58 | // Macro instantiations for: 59 | // o instruction memory 60 | // o register file 61 | // o data memory 62 | // o CPU visualization 63 | |cpu 64 | //m4+imem(@1) // Args: (read stage) 65 | //m4+rf(@1, @1) // Args: (read stage, write stage) - if equal, no register bypass is required 66 | //m4+dmem(@4) // Args: (read/write stage) 67 | 68 | //m4+cpu_viz(@4) // For visualisation, argument should be at least equal to the last stage of CPU logic. @4 would work for all labs. 69 | \SV 70 | endmodule 71 | -------------------------------------------------------------------------------- /reference_solutions.tlv: -------------------------------------------------------------------------------- 1 | \m4_TLV_version 1d: tl-x.org 2 | \SV 3 | 4 | // ========================================== 5 | // For use in Makerchip for the MYTH Workshop 6 | // Provides reference solutions 7 | // without visibility to source code. 8 | // ========================================== 9 | 10 | // ---------------------------------- 11 | // Instructions: 12 | // - When stuck on a particular lab, configure code below, 13 | // and compile/simulate. 14 | // - A reference solution will build, but the source code will not be visible. 15 | // - You may use waveforms, diagrams, and visualization to understand the proper circuit, but you 16 | // will have to come up with the code. Logic expression syntax can be found by hovering over the 17 | // signal assignment in the diagram. 18 | // - Also reference https://github.com/stevehoover/RISC-V_MYTH_Workshop/blob/master/README.md 19 | // for updated information during the workshop as well as live support links. 20 | // ---------------------------------- 21 | 22 | 23 | // ============= 24 | // Configuration 25 | // ============= 26 | 27 | // For RISC-V solutions, comment the line below. 28 | m4_define(['M4_CALCULATOR'], 1) 29 | // Provide a slide number for the lab (reference below). 30 | m4_define(['M4_SLIDE_NUM'], 100) 31 | 32 | // Default Makerchip TL-Verilog Code Template 33 | m4_include_makerchip_hidden(['myth_workshop_solutions.private.tlv']) 34 | 35 | // Macro providing required top-level module definition, random 36 | // stimulus support, and Verilator config. 37 | m4_makerchip_module // (Expanded in Nav-TLV pane.) 38 | \TLV 39 | m4+solution(M4_SLIDE_NUM) 40 | m4+cpu_viz(@4) // The visualization, configured to reflect the given pipeline stage. 41 | \SV 42 | endmodule 43 | 44 | /* 45 | 46 | Labs slide #, for reference 47 | 48 | ----- Calculator Labs ------ 49 | 50 | Slide Lab 51 | ----- --- 52 | 23 Sequential Calculator 53 | 35 Counter and Calculator in Pipeline 54 | 36 2-Cycle Calculator 55 | 41 2-Cycle Calculator with Validity 56 | 43 Calculator with Single-Value Memory 57 | 58 | ----- RISC-V Labs ---------- 59 | 60 | Slide Lab 61 | ----- --- 62 | 63 | D4SK2 64 | ----- 65 | 6 [Not supported] Next PC 66 | 7 Fetch (part 1) 67 | 8 Fetch (part 2) 68 | 10 Instruction Types Decode and Immediate Decode 69 | 11 Instruction Decode 70 | 12 RISC-V Instruction Field Decode 71 | 13 Instruction Decode 72 | 73 | D4SK3 74 | ----- 75 | 16 Register File Read 76 | 17 Register File Read (part 2) 77 | 18 ALU 78 | 20 Register File Write 79 | 21 Branches 1 80 | 22 Branches 2 81 | 25 Testbench 82 | 83 | D5SK1 84 | ----- 85 | 33 3-Cycle valid 86 | 36 3-Cycle RISC-V 1 87 | 37 3-Cycle RISC-V 2 88 | 89 | D5SK2 90 | ----- 91 | 39 Register File Bypass 92 | 42 Branches 93 | 44 Complete Instruction Decode 94 | 45 Complete ALU 95 | 96 | D5SK3 97 | ----- 98 | 48 Redirect Loads 99 | 49 Load Data 1 100 | 51 Load Data 2 101 | 52 Load/Store in Program 102 | 53 Jumps 103 | 104 | *********************************/ 105 | 106 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RISC-V_MYTH_Workshop 2 | 3 | For students of ["Microprocessor for You in Thirty Hours/THree weeks" (MYTH) Workshop](https://www.vlsisystemdesign.com/riscv-based-myth/), offered by [Redwood EDA](https://www.redwoodeda.com/) and training partners [VLSI System Design (VSD)](https://www.vlsisystemdesign.com/) and [The EEView](https://theeeview.com). Find here accompanying live info and links for "Day 3" - "Day 5" (which may not correspond to actual days, depending on the delivery format). 4 | 5 | ## About the Workshop 6 | 7 | This workshop has recieved a great deal of attention in the RISC-V community for enabling students to learn at a pace never before possible through the use of TL-Verilog and [Makerchip](https://makerchip.com). Some links: 8 | - [Workshop info](https://www.vlsisystemdesign.com/vsd-iat/) 9 | - riscv.org blogs about [13-year-old Nicholas Sharkey](https://riscv.org/blog/2020/11/13-year-old-nicholas-sharkey-creates-a-risc-v-core/) and [12-year-old Niel Josiah](https://riscv.org/blog/2020/12/risc-v-microarchitecture-for-kids-steve-hoover-redwood-eda/) 10 | - [Linkedin posts](https://www.linkedin.com/search/results/all/?keywords=%23mythworkshop&origin=GLOBAL_SEARCH_HEADER) 11 | - [riscv.org's maintains a list of RISC-V cores, including MYTH cores](https://riscv.org/exchange/) 12 | 13 | ## Slack 14 | 15 | You should have been invited to a Slack workspace for collaborative discussions. 16 | 17 | - If you have not already been added to the established Slack channels, request to be added. 18 | - Please introduce yourself in the appropriate channel. 19 | - Use the provided channels appropriately to ask questions throughout the workshop. Mentors monitor Slack nearly 24 hours/day throughout the workshop. 20 | - The search box at the top is your friend. Others may have encountered similar issues. 21 | 22 | ## VSD-IAT (for Day 1-2 content only, if included) 23 | 24 | You should already be up and running with the [VLSI Design Systems - Intelligent Assessment Technology platform](https://vsdiat.com/). If you missed the live tutorial in the first call, the recording should have been posted in Slack, and you can search for it. 25 | 26 | ## GitHub Classroom Setup and Lab Submissions 27 | 28 | Lab submissions begin on Day 2 and are done via GitHub Classroom. You should receive a link to join prior to Day 2. For this course, all interactions with your GitHub repository can be done from your browser. You can add files using the "Add File" dropdown menu. You can edit a text file by navigating to it and clicking the pencil icon. Live training is provided, and the recording should have been posted in Slack. 29 | 30 | Submission process: 31 | 32 | - Day 2: We just want to see that you have done the work. Capture a few screenshots and save them in the `Day2` folder of your repository. 33 | - Day 3-5: Labs involving the calculator or RISC-V CPU should be submitted. If you miss a few, don't sweat it, but we want to see your progress. For each calculator or RISC-V lab: 34 | - Open your github classroom repository in your web browser. 35 | - Navigate into the `Day3_5` folder and the corresponding `calculator_solutions.tlv` or `risc-v_solutions.tlv`. 36 | - Click edit (pencil). 37 | - Paste your updated solution, *replacing* the existing code. (Within Makerchip editor select all (Ctrl-A) and copy (Ctrl-C), then select all in github editor (Ctrl-A) and paste with (Ctrl-V).) 38 | - Add commit message specifying the slide number or name of the lab, and commit changes. 39 | - (Do not *append* your changes, replace them entirely. you prior work is captured in the "History" (or "Commits").) 40 | 41 | ## Day 3-5 Slides 42 | 43 | As you listen to videos and do the lab assignments, follow along in the slides. Comments have been added to address points of confusion. 44 | 45 | - [Day 3 Slides](https://drive.google.com/file/d/1ZcjLzg-53It4CO3jDLofiUPZJ485JZ_g/view?usp=sharing) 46 | - [Day 4 - 5 Slides](https://drive.google.com/file/d/1tqvXmFru31-tezDX30jTNJoLcQk308UM/view?usp=sharing) 47 | 48 | ## Labs Starting-Point Code 49 | 50 | ### Intro Labs (all that are not calculator or RISC-V) 51 | 52 | No special starting point code is required. 53 | 54 | Use [myth.makerchip.com](https://myth.makerchip.com). 55 | 56 | ### Calculator Labs 57 | 58 | Begin with the following [starter code](https://myth.makerchip.com/sandbox?code_url=https:%2F%2Fraw.githubusercontent.com%2Fstevehoover%2FRISC-V_MYTH_Workshop%2Fmaster%2Fcalculator_shell.tlv) (Ctrl-click). 59 | 60 | ### RISC-V Labs 61 | 62 | Begin with the following [starter code](https://myth.makerchip.com/sandbox?code_url=https:%2F%2Fraw.githubusercontent.com%2Fstevehoover%2FRISC-V_MYTH_Workshop%2Fmaster%2Frisc-v_shell.tlv) (Ctrl-click). 63 | 64 | **Note** : As the complexity of your design increases, it might take long time (~3 mins) to generate the diagrams or they might fail to generate altogether. 65 | This does **not** indicate a problem in your code. 66 | 67 | 68 | ## HELP!!! 69 | 70 | It's important to take your time with each concept and with each lab. Rushing ahead will slow you down in the end. 71 | 72 | When you get stuck: 73 | 74 | 1. Always check the LOG! Keep your log clean of errors (both SandPiper errors (blue) and Verilator errors (black)). In some cases we expect warnings (LOGIC_ERRORs) for signals that are "used but never assigned" where we want Makerchip to provide random input values. Common "Issues and Solutions" can be found below. 75 | 1. Check the slide PDFs for any corrections, and check below for "Common Issues and Solutions". 76 | 1. Review previous lectures. 77 | 1. Follow conversation in Slack to see if someone else encountered similar issues. 78 | 1. Explore these [reference solutions](https://myth.makerchip.com/sandbox?code_url=https:%2F%2Fraw.githubusercontent.com%2Fstevehoover%2FRISC-V_MYTH_Workshop%2Fmaster%2Freference_solutions.tlv) (Ctrl-click). 79 | 80 | No, we're not giving away the answers! This link will open in Makerchip the diagram, waveform, and visualization for the solution, but will not show source code. Explore these to figure out the issue that's plaguing you, and then go back to doing the lab on your own. If you are stuck on syntax, hover over a signal assignment in the diagram to see an expression. 81 | 82 | **Note** : Last time we conducted this workshop, students relied to heavily on reference solutions. This **slowed them down** . Furthermore, there are intentional bugs in the reference solutions, and we can easily tell if you are simply copying them. 83 | 84 | Note that you have to comment the line with `m4_define(['M4_CALCULATOR'], 1)` to see solutions for RISC-V Labs. 85 | 86 | Also, we've pre-generated a Diagram of the final RISC-V reference solution at the bottom of this README. 87 | 88 | 1. Share your sandbox URL with a mentor via Direct Message in Slack. (Be sure it is saved/cloned, and clone again before editing.) 89 | 1. We have a Zoom plugin in Slack. Feel free to request a meeting with the instructors, or meet with others. Start a meeting with: 90 | 91 | `/zoom meeting My topic` 92 | 93 | ## Common Issues and Solutions 94 | 95 | In some cases the viz logic will make error/warning messages a bit more obscure. If you have enabled visualization, try disabling it. 96 | 97 | ### SandPiper(TM) (blue log output) 98 | 99 | ### Verilator (black log output) 100 | 101 | #### Verilated model didn't DC converge 102 | 103 | Combinational logic loops back on itself so the combinational logic does not stabilize. Perhaps you missed a `>>1`. 104 | 105 | Errors related to `[***NULL***:***NULL***]`: Disable viz macro and this error will most likely go away. Debug other SandPiper errors and re-enable viz. 106 | 107 | ## Pre-generated Diagram 108 | 109 | Your generated CPU would look like this after implementing all labs. 110 | 111 | **Note** : As noted above in "HELP!!!" section, refer to this diagram only when stuck. Reverse-engineering this diagram will **not** help you finish faster, and we can tell whether you simply reverse-engineer it. 112 | 113 | *Ctrl-click* to use your browser's zooming and to hover over assignment statements. 114 | 115 | ![Complete CPU](tlv_lib/fullcore.svg) 116 | 117 | ## After the Workshop 118 | 119 | ### Show off your work! 120 | 121 | GitHub is the new resume. Show off your work to the world. Many former students have developed impressive READMEs for their repositories, and even developed additional features for their cores to showcase what they learned, to further explore the technology, and to contribute the the community. If you have something unique to share about your experience in the workshop and the core you have built, we would be happy to showcase it from [RISC-V International's list of RISC-V Cores](https://riscv.org/exchange/) by adding it to [this list](https://github.com/stevehoover/RISC-V_MYTH_Workshop/blob/master/student_projects.md). Just [let us know](mailto:steve.hoover@redwoodeda.com). 122 | 123 | If you choose to make your workshop repository public, follow these steps: 124 | 125 | 1. Go to repository ('risc-v-myth-workshop--') on Github. 126 | 2. Click on the 'Settings' in top ribbon (below repo name). 127 | 3. Scroll down to the bottom, in 'Danger Zone', click 'Change visibility'. 128 | 4. In the window that opens, select "Make public", type the given text, and click "I understand ....". 129 | 5. Done! You can use private mode (in firefox) or incognito (in chrome) to visit the repo and see how it would look like to the world. 130 | 6. Optionally, you can change the repository name. If you have any clones of your repository, you'll want to push changes and delete them first. 131 | 132 | 135 | [.](https://gitlab.com/rweda/Makerchip-public) 136 | -------------------------------------------------------------------------------- /tlv_lib/calculator_shell_lib.tlv: -------------------------------------------------------------------------------- 1 | \m4_TLV_version 1d: tl-x.org 2 | \SV 3 | 4 | \TLV cal_viz(@_stage, /_top) 5 | // Only for Makerchip. 6 | m4_ifdef(['m4_MAKERCHIP'], ['m4+cal_viz_internal(['@_stage'], ['/_top'])'], ['']) 7 | 8 | // Visualization for calculator 9 | // #rand_mode is for transitioning from m4_rand(..) to \$random() to enable instantiation below top level. 10 | \TLV cal_viz_internal(@_stage, /_top) 11 | m4_pushdef(['m4_top'], m4_ifelse(/_top, [''], ['['/top']'], ['['/_top']'])) 12 | m4_ifelse_block(m4_sp_graph_dangerous, 1, [''], [' 13 | |calc 14 | @0 15 | $ANY = m4_top|tb/default<>0$ANY; 16 | `BOGUS_USE($dummy $rand2 $rand1) 17 | |tb 18 | @0 19 | /default 20 | $valid = ! m4_top|calc<>0$reset; 21 | m4_rand($rand_op, 2, 0) 22 | $op[2:0] = (*cyc_cnt % 2) ? ( *cyc_cnt > 33 ? ($rand_op[2:0] % 2) : *cyc_cnt > 15 ? $rand_op[2:0] : (($rand_op[2:0] % 2) + ($rand_op[2:0] % 4)) ) : >>1$op; 23 | $val1[31:0] = '0; 24 | $val2[31:0] = '0; 25 | $out[31:0] = '0; 26 | $mem[31:0] = 32'habcd1234; 27 | m4_rand($rand1, 3, 0) 28 | m4_rand($rand2, 3, 0) 29 | $dummy = 0; 30 | `BOGUS_USE($out $mem $valid $val1 $val2 $dummy $rand1 $rand2) 31 | @_stage 32 | $ANY = m4_top|calc<>0$ANY; 33 | 34 | $op_viz[2:0] = {{($mem == 32'habcd1234) ? 1'b0 : $op[2]}, $op[1:0]}; 35 | $mem_mod[31:0] = ($mem[31:0] == 32'habcd1234) ? 32'b0 : $mem[31:0]; 36 | $is_op_sum = ($valid && ($op_viz[2:0] == 3'b000)); // sum 37 | $is_op_diff = ($valid && ($op_viz[2:0] == 3'b001)); // diff 38 | $is_op_prod = ($valid && ($op_viz[2:0] == 3'b010)); // prod 39 | $is_op_quot = ($valid && ($op_viz[2:0] == 3'b011)); // quot 40 | $is_op_recall = ($valid && ($op_viz[2:0] == 3'b100)); // recall(retrieving from memory) 41 | $is_op_mem = ($valid && ($op_viz[2:0] == 3'b101) && !($mem == 32'habcd1234)); // mem(storing to memory) 42 | $is_invalid_op = ($valid && ($op_viz[2:0] == 3'b110 || $op_viz[2:0] == 3'b111)); // invalid operation? 43 | 44 | //These signal represents the change in value's and is used to generate colours in \viz according. 45 | $val1_changed = $valid && !$is_op_recall && !$is_invalid_op; 46 | $val2_changed = $valid && !$is_op_recall && !$is_op_mem && !$is_invalid_op; 47 | $out_changed = $valid && ($out_modified || !(|$out_modified)) && !$is_invalid_op && !$is_op_mem; 48 | //$out_modified[31:0] = ($out > ((1 << 31) - 1)) ? (~$out + 1) : $out; 49 | $out_modified[31:0] = $out; 50 | //$is_neg_num = ($out > ((1 << 31) - 1)); 51 | 52 | \viz_js 53 | box: {strokeWidth: 0}, 54 | init() { 55 | let tlvname = new fabric.Text("TL-V", { 56 | left: 150 + 130, 57 | top: 150 - 40, 58 | fontSize: 22, 59 | fontFamily: "Times", 60 | }); 61 | let hexcalname = new fabric.Text("HEX CALCULATOR", { 62 | left: 150 + 60, 63 | top: 150 - 20, 64 | fontSize: 22, 65 | fontFamily: "Times", 66 | }); 67 | let calbox = new fabric.Rect({ 68 | left: 150, 69 | top: 150, 70 | fill: "#eeeeeeff", 71 | width: 316, 72 | height: 366, 73 | stroke: "black", 74 | strokeWidth: 1, 75 | }); 76 | let val1box = new fabric.Rect({ 77 | left: 150 + 28, 78 | top: 150 + 83, 79 | fill: "#eeeeeeff", 80 | width: 254 + 14, 81 | height: 40, 82 | stroke: "black", 83 | strokeWidth: 1, 84 | }); 85 | let val1num = new fabric.Text("", { 86 | left: 150 + 28 + 30, 87 | top: 150 + 89, 88 | fontSize: 22, 89 | fontFamily: "Times", 90 | }); 91 | let val2box = new fabric.Rect({ 92 | left: 150 + 187, 93 | top: 150 + 221, 94 | fill: "#eeeeeeff", 95 | width: 109, 96 | height: 40, 97 | stroke: "black", 98 | strokeWidth: 1, 99 | }); 100 | let val2num = new fabric.Text("", { 101 | left: 150 + 187 + 1, 102 | top: 150 + 221 + 7, 103 | fontSize: 22, 104 | fontFamily: "Times", 105 | }); 106 | let outbox = new fabric.Rect({ 107 | left: 150 + 97, 108 | top: 150 + 300, 109 | fill: "#eeeeeeff", 110 | width: 199, 111 | height: 40, 112 | stroke: "black", 113 | strokeWidth: 1, 114 | }); 115 | let outnum = new fabric.Text("", { 116 | left: 150 + 97 + 20, 117 | top: 150 + 300 + 8, 118 | fontSize: 22, 119 | fontFamily: "Times", 120 | }); 121 | let outnegsign = new fabric.Text("-", { 122 | left: 150 + 97 + 8, 123 | top: 150 + 300 + 6, 124 | fontSize: 22, 125 | fontFamily: "Times", 126 | fill : "#eeeeeeff", 127 | }); 128 | let equalname = new fabric.Text("=", { 129 | left: 150 + 38, 130 | top: 150 + 306, 131 | fontSize: 28, 132 | fontFamily: "Times", 133 | }); 134 | let sumbox = new fabric.Rect({ 135 | left: 150 + 28, 136 | top: 150 + 148, 137 | fill: "#eeeeeeff", 138 | width: 64, 139 | height: 64, 140 | stroke: "black", 141 | strokeWidth: 1 142 | }); 143 | let prodbox = new fabric.Rect({ 144 | left: 150 + 28, 145 | top: 150 + 222, 146 | fill: "#eeeeeeff", 147 | width: 64, 148 | height: 64, 149 | stroke: "black", 150 | strokeWidth: 1 151 | }); 152 | let minbox = new fabric.Rect({ 153 | left: 150 + 105, 154 | top: 150 + 148, 155 | fill: "#eeeeeeff", 156 | width: 64, 157 | height: 64, 158 | stroke: "black", 159 | strokeWidth: 1 160 | }); 161 | let quotbox = new fabric.Rect({ 162 | left: 150 + 105, 163 | top: 150 + 222, 164 | fill: "#eeeeeeff", 165 | width: 64, 166 | height: 64, 167 | stroke: "black", 168 | strokeWidth: 1 169 | }); 170 | let sumicon = new fabric.Text("+", { 171 | left: 150 + 28 + 26, 172 | top: 150 + 148 + 22, 173 | fontSize: 22, 174 | fontFamily: "Times", 175 | }); 176 | let prodicon = new fabric.Text("*", { 177 | left: 150 + 28 + 26, 178 | top: 150 + 222 + 22, 179 | fontSize: 22, 180 | fontFamily: "Times", 181 | }); 182 | let minicon = new fabric.Text("-", { 183 | left: 150 + 105 + 26, 184 | top: 150 + 148 + 22, 185 | fontSize: 22, 186 | fontFamily: "Times", 187 | }); 188 | let quoticon = new fabric.Text("/", { 189 | left: 150 + 105 + 26, 190 | top: 150 + 222 + 22, 191 | fontSize: 22, 192 | fontFamily: "Times", 193 | }); 194 | let membox = new fabric.Rect({ 195 | left: 105 + 150, 196 | top: 150 + 25, 197 | fill: "#eeeeeeff", 198 | width: 191, 199 | height: 23, 200 | stroke: "black", 201 | strokeWidth: 1, 202 | }); 203 | let memname = new fabric.Text("mem", { 204 | left: 150 + 28, 205 | top: 150 + 25, 206 | fontSize: 22, 207 | fontFamily: "Times", 208 | }); 209 | let memarrow = new fabric.Text("->", { 210 | left: 150 + 32 + 47, 211 | top: 150 + 25, 212 | fill: "#eeeeeeff", 213 | fontSize: 22, 214 | fontFamily: "monospace", 215 | }); 216 | let recallarrow = new fabric.Text("->", { 217 | left: 150 + 38 + 28, 218 | top: 150 + 308, 219 | fill: "#eeeeeeff", 220 | fontSize: 22, 221 | fontFamily: "monospace", 222 | }); 223 | let memnum = new fabric.Text("", { 224 | left: 150 + 105 + 30, 225 | top: 150 + 25, 226 | fontSize: 22, 227 | fontFamily: "Times", 228 | }); 229 | let membuttonbox = new fabric.Rect({ 230 | left: 150 + 187, 231 | top: 150 + 151, 232 | fill: "#eeeeeeff", 233 | width: 45, 234 | height: 40, 235 | stroke: "black", 236 | strokeWidth: 1 237 | }); 238 | let recallbuttonbox = new fabric.Rect({ 239 | left: 150 + 245, 240 | top: 150 + 151, 241 | fill: "#eeeeeeff", 242 | width: 51, 243 | height: 40, 244 | stroke: "black", 245 | strokeWidth: 1 246 | }); 247 | let membuttonname = new fabric.Text("mem", { 248 | left: 150 + 187 + 1, 249 | top: 150 + 151 + 7, 250 | fontSize: 22, 251 | fontFamily: "Times", 252 | }); 253 | let recallbuttonname = new fabric.Text("recall", { 254 | left: 150 + 245 + 1, 255 | top: 150 + 151 + 7, 256 | fontSize: 22, 257 | fontFamily: "Times", 258 | }); 259 | return {tlvname, hexcalname, calbox, val1box, val1num, val2box, val2num, outbox, outnum, equalname, sumbox, minbox, prodbox, quotbox, sumicon, prodicon, minicon, quoticon, outnegsign, membox, memname, memnum, membuttonbox, recallbuttonbox, membuttonname, recallbuttonname, memarrow, recallarrow}; 260 | }, 261 | render() { 262 | let valid = '$valid'.asBool(false); 263 | let colorsum = '$is_op_sum'.asBool(false); 264 | let colorprod = '$is_op_prod'.asBool(false); 265 | let colormin = '$is_op_diff'.asBool(false); 266 | let colorquot = '$is_op_quot'.asBool(false); 267 | let colormembutton = '$is_op_mem'.asBool(false); 268 | let colorrecallbutton = '$is_op_recall'.asBool(false); 269 | let colormemarrow = '$is_op_mem'.asBool(false); 270 | let colorrecallarrow = '$is_op_recall'.asBool(false); 271 | let recallmod = '$is_op_recall'.asBool(false); 272 | let val1mod = '$val1_changed'.asBool(false); 273 | let val2mod = '$val2_changed'.asBool(false); 274 | let outmod = '$out_changed'.asBool(false); 275 | //let colornegnum = '$is_neg_num'.asBool(false); 276 | let oldvalval1 = ""; // for debugging 277 | let oldvalval2 = ""; // for debugging 278 | let oldvalout = ""; // for debugging 279 | let oldvalrecall = ""; // for debugging 280 | this.getObjects().val1num.set({ 281 | text: '$val1'.asInt(NaN).toString(16) + oldvalval1, 282 | fill: val1mod ? "blue" : "grey"}); 283 | this.getObjects().val2num.set({ 284 | text: '$val2'.asInt(NaN).toString(16) + oldvalval2, 285 | fill: val2mod ? "blue" : "grey"}); 286 | this.getObjects().outnum.set({ 287 | text: '$out_modified'.asInt(NaN).toString(16) + oldvalout, 288 | fill: outmod ? "blue" : "grey"}); 289 | this.getObjects().memnum.set({ 290 | text: '$mem_mod'.asInt(NaN).toString(16) + oldvalrecall, 291 | fill: (recallmod || colormembutton) ? "blue" : "grey"}); 292 | this.getObjects().sumbox.set({fill: colorsum ? "#9fc5e8ff" : "#eeeeeeff"}); 293 | this.getObjects().minbox.set({fill: colormin ? "#9fc5e8ff" : "#eeeeeeff"}); 294 | this.getObjects().prodbox.set({fill: colorprod ? "#9fc5e8ff" : "#eeeeeeff"}); 295 | this.getObjects().quotbox.set({fill: colorquot ? "#9fc5e8ff" : "#eeeeeeff"}); 296 | this.getObjects().membuttonbox.set({fill: colormembutton ? "#9fc5e8ff" : "#eeeeeeff"}); 297 | this.getObjects().recallbuttonbox.set({fill: colorrecallbutton ? "#9fc5e8ff" : "#eeeeeeff"}); 298 | this.getObjects().memarrow.set({fill: colormemarrow ? "blue" : "#eeeeeeff"}); 299 | this.getObjects().recallarrow.set({fill: colorrecallarrow ? "blue" : "#eeeeeeff"}); 300 | } 301 | ']) 302 | m4_popdef(['m4_top']) 303 | 304 | // Currently calc solutions calls m4_cpu_viz (a hack to avoid the need to modify Makerchip hidden files). Calc solutions provide their own viz, so make sure cpu_viz is disabled. 305 | \TLV cpu_viz(@_st) 306 | // Nothing. 307 | -------------------------------------------------------------------------------- /tlv_lib/risc-v_shell_lib.tlv: -------------------------------------------------------------------------------- 1 | \m4_TLV_version 1d: tl-x.org 2 | \SV 3 | m4_include_lib(['https://raw.githubusercontent.com/stevehoover/warp-v_includes/2d6d36baa4d2bc62321f982f78c8fe1456641a43/risc-v_defs.tlv']) 4 | 5 | m4+definitions([' 6 | m4_ifelse_block(M4_MAKERCHIP, 1,[' 7 | m4_define_vector(['M4_WORD'], 32) 8 | m4_define(['M4_EXT_I'], 1) 9 | m4_define(['M4_NUM_INSTRS'], 0) 10 | m4_echo(m4tlv_riscv_gen__body()) 11 | '],[' 12 | m4_define(['m4_asm'], ) 13 | m4_define(['M4_NUM_INSTRS'], 1073741824) 14 | m4_define(['m4_makerchip_module'], ['module riscv(input clk, input reset, input [31:0] idata0, idata1, idata2, idata3, idata4, idata5, idata6, idata7, idata8, idata9, idata10, idata11, idata12, idata13, idata14, idata15, idata16, idata17, idata18, idata19, idata20, idata21, idata22, idata23, idata24, idata25, idata26, idata27, idata28, idata29, idata30, idata31, output reg [31:0] reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15, reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23, reg24, reg25, reg26, reg27, reg28, reg29, reg30, reg31); wire cyc_cnt; wire passed; wire failed; assign cyc_cnt = 100; // cyc_cnt, passed and failed signals are valid only when running on makerchip, not valid here!']) 15 | ']) 16 | ']) 17 | 18 | // Instruction memory in |cpu at the given stage. 19 | \TLV imem(@_stage) 20 | // Instruction Memory containing program defined by m4_asm(...) instantiations. 21 | @_stage 22 | m4_ifelse_block(M4_MAKERCHIP, 1,[' 23 | \SV_plus 24 | // The program in an instruction memory. 25 | wire [31:0] instrs [0:M4_NUM_INSTRS-1]; 26 | assign instrs[0] = m4_instr0;m4_forloop(['m4_instr_ind'], 1, M4_NUM_INSTRS, [' assign instrs[m4_instr_ind] = m4_echo(['m4_instr']m4_instr_ind);']) 27 | /M4_IMEM_HIER 28 | $instr[31:0] = *instrs\[#imem\]; 29 | ?$imem_rd_en 30 | $imem_rd_data[31:0] = /imem[$imem_rd_addr]$instr; 31 | '],[' 32 | 33 | ?$imem_rd_en 34 | $imem_rd_data[31:0] = ($imem_rd_addr[31:0] == 0) ? *idata0 : 35 | ($imem_rd_addr[31:0] == 1) ? *idata1 : 36 | ($imem_rd_addr[31:0] == 2) ? *idata2 : 37 | ($imem_rd_addr[31:0] == 3) ? *idata3 : 38 | ($imem_rd_addr[31:0] == 4) ? *idata4 : 39 | ($imem_rd_addr[31:0] == 5) ? *idata5 : 40 | ($imem_rd_addr[31:0] == 6) ? *idata6 : 41 | ($imem_rd_addr[31:0] == 7) ? *idata7 : 42 | ($imem_rd_addr[31:0] == 8) ? *idata8 : 43 | ($imem_rd_addr[31:0] == 9) ? *idata9 : 44 | ($imem_rd_addr[31:0] == 10) ? *idata10 : 45 | ($imem_rd_addr[31:0] == 11) ? *idata11 : 46 | ($imem_rd_addr[31:0] == 12) ? *idata12 : 47 | ($imem_rd_addr[31:0] == 13) ? *idata13 : 48 | ($imem_rd_addr[31:0] == 14) ? *idata14 : 49 | ($imem_rd_addr[31:0] == 15) ? *idata15 : 50 | ($imem_rd_addr[31:0] == 16) ? *idata16 : 51 | ($imem_rd_addr[31:0] == 17) ? *idata17 : 52 | ($imem_rd_addr[31:0] == 18) ? *idata18 : 53 | ($imem_rd_addr[31:0] == 19) ? *idata19 : 54 | ($imem_rd_addr[31:0] == 20) ? *idata20 : 55 | ($imem_rd_addr[31:0] == 21) ? *idata21 : 56 | ($imem_rd_addr[31:0] == 22) ? *idata22 : 57 | ($imem_rd_addr[31:0] == 23) ? *idata23 : 58 | ($imem_rd_addr[31:0] == 24) ? *idata24 : 59 | ($imem_rd_addr[31:0] == 25) ? *idata25 : 60 | ($imem_rd_addr[31:0] == 26) ? *idata26 : 61 | ($imem_rd_addr[31:0] == 27) ? *idata27 : 62 | ($imem_rd_addr[31:0] == 28) ? *idata28 : 63 | ($imem_rd_addr[31:0] == 29) ? *idata29 : 64 | ($imem_rd_addr[31:0] == 30) ? *idata30 : 65 | ($imem_rd_addr[31:0] == 31) ? *idata31 : 66 | 31'b0 ; 67 | ']) 68 | 69 | 70 | // A 2-rd 1-wr register file in |cpu that reads and writes in the given stages. If read/write stages are equal, the read values reflect previous writes. 71 | // Reads earlier than writes will require bypass. 72 | \TLV rf(@_rd, @_wr) 73 | // Reg File 74 | @_wr 75 | /xreg[31:0] 76 | $wr = |cpu$rf_wr_en && (|cpu$rf_wr_index != 5'b0) && (|cpu$rf_wr_index == #xreg); 77 | $value[31:0] = |cpu$reset ? #xreg : 78 | $wr ? |cpu$rf_wr_data : 79 | $RETAIN; 80 | @_rd 81 | ?$rf_rd_en1 82 | $rf_rd_data1[31:0] = /xreg[$rf_rd_index1]>>m4_stage_eval(@_wr - @_rd + 1)$value; 83 | ?$rf_rd_en2 84 | $rf_rd_data2[31:0] = /xreg[$rf_rd_index2]>>m4_stage_eval(@_wr - @_rd + 1)$value; 85 | `BOGUS_USE($rf_rd_data1 $rf_rd_data2) 86 | 87 | 88 | // A data memory in |cpu at the given stage. Reads and writes in the same stage, where reads are of the data written by the previous transaction. 89 | \TLV dmem(@_stage) 90 | // Data Memory 91 | @_stage 92 | /dmem[15:0] 93 | $wr = |cpu$dmem_wr_en && (|cpu$dmem_addr == #dmem); 94 | $value[31:0] = |cpu$reset ? #dmem : 95 | $wr ? |cpu$dmem_wr_data : 96 | $RETAIN; 97 | 98 | ?$dmem_rd_en 99 | $dmem_rd_data[31:0] = /dmem[$dmem_addr]>>1$value; 100 | `BOGUS_USE($dmem_rd_data) 101 | 102 | \TLV myth_fpga(@_stage) 103 | @_stage 104 | \SV_plus 105 | m4_ifelse_block(M4_MAKERCHIP, 1,[''],[' 106 | always @ (posedge clk) begin 107 | *reg0 = |cpu/xreg[0]>>5$value; 108 | *reg1 = |cpu/xreg[1]>>5$value; 109 | *reg2 = |cpu/xreg[2]>>5$value; 110 | *reg3 = |cpu/xreg[3]>>5$value; 111 | *reg4 = |cpu/xreg[4]>>5$value; 112 | *reg5 = |cpu/xreg[5]>>5$value; 113 | *reg6 = |cpu/xreg[6]>>5$value; 114 | *reg7 = |cpu/xreg[7]>>5$value; 115 | *reg8 = |cpu/xreg[8]>>5$value; 116 | *reg9 = |cpu/xreg[9]>>5$value; 117 | *reg10 = |cpu/xreg[10]>>5$value; 118 | *reg11 = |cpu/xreg[11]>>5$value; 119 | *reg12 = |cpu/xreg[12]>>5$value; 120 | *reg13 = |cpu/xreg[13]>>5$value; 121 | *reg14 = |cpu/xreg[14]>>5$value; 122 | *reg15 = |cpu/xreg[15]>>5$value; 123 | *reg16 = |cpu/xreg[16]>>5$value; 124 | *reg17 = |cpu/xreg[17]>>5$value; 125 | *reg18 = |cpu/xreg[18]>>5$value; 126 | *reg19 = |cpu/xreg[19]>>5$value; 127 | *reg20 = |cpu/xreg[20]>>5$value; 128 | *reg21 = |cpu/xreg[21]>>5$value; 129 | *reg22 = |cpu/xreg[22]>>5$value; 130 | *reg23 = |cpu/xreg[23]>>5$value; 131 | *reg24 = |cpu/xreg[24]>>5$value; 132 | *reg25 = |cpu/xreg[25]>>5$value; 133 | *reg26 = |cpu/xreg[26]>>5$value; 134 | *reg27 = |cpu/xreg[27]>>5$value; 135 | *reg28 = |cpu/xreg[28]>>5$value; 136 | *reg29 = |cpu/xreg[29]>>5$value; 137 | *reg30 = |cpu/xreg[30]>>5$value; 138 | *reg31 = |cpu/xreg[31]>>5$value; 139 | end 140 | ']) 141 | 142 | \TLV cpu_viz(@_stage) 143 | m4_ifelse_block(M4_MAKERCHIP, 1,[' 144 | m4_ifelse_block(m4_sp_graph_dangerous, 1, [''], [' 145 | |cpu 146 | // for pulling default viz signals into CPU 147 | // and then back into viz 148 | @0 149 | $ANY = /top|cpuviz/defaults<>0$ANY; 150 | `BOGUS_USE($dummy) 151 | /xreg[31:0] 152 | $ANY = /top|cpuviz/defaults/xreg<>0$ANY; 153 | /dmem[15:0] 154 | $ANY = /top|cpuviz/defaults/dmem<>0$ANY; 155 | // String representations of the instructions for debug. 156 | \SV_plus 157 | logic [40*8-1:0] instr_strs [0:M4_NUM_INSTRS]; 158 | assign instr_strs = '{m4_asm_mem_expr "END "}; 159 | |cpuviz 160 | @1 161 | /imem[m4_eval(M4_NUM_INSTRS-1):0] // TODO: Cleanly report non-integer ranges. 162 | $instr[31:0] = /top|cpu/imem<>0$instr; 163 | $instr_str[40*8-1:0] = *instr_strs[imem]; 164 | \viz_js 165 | box: {width: 500, height: 18, strokeWidth: 0}, 166 | onTraceData() { 167 | let instr_str = '$instr_str'.asString() + ": " + '$instr'.asBinaryStr(NaN); 168 | return {objects: {instr_str: new fabric.Text(instr_str, { 169 | top: 0, 170 | left: 0, 171 | fontSize: 14, 172 | fontFamily: "monospace" 173 | })}}; 174 | }, 175 | where: {left: -580, top: 0} 176 | 177 | @0 178 | /defaults 179 | {$is_lui, $is_auipc, $is_jal, $is_jalr, $is_beq, $is_bne, $is_blt, $is_bge, $is_bltu, $is_bgeu, $is_lb, $is_lh, $is_lw, $is_lbu, $is_lhu, $is_sb, $is_sh, $is_sw} = '0; 180 | {$is_addi, $is_slti, $is_sltiu, $is_xori, $is_ori, $is_andi, $is_slli, $is_srli, $is_srai, $is_add, $is_sub, $is_sll, $is_slt, $is_sltu, $is_xor} = '0; 181 | {$is_srl, $is_sra, $is_or, $is_and, $is_csrrw, $is_csrrs, $is_csrrc, $is_csrrwi, $is_csrrsi, $is_csrrci} = '0; 182 | {$is_load, $is_store} = '0; 183 | 184 | $valid = 1'b1; 185 | $rd[4:0] = 5'b0; 186 | $rs1[4:0] = 5'b0; 187 | $rs2[4:0] = 5'b0; 188 | $src1_value[31:0] = 32'b0; 189 | $src2_value[31:0] = 32'b0; 190 | 191 | $result[31:0] = 32'b0; 192 | $pc[31:0] = 32'b0; 193 | $imm[31:0] = 32'b0; 194 | 195 | $is_s_instr = 1'b0; 196 | 197 | $rd_valid = 1'b0; 198 | $rs1_valid = 1'b0; 199 | $rs2_valid = 1'b0; 200 | $rf_wr_en = 1'b0; 201 | $rf_wr_index[4:0] = 5'b0; 202 | $rf_wr_data[31:0] = 32'b0; 203 | $rf_rd_en1 = 1'b0; 204 | $rf_rd_en2 = 1'b0; 205 | $rf_rd_index1[4:0] = 5'b0; 206 | $rf_rd_index2[4:0] = 5'b0; 207 | 208 | $ld_data[31:0] = 32'b0; 209 | $imem_rd_en = 1'b0; 210 | $imem_rd_addr[M4_IMEM_INDEX_CNT-1:0] = {M4_IMEM_INDEX_CNT{1'b0}}; 211 | 212 | /xreg[31:0] 213 | $value[31:0] = 32'b0; 214 | $wr = 1'b0; 215 | `BOGUS_USE($value $wr) 216 | $dummy[0:0] = 1'b0; 217 | /dmem[15:0] 218 | $value[31:0] = 32'b0; 219 | $wr = 1'b0; 220 | `BOGUS_USE($value $wr) 221 | $dummy[0:0] = 1'b0; 222 | `BOGUS_USE($is_lui $is_auipc $is_jal $is_jalr $is_beq $is_bne $is_blt $is_bge $is_bltu $is_bgeu $is_lb $is_lh $is_lw $is_lbu $is_lhu $is_sb $is_sh $is_sw) 223 | `BOGUS_USE($is_addi $is_slti $is_sltiu $is_xori $is_ori $is_andi $is_slli $is_srli $is_srai $is_add $is_sub $is_sll $is_slt $is_sltu $is_xor) 224 | `BOGUS_USE($is_srl $is_sra $is_or $is_and $is_csrrw $is_csrrs $is_csrrc $is_csrrwi $is_csrrsi $is_csrrci) 225 | `BOGUS_USE($is_load $is_store) 226 | `BOGUS_USE($valid $rd $rs1 $rs2 $src1_value $src2_value $result $pc $imm) 227 | `BOGUS_USE($is_s_instr $rd_valid $rs1_valid $rs2_valid) 228 | `BOGUS_USE($rf_wr_en $rf_wr_index $rf_wr_data $rf_rd_en1 $rf_rd_en2 $rf_rd_index1 $rf_rd_index2 $ld_data) 229 | `BOGUS_USE($imem_rd_en $imem_rd_addr) 230 | 231 | $dummy[0:0] = 1'b0; 232 | @_stage 233 | $ANY = /top|cpu<>0$ANY; 234 | 235 | /xreg[31:0] 236 | $ANY = /top|cpu/xreg<>0$ANY; 237 | `BOGUS_USE($dummy) 238 | 239 | /dmem[15:0] 240 | $ANY = /top|cpu/dmem<>0$ANY; 241 | `BOGUS_USE($dummy) 242 | 243 | // m4_mnemonic_expr is build for WARP-V signal names, which are slightly different. Correct them. 244 | m4_define(['m4_modified_mnemonic_expr'], ['m4_patsubst(m4_mnemonic_expr, ['_instr'], [''])']) 245 | $mnemonic[10*8-1:0] = m4_modified_mnemonic_expr $is_load ? "LOAD " : $is_store ? "STORE " : "ILLEGAL "; 246 | \viz_js 247 | box: {left: -600, top: -20, width: 2000, height: 1000, strokeWidth: 0}, 248 | render() { 249 | // 250 | // PC instr_mem pointer 251 | // 252 | let $pc = '$pc'; 253 | let color = !('$valid'.asBool()) ? "gray" : 254 | "blue"; 255 | let pcPointer = new fabric.Text("->", { 256 | top: 18 * ($pc.asInt() / 4), 257 | left: -600, 258 | fill: color, 259 | fontSize: 14, 260 | fontFamily: "monospace" 261 | }); 262 | // 263 | // 264 | // Fetch Instruction 265 | // 266 | // TODO: indexing only works in direct lineage. let fetchInstr = new fabric.Text('|fetch/instr_mem[$Pc]$instr'.asString(), { // TODO: make indexing recursive. 267 | //let fetchInstr = new fabric.Text('$raw'.asString("--"), { 268 | // top: 50, 269 | // left: 90, 270 | // fill: color, 271 | // fontSize: 14, 272 | // fontFamily: "monospace" 273 | //}); 274 | // 275 | // Instruction with values. 276 | // 277 | let regStr = (valid, regNum, regValue) => { 278 | return valid ? `r${regNum} (${regValue})` : `rX`; 279 | }; 280 | let srcStr = ($src, $valid, $reg, $value) => { 281 | return $valid.asBool(false) 282 | ? `\n ${regStr(true, $reg.asInt(NaN), $value.asInt(NaN))}` 283 | : ""; 284 | }; 285 | let str = `${regStr('$rd_valid'.asBool(false), '$rd'.asInt(NaN), '$result'.asInt(NaN))}\n` + 286 | ` = ${'$mnemonic'.asString()}${srcStr(1, '$rs1_valid', '$rs1', '$src1_value')}${srcStr(2, '$rs2_valid', '$rs2', '$src2_value')}\n` + 287 | ` i[${'$imm'.asInt(NaN)}]`; 288 | let instrWithValues = new fabric.Text(str, { 289 | top: 70, 290 | left: 90, 291 | fill: color, 292 | fontSize: 14, 293 | fontFamily: "monospace" 294 | }); 295 | return [pcPointer, instrWithValues]; 296 | } 297 | // 298 | // Register file 299 | // 300 | /xreg[31:0] 301 | \viz_js 302 | box: {width: 90, height: 18, strokeWidth: 0}, 303 | all: { 304 | box: {strokeWidth: 0}, 305 | init() { 306 | let regname = new fabric.Text("Reg File", { 307 | top: -20, left: 2, 308 | fontSize: 14, 309 | fontFamily: "monospace" 310 | }); 311 | return {regname}; 312 | } 313 | }, 314 | init() { 315 | let reg = new fabric.Text("", { 316 | top: 0, left: 0, 317 | fontSize: 14, 318 | fontFamily: "monospace" 319 | }); 320 | return {reg}; 321 | }, 322 | render() { 323 | let mod = '$wr'.asBool(false); 324 | let reg = parseInt(this.getIndex()); 325 | let regIdent = reg.toString(); 326 | let oldValStr = mod ? `(${'>>1$value'.asInt(NaN).toString()})` : ""; 327 | this.getObjects().reg.set({ 328 | text: regIdent + ": " + '$value'.asInt(NaN).toString() + oldValStr, 329 | fill: mod ? "blue" : "black"}); 330 | }, 331 | where: {left: 365, top: -20}, 332 | where0: {left: 0, top: 0} 333 | // 334 | // DMem 335 | // 336 | /dmem[15:0] 337 | \viz_js 338 | box: {width: 100, height: 18, strokeWidth: 0}, 339 | all: { 340 | box: {strokeWidth: 0}, 341 | init() { 342 | let memname = new fabric.Text("Mini DMem", { 343 | top: -20, 344 | left: 2, 345 | fontSize: 14, 346 | fontFamily: "monospace" 347 | }); 348 | return {memname}; 349 | } 350 | }, 351 | init() { 352 | let mem = new fabric.Text("", { 353 | top: 0, 354 | left: 10, 355 | fontSize: 14, 356 | fontFamily: "monospace" 357 | }); 358 | return {mem}; 359 | }, 360 | render() { 361 | let mod = '$wr'.asBool(false); 362 | let mem = parseInt(this.getIndex()); 363 | let memIdent = mem.toString(); 364 | let oldValStr = mod ? `(${'>>1$value'.asInt(NaN).toString()})` : ""; 365 | this.getObjects().mem.set({ 366 | text: memIdent + ": " + '$value'.asInt(NaN).toString() + oldValStr, 367 | fill: mod ? "blue" : "black"}); 368 | }, 369 | where: {left: 458, top: -20}, 370 | where0: {left: 0, top: 0} 371 | ']) 372 | ']) --------------------------------------------------------------------------------