== Editing Wavedrom diagrams for Unpriv

[NOTE]
====
This is a work in progress. I am at this point not versed in content issues with respect to the diagrams and in addition I am discovering the editing process through trial and error. There are properties for which I have not yet tested procedures. For that reason I welcome helpful suggestions and critiques. Please email help@riscv.org.
====

=== Relevant contextual information

Wavedrom is a utility that is available at https://wavedrom.com/.

// contributors can make suggestions here.
The Wavedrom diagrams used in the Unpriv specification include opcodes and related information. The diagrams are vital to understanding the specification.

For some RISC-V specifications, Wavedrom diagrams have been placed within topics that are seen as https://csrc.nist.gov/glossary/term/information_object[information objects] that have identifiable patterns but have yet to be fully and formally defined.

The Wavedrom diagrams for the Unpriv specification are contained in the src/images/wavedrom folder in the https://github.com/riscv/riscv-isa-manual/tree/convert2adoc[convert2adoc] branch.

Wavedrom diagrams are coded using a javascript-like code structure.
//if a contributor understands the rules for creating the diagrams for RISC-V please inform me.

The working assumption is that we need to start with a 1:1 converted version, with the exception that we are adding missing figure titles, table titles, and example titles for consistency in the specification.

=== Example Wavedrom code, before and after

Following is an example Wavedrom file that is typical of one the needs just a few edits, minus the `[]` brackets that indicate a macro (because using the macro even within a code block activates a process in the Asciidoctor build):

[source,adoc]
----
{reg: [
  {bits: 7, name: 'opcode',	 attr: ['FMADD', 'FNMADD', 'FMSUB', 'FNMSUB'],    type: 8},
  {bits: 5, name: 'rd',     attr: 'dest',     type: 2},
  {bits: 3, name: 'func3',  attr: 'RM', type: 8},
  {bits: 5, name: 'rs1',    attr: 'src1',     type: 4},
  {bits: 5, name: 'rs2',    attr: 'src2',     type: 4},
  {bits: 2, name: 'fmt',    attr: 'Q',        type: 8},
  {bits: 5, name: 'rs3',    attr: 'src3',     type: 4},
]}
----

This renders as follows:

[wavedrom, , ]
....
{reg: [
  {bits: 7, name: 'opcode',	attr: ['FMADD', 'FNMADD', 'FMSUB', 'FNMSUB'],    type: 8},
  {bits: 5, name: 'rd',     attr: 'dest',     type: 2},
  {bits: 3, name: 'func3',  attr: 'RM', type: 8},
  {bits: 5, name: 'rs1',    attr: 'src1',     type: 4},
  {bits: 5, name: 'rs2',    attr: 'src2',     type: 4},
  {bits: 2, name: 'fmt',    attr: 'Q',        type: 8},
  {bits: 5, name: 'rs3',    attr: 'src3',     type: 4},
]}
....


.For convenience, it makes sense to line up the `type:` attribute so that it remains easy to see:

[source,adoc]
----
{reg: [
  {bits: 7, name: 'opcode', type: 8,	attr: ['FMADD', 'FNMADD', 'FMSUB', 'FNMSUB'],    },
  {bits: 5, name: 'rd',   	type: 2,	attr: 'dest',   },
  {bits: 3, name: 'func3',	type: 8, 	attr: 'RM', },
  {bits: 5, name: 'rs1',    type: 4, 	attr: 'src1', },
  {bits: 5, name: 'rs2',    type: 4, 	attr: 'src2',  },
  {bits: 2, name: 'fmt',    type: 8, 	attr: 'Q',    },
  {bits: 5, name: 'rs3',    type: 8, 	attr: 'src3', },
]}
----

The output remains the same:

[wavedrom, , ]
....
{reg: [
  {bits: 7, name: 'opcode', type: 8,	attr: ['FMADD', 'FNMADD', 'FMSUB', 'FNMSUB'],    },
  {bits: 5, name: 'rd',   	type: 2,	attr: 'dest',   },
  {bits: 3, name: 'func3',	type: 8, 	attr: 'RM', },
  {bits: 5, name: 'rs1',    type: 4, 	attr: 'src1', },
  {bits: 5, name: 'rs2',    type: 4, 	attr: 'src2',  },
  {bits: 2, name: 'fmt',    type: 8, 	attr: 'Q',    },
  {bits: 5, name: 'rs3',    type: 8, 	attr: 'src3', },
]}
....

[start=2]
. For each line that contain a single value for the `attr` attribute:

* add `[]` to contain additional values--and--
* follow the convention for commas to contain and separate additional values until all the lines contain the same number of values for `attr` that are in the 'opcodes' row:

