Livt packages

Eccelerators.RiscV

Version 0.3.0

Composable RV32I and Zmmul processors, machine-mode support, and reusable FPGA system components written in Livt.

Published files (120)

src/Contracts/RvDecoded.lvt

namespace Eccelerators.RiscV.Contracts

/**
 * Value-only decode control word. PC, instruction and immediate travel separately.
 * Bits 0..4 rd, 5..9 rs1, 10..14 rs2, 15 usesRs1, 16 usesRs2,
 * 17 writesRd, 18 legal, 19..26 operation. Bits 27..31 reserved zero.
 * No component instance, scheduled getters or architectural state.
 */
public class RvDecoded
{
	// Masks for packed register indices and operation IDs.
	public const REGISTER_MASK: uint = 31
	public const OPERATION_MASK: uint = 255

	// Bit offsets of the remaining packed fields; rd starts at bit zero.
	public const RS1_SHIFT: int = 5
	public const RS2_SHIFT: int = 10
	public const USES_RS1_SHIFT: int = 15
	public const USES_RS2_SHIFT: int = 16
	public const WRITES_RD_SHIFT: int = 17
	public const LEGAL_SHIFT: int = 18
	public const OPERATION_SHIFT: int = 19

	/**
	 * Packs operation (0..255), register indices (0..31) and decode flags.
	 * Values outside those ranges are masked; callers retain PC and immediate separately.
	 */
	public static fn Pack[](operation: uint, rd: uint, rs1: uint, rs2: uint,
		usesRs1: bool, usesRs2: bool, writesRd: bool, legal: bool) uint
	{
		var word = (rd & REGISTER_MASK)
			| ((rs1 & REGISTER_MASK) << RS1_SHIFT)
			| ((rs2 & REGISTER_MASK) << RS2_SHIFT)
			| ((operation & OPERATION_MASK) << OPERATION_SHIFT)

		if (usesRs1) {
			word = word | (1 << USES_RS1_SHIFT)
		}

		if (usesRs2) {
			word = word | (1 << USES_RS2_SHIFT)
		}

		if (writesRd) {
			word = word | (1 << WRITES_RD_SHIFT)
		}

		if (legal) {
			word = word | (1 << LEGAL_SHIFT)
		}

		return word
	}

	/**
	 * Returns the five-bit destination index; x0 still suppresses architectural writes.
	 */
	public static fn Rd[](word: uint) uint
	{
		return word & REGISTER_MASK
	}

	/**
	 * Returns source register 1; consult HasSource1 before reading it.
	 */
	public static fn Rs1[](word: uint) uint
	{
		return (word >> RS1_SHIFT) & REGISTER_MASK
	}

	/**
	 * Returns source register 2; consult HasSource2 before reading it.
	 */
	public static fn Rs2[](word: uint) uint
	{
		return (word >> RS2_SHIFT) & REGISTER_MASK
	}

	/**
	 * Returns the eight-bit operation ID agreed by the decoder and execution unit.
	 */
	public static fn Operation[](word: uint) uint
	{
		return (word >> OPERATION_SHIFT) & OPERATION_MASK
	}

	/**
	 * Reports whether execution consumes source register 1.
	 */
	public static fn HasSource1[](word: uint) bool
	{
		return (word & (1 << USES_RS1_SHIFT)) != 0
	}

	/**
	 * Reports whether execution consumes source register 2.
	 */
	public static fn HasSource2[](word: uint) bool
	{
		return (word & (1 << USES_RS2_SHIFT)) != 0
	}

	/**
	 * Reports destination-write intent; the engine must still suppress x0 and faults.
	 */
	public static fn HasDestinationWrite[](word: uint) bool
	{
		return (word & (1 << WRITES_RD_SHIFT)) != 0
	}

	/**
	 * Reports whether the decoder accepted the instruction in the selected ISA.
	 */
	public static fn IsLegal[](word: uint) bool
	{
		return (word & (1 << LEGAL_SHIFT)) != 0
	}
}