Resolving issue with m4_asm_end which must be used from both \TLV and \SV context.

Use of new signal goTo* functions in VIZ.
Readme updates.
This commit is contained in:
Steve Hoover 2021-02-26 17:43:18 -05:00
parent 315e5d541a
commit f86204080c
2 changed files with 17 additions and 10 deletions

View File

@ -2,14 +2,20 @@
Accompanying resources for the [Building a RISC-V CPU Core](https://courses.edx.org/TBD) [EdX](https://edx.org/) course by [Steve Hoover](https://www.linkedin.com/in/steve-hoover-a44b607/) of [Redwood EDA](https://redwoodeda.com), [Linux Foundation](https://www.linuxfoundation.org/), and [RISC-V International](https://riscv.org). Accompanying resources for the [Building a RISC-V CPU Core](https://courses.edx.org/TBD) [EdX](https://edx.org/) course by [Steve Hoover](https://www.linkedin.com/in/steve-hoover-a44b607/) of [Redwood EDA](https://redwoodeda.com), [Linux Foundation](https://www.linuxfoundation.org/), and [RISC-V International](https://riscv.org).
## Welcome
Congratulations for taking this step to expand your knowledge of computer hardware.
At this time, there are no course corrections or platform issues to report. Please do let us know within the EdX platform if anything gets in your way. There's a great deal of infrastructure to maintain for the course, and we aim to keep it all running smoothly. Now, back to EdX.
## RISC-V Starting-Point Code ## RISC-V Starting-Point Code
To begin the first RISC-V lab, Ctrl-click this link to <a href="https://makerchip.com/sandbox?code_url=https:%2F%2Fraw.githubusercontent.com%2Fstevehoover%2FLF-Building-a-RISC-V-CPU-Core%2Fmaster%2Frisc-v_shell.tlv" target="_blank" atom_fix="_">open starting-point code in makerchip</a>. To begin the first RISC-V lab, when instructed to do so, Ctrl-click this link to <a href="https://makerchip.com/sandbox?code_url=https:%2F%2Fraw.githubusercontent.com%2Fstevehoover%2FLF-Building-a-RISC-V-CPU-Core%2Fmaster%2Frisc-v_shell.tlv" target="_blank" atom_fix="_">open starting-point code in makerchip</a>.
## RISC-V Reference Solution ## RISC-V Reference Solution
In case you get stuck, we've got your back! These <a href="https://makerchip.com/sandbox?code_url=https:%2F%2Fraw.githubusercontent.com%2Fstevehoover%2FLF-Building-a-RISC-V-CPU-Core%2Fmain%2Frisc-v_solutions.tlv" target="_blank" atom_fix="_">reference solutions</a> (Ctrl-click) will help with syntax, etc. without handing your the answers. In case you get stuck, we've got your back! These <a href="https://makerchip.com/sandbox?code_url=https:%2F%2Fraw.githubusercontent.com%2Fstevehoover%2FLF-Building-a-RISC-V-CPU-Core%2Fmain%2Frisc-v_solutions.tlv" target="_blank" atom_fix="_">reference solutions</a> (Ctrl-click) will help with syntax, etc. without handing you the answers.
## Final Result Here's a pre-built logic diagram of the final CPU. Ctrl-click here to [explore in its own tab](https://raw.githubusercontent.com/stevehoover/LF-Building-a-RISC-V-CPU-Core/main/lib/riscv.svg).
![Final Core](lib/riscv.svg) ![Final Core](lib/riscv.svg)

View File

@ -15,7 +15,8 @@ m4+definitions(['
// A single-line M4 macro instantiated at the end of the asm code. // A single-line M4 macro instantiated at the end of the asm code.
// It actually produces a definition of an SV macro that instantiates the IMem conaining the program (that can be parsed without \SV_plus). // It actually produces a definition of an SV macro that instantiates the IMem conaining the program (that can be parsed without \SV_plus).
m4_define(['m4_asm_end'], ['`define READONLY_MEM(ADDR, DATA) logic [31:0] instrs [0:M4_NUM_INSTRS-1]; assign DATA \= instrs[ADDR[\$clog2(\$size(instrs)) + 1 : 2]]; assign instrs \= '{m4_instr0['']m4_forloop(['m4_instr_ind'], 1, M4_NUM_INSTRS, [', m4_echo(['m4_instr']m4_instr_ind)'])};']) m4_define(['m4_asm_end'], ['`define READONLY_MEM(ADDR, DATA) logic [31:0] instrs [0:M4_NUM_INSTRS-1]; assign DATA = instrs[ADDR[$clog2($size(instrs)) + 1 : 2]]; assign instrs = '{m4_instr0['']m4_forloop(['m4_instr_ind'], 1, M4_NUM_INSTRS, [', m4_echo(['m4_instr']m4_instr_ind)'])};'])
m4_define(['m4_asm_end_tlv'], ['`define READONLY_MEM(ADDR, DATA) logic [31:0] instrs [0:M4_NUM_INSTRS-1]; assign DATA \= instrs[ADDR[\$clog2(\$size(instrs)) + 1 : 2]]; assign instrs \= '{m4_instr0['']m4_forloop(['m4_instr_ind'], 1, M4_NUM_INSTRS, [', m4_echo(['m4_instr']m4_instr_ind)'])};'])
']) '])
@ -562,7 +563,7 @@ m4+definitions(['
} else { } else {
// Using an unstable API, so: // Using an unstable API, so:
try { try {
passed.goTo(passed.signal.waveData.endCycle - 1) passed.goToSimEnd().step(-1)
if (passed.asBool()) { if (passed.asBool()) {
this.getInitObject("passed").set({text:"Sim Passes", visible: true, fill: "lightgray"}) this.getInitObject("passed").set({text:"Sim Passes", visible: true, fill: "lightgray"})
} }
@ -611,12 +612,12 @@ m4+definitions(['
let instr = this.svSigRef(`instrs(${this.getIndex()})`) let instr = this.svSigRef(`instrs(${this.getIndex()})`)
if (instr) { if (instr) {
let binary_str = instr.goTo(0).asBinaryStr("") let binary_str = instr.goToSimStart().asBinaryStr("")
this.getInitObject("binary").setText(binary_str) this.getInitObject("binary").setText(binary_str)
} }
let disassembled = this.svSigRef(`instr_strs(${this.getIndex()})`) let disassembled = this.svSigRef(`instr_strs(${this.getIndex()})`)
if (disassembled) { if (disassembled) {
let disassembled_str = disassembled.goTo(0).asString("") let disassembled_str = disassembled.goToSimStart().asString("")
disassembled_str = disassembled_str.slice(0, -5) disassembled_str = disassembled_str.slice(0, -5)
this.getInitObject("disassembled").setText(disassembled_str) this.getInitObject("disassembled").setText(disassembled_str)
} }
@ -720,7 +721,7 @@ m4+definitions(['
// Terminate with success condition (regardless of correctness of register values): // Terminate with success condition (regardless of correctness of register values):
m4_asm(ADDI, x30, x0, 1) m4_asm(ADDI, x30, x0, 1)
m4_asm(JAL, x0, 0) // 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) m4_asm(JAL, x0, 0) // 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)
m4_asm_end() m4_asm_end_tlv()
m4_define(['M4_MAX_CYC'], 70) m4_define(['M4_MAX_CYC'], 70)
// (A copy of this appears in the shell code.) // (A copy of this appears in the shell code.)
@ -747,7 +748,7 @@ m4+definitions(['
// Test result value in x14, and set x31 to reflect pass/fail. // Test result value in x14, and set x31 to reflect pass/fail.
m4_asm(ADDI, x30, x14, 111111010100) // Subtract expected value of 44 to set x30 to 1 if and only iff the result is 45 (1 + 2 + ... + 9). m4_asm(ADDI, x30, x14, 111111010100) // Subtract expected value of 44 to set x30 to 1 if and only iff the result is 45 (1 + 2 + ... + 9).
m4_asm(BGE, x0, x0, 0) // 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) m4_asm(BGE, x0, x0, 0) // 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)
m4_asm_end() m4_asm_end_tlv()
m4_define(['M4_MAX_CYC'], 40) m4_define(['M4_MAX_CYC'], 40)