Add docs section for custom extensions
This commit is contained in:
		
							parent
							
								
									bf38d93d33
								
							
						
					
					
						commit
						ce93c45e69
					
				| 
						 | 
					@ -14,6 +14,8 @@ include::sections/configuration_and_integration.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include::sections/csr.adoc[]
 | 
					include::sections/csr.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include::sections/custom_extensions.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[debug-chapter]]
 | 
					[[debug-chapter]]
 | 
				
			||||||
include::sections/debug.adoc[]
 | 
					include::sections/debug.adoc[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										18410
									
								
								doc/hazard3.pdf
								
								
								
								
							
							
						
						
									
										18410
									
								
								doc/hazard3.pdf
								
								
								
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -25,6 +25,7 @@ These are both thin wrappers around the https://github.com/Wren6991/Hazard3/blob
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The core module `hazard3_core` can also be instantiated directly, which may be more efficient if support for some other bus standard is desired. However, the interface of `hazard3_core` will not be documented and is not guaranteed to be stable.
 | 
					The core module `hazard3_core` can also be instantiated directly, which may be more efficient if support for some other bus standard is desired. However, the interface of `hazard3_core` will not be documented and is not guaranteed to be stable.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[config-parameters-section]]
 | 
				
			||||||
=== Configuration Parameters
 | 
					=== Configuration Parameters
 | 
				
			||||||
 | 
					
 | 
				
			||||||
==== Reset state configuration
 | 
					==== Reset state configuration
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -676,6 +676,7 @@ Note also that this is not the same as the "rule locking bypass" bit in the ePMP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
=== Custom Power Control CSRs
 | 
					=== Custom Power Control CSRs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[reg-msleep]]
 | 
				
			||||||
==== msleep
 | 
					==== msleep
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Address: `0xbf0`
 | 
					Address: `0xbf0`
 | 
				
			||||||
| 
						 | 
					@ -687,25 +688,4 @@ M-mode sleep control register.
 | 
				
			||||||
| Bits | Name | Description
 | 
					| Bits | Name | Description
 | 
				
			||||||
| 31:3 | - | RES0
 | 
					| 31:3 | - | RES0
 | 
				
			||||||
| 2    | `deepsleep` | Deassert the clock request signal when entering the block or WFI state, and wait for clock acknowledge to reassert before leaving the block or WFI state.
 | 
					| 2    | `deepsleep` | Deassert the clock request signal when entering the block or WFI state, and wait for clock acknowledge to reassert before leaving the block or WFI state.
 | 
				
			||||||
| 1    | `block` | Write 1 to enter a WFI sleep state until either an unblock signal is received, or an interrupt is asserted that would cause a WFI to exit. Clears automatically when leaving the blocked state.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If an unblock signal has been received since the last time `block` was written to 1, the write is ignored. In other words, the blocked state falls through immediately in this case.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
An unblock signal is received when another hart writes 1 to its `unblock` register, or for some other platform-specified reason.
 | 
					 | 
				
			||||||
| 0    | `unblock` | Write 1 to post an unblock signal to other harts in the system. Always reads back as 0.
 | 
					 | 
				
			||||||
|===
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
==== sleep
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Address: `0x8f0`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
U-mode sleep control register. A subset of the fields in `msleep`. If `mstatus.tw` is 1, then attempting to access this register from U-mode causes an illegal opcode trap.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[cols="10h,20h,~", options="header"]
 | 
					 | 
				
			||||||
|===
 | 
					 | 
				
			||||||
| Bits | Name | Description
 | 
					 | 
				
			||||||
| 31:2 | - | RES0
 | 
					 | 
				
			||||||
| 1    | `block` | U-mode access to the `msleep.block` bit
 | 
					 | 
				
			||||||
| 0    | `unblock` | U-mode access to the `msleep.unblock` bit
 | 
					 | 
				
			||||||