[source,adoc]
----
{reg: [
  {bits: 7, name: 'opcode', type: 8,	attr: ['FMADD', 'FNMADD', 'FMSUB', 'FNMSUB'], },
  {bits: 5, name: 'rd',   	type: 2,	attr: ['dest','dest','dest','dest',],},
  {bits: 3, name: 'func3',	type: 8, 	attr: ['RM','RM','RM','RM',], },
  {bits: 5, name: 'rs1',    type: 4, 	attr: ['src1','src1','src1','src1',], },
  {bits: 5, name: 'rs2',    type: 4, 	attr: ['src2','src2', 'src2', 'src2', ],  },
  {bits: 2, name: 'fmt',    type: 8, 	attr: ['Q','Q','Q','Q',],    },
  {bits: 5, name: 'rs3',    type: 8, 	attr: ['src3','src3','src3','src3',], },
]}
----

[WARNING]
====
Wavedrom makes use of straight single quotes like `''` rather than diagonal single quotes like ````.
====

Here's the result:

[wavedrom, , ]
....
{reg: [
  {bits: 7, name: 'opcode', type: 8,	attr: ['FMADD', 'FNMADD', 'FMSUB', 'FNMSUB'], },
  {bits: 5, name: 'rd',   	type: 2,	attr: ['dest','dest','dest','dest'],},
  {bits: 3, name: 'func3',	type: 8, 	attr: ['RM','RM','RM','RM'], },
  {bits: 5, name: 'rs1',    type: 4, 	attr: ['src1','src1','src1','src1'], },
  {bits: 5, name: 'rs2',    type: 4, 	attr: ['src2','src2', 'src2', 'src2'],  },
  {bits: 2, name: 'fmt',    type: 8, 	attr: ['Q','Q','Q','Q'],    },
  {bits: 5, name: 'rs3',    type: 8, 	attr: ['src3','src3','src3','src3'], },
]}
....

[start=3]
. Check the LaTeX version of the diagram to check for the numerical values that are needed within the missing row:

[source,adoc]
----
{reg: [
  {bits: 7, name: 'opcode', type: 8,	attr: ['8', 'FMADD', 'FNMADD', 'FMSUB', 'FNMSUB'], },
  {bits: 5, name: 'rd',   	type: 2,	attr: ['6', 'dest','dest','dest','dest',], },
  {bits: 3, name: 'func3',	type: 8, 	attr: ['4', 'RM','RM','RM','RM',], },
  {bits: 5, name: 'rs1',    type: 4, 	attr: ['6', 'src1','src1','src1','src1',], },
  {bits: 5, name: 'rs2',    type: 4, 	attr: ['6', 'src2','src2', 'src2', 'src2', ], },
  {bits: 2, name: 'fmt',    type: 8, 	attr: ['4', 'Q','Q','Q','Q',], },
  {bits: 5, name: 'rs3',    type: 8, 	attr: ['6', 'src3','src3','src3','src3',], },
]}
----

Now the diagram should contain all of the content that exists within the LaTeX version:

[wavedrom, , ]
....
{reg: [
  {bits: 7, name: 'opcode', type: 8,	attr: ['7', 'FMADD', 'FNMADD', 'FMSUB', 'FNMSUB'], },
  {bits: 5, name: 'rd',   	type: 2,	attr: ['5', 'dest','dest','dest','dest',],},
  {bits: 3, name: 'func3',	type: 8, 	attr: ['3', 'RM','RM','RM','RM',], },
  {bits: 5, name: 'rs1',    type: 4, 	attr: ['5', 'src1','src1','src1','src1',], },
  {bits: 5, name: 'rs2',    type: 4, 	attr: ['5', 'src2','src2', 'src2', 'src2', ], },
  {bits: 2, name: 'fmt',    type: 8, 	attr: ['3', 'Q','Q','Q','Q',],    },
  {bits: 5, name: 'rs3',    type: 8, 	attr: ['5', 'src3','src3','src3','src3',], },
]}
....

[start=4]
. If you or a member of your team can build locally, please ensure that someone checks that the diagrams build without errors.
. Generate a PR to the convert2adoc branch and indicate whether you or a member of the team has tested your changes in a local build.
. As always, thanks for your participation in the success of RISC-V.

=== Caveats for editing wavedrom diagrams

At the time of this writing, we have noticed the following unexpected results during diagram builds using the asciidoctor-pdf toolchain, as follows:

* Some, but not all, unicode that works in AsciiDoc (see <<useful-unicode>> ) actually breaks the Wavedrom diagram build, and other unicode does not break the Wavedrom diagram build but still doesn't render properly.
* Latexmath appears to not work at all in Wavedrom diagrams.
* After struggling to understand why various options that we explored for an acceptable &#8800; in Wavedrom diagrams and discovering the above rather confusing results, we decided to use `!=` as a workaround. With the fact that both Asciidoctor and Wavedrom are evolving, and also the fact that bytefield is being considered as an alternative diagrams rendering solution, it seems possible that this workaround will be temporary.
