├── .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 | 
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 | '])
--------------------------------------------------------------------------------