|===
 | 
					|===
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,170 @@
 | 
				
			||||||
 | 
					== Custom Extensions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Hazard3 implements a small number of custom extensions. All are optional: custom extensions are only included if the relevant feature flags are set to 1 when instantiating the processor (<<config-parameters-section>>). Hazard3 is always a _conforming_ RISC-V implementation, and when these extensions are disabled it is also a _standard_ RISC-V implementation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If any one of these extensions is enabled, the `x` bit in <<reg-misa>> is set to indicate the presence of a nonstandard extension.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Xh3power: Hazard3 power management
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This extension adds a new M-mode CSR (<<reg-msleep>>), and two new hint instructions, `h3.block` and `h3.unblock`, in the `slt` nop-compatible custom hint space.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The hints are used to allow processors to sleep until woken by other processors in a multiprocessor environment. The `msleep` CSR is used to control some of the details of the processor's WFI sleep state, to trade off sleep power consumption against wakeup latency.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== h3.block
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Enter a WFI sleep state until either an unblock signal is received, or an interrupt is asserted that would cause a WFI to exit.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If `mstatus.tw` is set, attempting to execute this instruction in privilege modes lower than M-mode will generate an illegal instruction exception.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If an unblock signal has been received in the time since the last `h3.block`, this instruction executes as a `nop`, and the processor does not enter the sleep state. Conceptually, the sleep state falls through immediately because the corresponding unblock signal has already been received.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					An unblock signal is received when a neighbouring processor (the exact definition of "neighbouring" being left to the implementor) executes an `h3.unblock` instruction, or for some other platform-defined reason.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This instruction is encoded as `slt x0, x0, x0`, which is part of the custom nop-compatible hint encoding space.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example C macro:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					#define __h3_block() asm ("slt x0, x0, x0")
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example assembly macro:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					.macro h3.block
 | 
				
			||||||
 | 
						slt x0, x0, x0
 | 
				
			||||||
 | 
					.endm
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== h3.unblock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Post an unblock signal to other processors in the system. For example, to notify another processor that a work queue is now nonempty.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If `mstatus.tw` is set, attempting to execute this instruction in privilege modes lower than M-mode will generate an illegal instruction exception.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This instruction is encoded as `slt x0, x0, x1`, which is part of the custom nop-compatible hint encoding space.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example C macro:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					#define __h3_unblock() asm ("slt x0, x0, x1")
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example assembly macro:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					.macro h3.unblock
 | 
				
			||||||
 | 
						slt x0, x0, x1
 | 
				
			||||||
 | 
					.endm
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Xh3bextm: Hazard3 bit extract multiple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This is a small extension with multi-bit versions of the "bit extract" instructions from Zbs, used for extracting small, contiguous bit fields.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== h3.bextm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"Bit extract multiple", a multi-bit version of the `bext` instruction from Zbs. Perform a right-shift followed by a mask of 1-8 LSBs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Encoding (R-type):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[cols="10h,20h,20h,~", options="header"]
 | 
				
			||||||
 | 
					|===
 | 
				
			||||||
 | 
					| Bits  | Name          | Value    | Description
 | 
				
			||||||
 | 
					| 31:29 | `funct7[6:4]` | `0b000`  | RES0
 | 
				
			||||||
 | 
					| 28:26 | `size`        | -        | Number of ones in mask, values 0->7 encode 1->8 bits.
 | 
				
			||||||
 | 
					| 25    | `funct7[0]`   | `0b0`    | RES0, because aligns with `shamt[5]` of potential RV64 version of `h3.bextmi` 
 | 
				
			||||||
 | 
					| 24:20 | `rs2`         | -        | Source register 2 (shift amount)
 | 
				
			||||||
 | 
					| 19:15 | `rs1`         | -        | Source register 1
 | 
				
			||||||
 | 
					| 14:12 | `funct3`      | `0b000`  | `h3.bextm`
 | 
				
			||||||
 | 
					| 11:7  | `rd`          | -        | Destination register
 | 
				
			||||||
 | 
					| 6:2   | `opc`         | `0b01011`| custom0 opcode
 | 
				
			||||||
 | 
					| 1:0   | `size`        | `0b11`   | 32-bit instruction
 | 
				
			||||||
 | 
					|===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example C macro (using GCC statement expressions):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					// nbits must be a constant expression
 | 
				
			||||||
 | 
					#define __h3_bextm(nbits, rs1, rs2) ({\
 | 
				
			||||||
 | 
						uint32_t __h3_bextm_rd; \
 | 
				
			||||||
 | 
						asm (".insn r 0x0b, 0, %3, %0, %1, %2"\
 | 
				
			||||||
 | 
							: "=r" (__h3_bextm_rd) \
 | 
				
			||||||
 | 
							: "r" (rs1), "r" (rs2), "i" ((((nbits) - 1) & 0x7) << 1)\
 | 
				
			||||||
 | 
						); \
 | 
				
			||||||
 | 
						__h3_bextm_rd; \
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example assembly macro:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					// rd = (rs1 >> rs2[4:0]) & ~(-1 << nbits)
 | 
				
			||||||
 | 
					.macro h3.bextm rd rs1 rs2 nbits
 | 
				
			||||||
 | 
					.if (\nbits < 1) || (\nbits > 8)
 | 
				
			||||||
 | 
					.err
 | 
				
			||||||
 | 
					.endif
 | 
				
			||||||
 | 
					#if NO_HAZARD3_CUSTOM
 | 
				
			||||||
 | 
					    srl  \rd, \rs1, \rs2
 | 
				
			||||||
 | 
					    andi \rd, \rd, ((1 << \nbits) - 1)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					.insn r 0x0b, 0x0, (((\nbits - 1) & 0x7 ) << 1), \rd, \rs1, \rs2
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					.endm
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==== h3.bextmi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Immediate variant of `h3.bextm`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Encoding (I-type):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[cols="10h,20h,20h,~", options="header"]
 | 
				
			||||||
 | 
					|===
 | 
				
			||||||
 | 
					| Bits  | Name          | Value    | Description
 | 
				
			||||||
 | 
					| 31:29 | `imm[11:9]`   | `0b000`  | RES0
 | 
				
			||||||
 | 
					| 28:26 | `size`        | -        | Number of ones in mask, values 0->7 encode 1->8 bits.
 | 
				
			||||||
 | 
					| 25    | `imm[5]`      | `0b0`    | RES0, for potential future RV64 version 
 | 
				
			||||||
 | 
					| 24:20 | `shamt`       | -        | Shift amount, 0 through 31 
 | 
				
			||||||
 | 
					| 19:15 | `rs1`         | -        | Source register 1
 | 
				
			||||||
 | 
					| 14:12 | `funct3`      | `0b100`  | `h3.bextmi`
 | 
				
			||||||
 | 
					| 11:7  | `rd`          | -        | Destination register
 | 
				
			||||||
 | 
					| 6:2   | `opc`         | `0b01011`| custom0 opcode
 | 
				
			||||||
 | 
					| 1:0   | `size`        | `0b11`   | 32-bit instruction
 | 
				
			||||||
 | 
					|===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example C macro (using GCC statement expressions):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					// nbits and shamt must be constant expressions
 | 
				
			||||||
 | 
					#define __h3_bextmi(nbits, rs1, shamt) ({\
 | 
				
			||||||
 | 
						uint32_t __h3_bextmi_rd; \
 | 
				
			||||||
 | 
						asm (".insn i 0x0b, 0x4, %0, %1, %2"\
 | 
				
			||||||
 | 
							: "=r" (__h3_bextmi_rd) \
 | 
				
			||||||
 | 
							: "r" (rs1), "i" ((((nbits) - 1) & 0x7) << 6 | ((shamt) & 0x1f)) \
 | 
				
			||||||
 | 
						); \
 | 
				
			||||||
 | 
						__h3_bextmi_rd; \
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example assembly macro:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					// rd = (rs1 >> shamt) & ~(-1 << nbits)
 | 
				
			||||||
 | 
					.macro h3.bextmi rd rs1 shamt nbits
 | 
				
			||||||
 | 
					.if (\nbits < 1) || (\nbits > 8)
 | 
				
			||||||
 | 
					.err
 | 
				
			||||||
 | 
					.endif
 | 
				
			||||||
 | 
					.if (\shamt < 0) || (\shamt > 31)
 | 
				
			||||||
 | 
					.err
 | 
				
			||||||
 | 
					.endif
 | 
				
			||||||
 | 
					#if NO_HAZARD3_CUSTOM
 | 
				
			||||||
 | 
					    srli \rd, \rs1, \shamt
 | 
				
			||||||
 | 
					    andi \rd, \rd, ((1 << \nbits) - 1)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					.insn i 0x0b, 0x4, \rd, \rs1, (\shamt & 0x1f) | (((\nbits - 1) & 0x7 ) << 6)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					.endm
 | 
				
			||||||
 | 
					----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue