Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/gen/cpp_hart_gen/rv32_Debug/build/iss",
"args": ["-m", "rv32", "-c", "${workspaceFolder}/cfgs/rv32-riscv-tests.yaml", "${workspaceFolder}/ext/riscv-tests/isa/rv32ui-p-addi"],
"args": ["-m", "rv32", "-c", "${workspaceFolder}/cfgs/mc100-32-riscv-tests.yaml", "${workspaceFolder}/ext/riscv-tests/isa/rv32ui-p-addi"],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
Expand Down
4 changes: 2 additions & 2 deletions backends/cpp_hart_gen/cpp/include/udb/bitfield.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ namespace udb {
template <template <unsigned, bool> class BitsClass, unsigned N, bool Signed>
requires ((N >= Size) && (BitsClass<N, Signed>::IsABits))
BitfieldMember<ParentSize, Start, Size>::template operator BitsClass<N, Signed>() const {
return BitsClass<N, Signed> {(static_cast<BitsType<ParentSize>>(m_parent) >> Bits<ParentSize>(Start)) & MaximumValue};
return BitsClass<N, Signed> {static_cast<BitsType<ParentSize>>(m_parent) >> Bits<Size>(Start) & MaximumValue};
}

template <unsigned ParentSize, unsigned Start, unsigned Size>
Expand All @@ -185,7 +185,7 @@ namespace udb {
&BitfieldMember<ParentSize, Start, Size>::template operator=(
const BitfieldMember<ParentSize, Start, Size> &other) {
m_parent = (static_cast<BitsType<ParentSize>>(m_parent) & ~Mask) |
((static_cast<BitsType<Size>>(other).template widening_sll<Start>()) & Mask);
((static_cast<BitsType<Size>>(other).template widening_sll<Size>()) & Mask);
return *this;
}

Expand Down
12 changes: 5 additions & 7 deletions backends/cpp_hart_gen/cpp/include/udb/bits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2801,14 +2801,12 @@ namespace udb {
template <unsigned, bool> class MsbType, unsigned MsbN,
template <unsigned, bool> class LsbType, unsigned LsbN
>
constexpr _PossiblyUnknownRuntimeBits<constmax_v<MsbN, LsbN>, false> extract(const MsbType<MsbN, false>& msb, const LsbType<LsbN, false>& lsb) const {
constexpr _PossiblyUnknownBits<N, false> extract(const MsbType<MsbN, false>& msb, const LsbType<LsbN, false>& lsb) const {
udb_assert(msb >= lsb, "Negative range is not allowed");
udb_assert(lsb.get() <= width(), "Extract out of range");

return _PossiblyUnknownRuntimeBits<constmax_v<MsbN, LsbN>, false>(
WidthArg(msb.get() - lsb.get() + 1),
ValueArg(_PossiblyUnknownBits<constmax_v<MsbN, LsbN>, false>(m_val.extract(msb, lsb), m_unknown_mask.extract(msb, lsb)))
);
_Bits<N, false> mask = (_Bits<N, false>{1} << (msb - lsb)) - _Bits<N, false>{1};
return _PossiblyUnknownBits<N, false>{m_val.extract(msb, lsb), m_unknown_mask.extract(msb, lsb)};
}

template <unsigned Pos>
Expand Down Expand Up @@ -3020,8 +3018,8 @@ namespace udb {

constexpr explicit _PossiblyUnknownRuntimeBits(unsigned width) : m_width(width) {}
constexpr explicit _PossiblyUnknownRuntimeBits(const WidthArg& width) : m_width(width.width) {}
constexpr explicit _PossiblyUnknownRuntimeBits(const ValueArg<_PossiblyUnknownBits<MaxN, Signed>> val, const WidthArg& width) : m_val(val.value), m_width(width.width) {}
constexpr explicit _PossiblyUnknownRuntimeBits(const WidthArg& width, const ValueArg<_PossiblyUnknownBits<MaxN, Signed>> val) : m_val(val.value), m_width(width.width) {}
constexpr explicit _PossiblyUnknownRuntimeBits(const ValueArg<StorageType> val, const WidthArg& width) : m_val(val.value), m_width(width.width) {}
constexpr explicit _PossiblyUnknownRuntimeBits(const WidthArg& width, const ValueArg<StorageType> val) : m_val(val.value), m_width(width.width) {}

// template <std::integral T>
// constexpr _PossiblyUnknownRuntimeBits(const T &initial_value, unsigned width)
Expand Down
37 changes: 11 additions & 26 deletions backends/cpp_hart_gen/tasks.rake
Original file line number Diff line number Diff line change
Expand Up @@ -397,32 +397,17 @@ namespace :test do

task riscv_tests: ["build_riscv_tests", "build:cpp_hart"] do
configs_name, build_name = configs_build_name
rv32uiTests = ["simple", "add", "addi", "and",
"andi", "auipc", "beq", "bge", "bgeu", "blt",
"bltu", "bne", "fence_i", "jal", "jalr",
"lb", "lbu", "lh", "lhu", "lw", "ld_st",
"lui", "ma_data", "or", "ori", "sb", "sh",
"sw", "st_ld", "sll", "slli", "slt", "slti",
"sltiu", "sltu", "sra", "srai", "srl",
"srli", "sub", "xor", "xori"]

rv32uiTests.each do |t|
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/rv32-riscv-tests.yaml ext/riscv-tests/isa/rv32ui-p-#{t}"
end

rv32umTests = [ "div", "divu", "mul", "mulh", "mulhsu", "mulhu", "rem", "remu" ]
rv32umTests.each do |t|
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/rv32-riscv-tests.yaml ext/riscv-tests/isa/rv32um-p-#{t}"
end

rv32ucTests = [ "rvc" ]
rv32ucTests.each do |t|
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/rv32-riscv-tests.yaml ext/riscv-tests/isa/rv32uc-p-#{t}"
end

rv32siTests = ["csr", "dirty", "ma_fetch", "scall", "sbreak"]
rv32siTests.each do |t|
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/rv32-riscv-tests.yaml ext/riscv-tests/isa/rv32si-p-#{t}"
tests = ["simple", "add", "addi", "and",
"andi", "auipc", "beq", "bge", "bgeu", "blt",
"bltu", "bne", "fence_i", "jal", "jalr",
"lb", "lbu", "lh", "lhu", "lw", "ld_st",
"lui", "ma_data", "or", "ori", "sb", "sh",
"sw", "st_ld", "sll", "slli", "slt", "slti",
"sltiu", "sltu", "sra", "srai", "srl",
"srli", "sub", "xor", "xori"]

tests.each do |t|
sh "#{CPP_HART_GEN_DST}/#{build_name}/build/iss -m rv32 -c #{$root}/cfgs/mc100-32-riscv-tests.yaml ext/riscv-tests/isa/rv32ui-p-#{t}"
end
end
end
2 changes: 1 addition & 1 deletion backends/cpp_hart_gen/templates/enum.hxx.erb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace udb {
}

constexpr bool operator!=(const <%= enum.name %>& rhs) const {
return m_value != rhs.m_value;
return m_value == rhs.m_value;
}

constexpr bool operator<(const <%= enum.name %>& rhs) const {
Expand Down
9 changes: 0 additions & 9 deletions backends/cpp_hart_gen/templates/hart_impl.hxx.erb
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,11 @@ namespace udb {
for (unsigned b = 0; b < bb_size; b++) {
inst = current_bb->pop();

fmt::print("PC {:x} {}\n", m_pc, inst->disassemble());
for (auto r : inst->srcRegs()) {
fmt::print("R {} {:x}\n", r.to_string(), _xreg(r.get_num()));
}

// set the fall-through next pc
m_next_pc = m_pc + Bits<MXLEN>{inst->enc_len()};

inst->execute();

for (auto r : inst->dstRegs()) {
fmt::print("R= {} {:x}\n", r.to_string(), _xreg(r.get_num()));
}

advance_pc();
if (this->m_exit_requested) {
this->m_exit_requested = false; // reset the request
Expand Down
125 changes: 5 additions & 120 deletions backends/generators/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,105 +17,6 @@ def check_requirement(req, exts):
return False


def build_match_from_format(format_field):
"""
Build a match string from the format field in the new schema.
"""
if not format_field or "opcodes" not in format_field:
return None

# Determine instruction width by finding maximum bit position
valid_locations = []

opcodes = format_field["opcodes"]
# Check opcodes
for field_data in opcodes.values():
if isinstance(field_data, dict) and "location" in field_data:
if isinstance(field_data["location"], str):
try:
location = field_data["location"]
split_location = location.split("|")
high = max(
(
int(location.split("-")[0])
if "-" in location
else int(location)
)
for location in split_location
)
valid_locations.append(high)
except (ValueError, IndexError):
raise ValueError(
f"Invalid location format: {field_data['location']}"
)
elif isinstance(field_data["location"], int):
try:
valid_locations.append(field_data["location"])
except (ValueError, IndexError):
raise ValueError(
f"Invalid location format: {field_data['location']}"
)
else:
raise ValueError(f"Unknown location format: {field_data['location']}")

if "variables" in format_field:
variables = format_field["variables"]
# Check variables
for var_data in variables.values():
if isinstance(var_data, dict) and "location" in var_data:
if isinstance(var_data["location"], str):
try:
location = var_data["location"]
if "-" in location:
high = int(location.split("-")[0])
else:
high = int(location)
valid_locations.append(high)
except (ValueError, IndexError):
raise ValueError(
f"Invalid location format: {var_data['location']}"
)
elif isinstance(var_data["location"], int):
try:
valid_locations.append(var_data["location"])
except (ValueError, IndexError):
raise ValueError(
f"Invalid location format: {var_data['location']}"
)
else:
raise ValueError(f"Invalid location format: {var_data['location']}")

if not valid_locations:
raise ValueError("No valid bit locations found in format field")

max_bit = max(valid_locations)

# Set instruction width based on maximum bit position
width = max_bit + 1
match_bits = ["-"] * width

# Populate match string with opcode bits
for field_data in opcodes.values():
if isinstance(field_data, dict):
try:
location = field_data["location"]
if isinstance(location, str) and "-" in location:
high, low = map(int, location.split("-"))
else:
high = low = int(location)

if high < low or high >= width:
logging.warning(f"Invalid bit range: {location}")
continue # Skip invalid bit ranges

binary_value = format(field_data["value"], f"0{high - low + 1}b")
match_bits[width - high - 1 : width - low] = binary_value
except (ValueError, IndexError):
raise ValueError(f"Error processing opcode field: {field_data}")

return "".join(match_bits)


def parse_extension_requirements(extensions_spec):
"""
Parse the extension requirements from the definedBy field.
Expand Down Expand Up @@ -276,27 +177,11 @@ def load_instructions(

encoding = data.get("encoding", {})
if not encoding:
# Check if this instruction uses the new schema with a 'format' field
format_field = data.get("format")
if not format_field:
logging.error(
f"Missing 'encoding' field in instruction {name} in {path}"
)
encoding_filtered += 1
continue

# Try to build a match string from the format field
match_string = build_match_from_format(format_field)
if not match_string:
logging.error(
f"Could not build encoding from format field in instruction {name} in {path}"
)
encoding_filtered += 1
continue

# Create a synthetic encoding compatible with existing logic
encoding = {"match": match_string, "variables": []}
logging.debug(f"Built encoding from format field for {name}")
logging.error(
f"Missing 'encoding' field in instruction {name} in {path}"
)
encoding_filtered += 1
continue

# Check if the instruction specifies a base architecture constraint
base = data.get("base")
Expand Down
15 changes: 6 additions & 9 deletions backends/instructions_appendix/all_instructions.golden.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,6 @@ Encoding::
Description::
This instruction implements the rotation, SubBytes and Round Constant addition steps of the AES
block cipher Key Schedule.


`rnum` must be in the range `0x0..0xA`. The values `0xB..0xF` are reserved.


Expand Down Expand Up @@ -7268,7 +7266,7 @@ Encoding::
....

Description::
The xref:insts:fadd_d.adoc#udb:doc:inst:fadd_d[fadd.d] instruction is analogous to xref:insts:fadd_s.adoc#udb:doc:inst:fadd_s[fadd.s] and performs double-precision floating-point addition between
The xref:insts:fadd_d.adoc#udb:doc:inst:fadd_d[fadd.d] instruction is analogous to xref:insts:fadd_s.adoc#udb:doc:inst:fadd_s[fadd.s] and performs double-precision floating-point addition of
`fs1` and `fs2` and writes the final result to `fd`.


Expand Down Expand Up @@ -7387,7 +7385,7 @@ Encoding::
....

Description::
The xref:insts:fadd_s.adoc#udb:doc:inst:fadd_s[fadd.s] instruction performs single-precision floating-point addition of `xs1` and `xs2`
The xref:insts:fadd_s.adoc#udb:doc:inst:fadd_s[fadd.s] instruction performs single-precision floating-point addition of `fs1` and `fs2`
and writes the final result to `fd`.


Expand Down Expand Up @@ -10622,8 +10620,7 @@ Encoding::
....

Description::
The
The xref:insts:fli_q.adoc#udb:doc:inst:fli_q[fli.q] instruction loads one of 32 quad-precision floating-point constants, encoded in the `rs1`
The xref:insts:fli_q.adoc#udb:doc:inst:fli_q[fli.q] instruction loads one of 32 quad-precision floating-point constants, encoded in the `xs1`
field, into floating-point register `rd`.
xref:insts:fli_q.adoc#udb:doc:inst:fli_q[fli.q] is encoded like xref:insts:fmv_w_x.adoc#udb:doc:inst:fmv_w_x[fmv.w.x], but with _fmt_ = Q.

Expand Down Expand Up @@ -12246,7 +12243,7 @@ Included in::
== fmv.d.x

Synopsis::
Floating-Point Move from Integer Register to Double-Precision Register
Floating-Point Move Double-Precision from Integer Register

Assembly::
fmv.d.x fd, xs1
Expand Down Expand Up @@ -12365,7 +12362,7 @@ Included in::
== fmv.x.d

Synopsis::
Floating-Point Move from Double-Precision Register to Integer Register
Floating-Point Move Double-Precision to Integer Register

Assembly::
fmv.x.d xd, fs1
Expand Down Expand Up @@ -12631,7 +12628,7 @@ Encoding::
Description::
The xref:insts:fmvp_q_x.adoc#udb:doc:inst:fmvp_q_x[fmvp.q.x] instruction moves a double-precision number from a pair of integer registers into
a floating-point register.
Integer registers xs1 and xs2 supply bits 63:0 and 127:64, respectively; the result is written to
Integer registers `xs1` and `xs2` supply bits 63:0 and 127:64, respectively; the result is written to
floating-point register `fd`.
xref:insts:fmvp_q_x.adoc#udb:doc:inst:fmvp_q_x[fmvp.q.x] is encoded in the OP-FP major opcode with _funct3_=0 and _funct7_=1011011.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
$schema: https://riscv.org/udb/schemas/config_schema-0.1.0.json
kind: architecture configuration
type: fully configured
name: rv32-riscv-tests
description: A compliant full config for rv32 riscv-tests
name: MC100-32-riscv-tests
description: An example MC100-32-compliant full config for riscv-tests
implemented_extensions:
- [Sm, "1.11.0"]
- [I, "2.1"]
Expand All @@ -17,7 +17,6 @@ implemented_extensions:
- [Smpmp, "1.11.0"]
- [U, "1.0.0"]
- [Zifencei, "2.0.0"]
- [Sv32, "1.11.0"]

params:
MXLEN: 32
Expand Down Expand Up @@ -109,7 +108,7 @@ params:
false,
false,
]
STVEC_MODE_DIRECT: true
STVEC_MODE_DIRECT: false
STVEC_MODE_VECTORED: true
SATP_MODE_BARE: true
TRAP_ON_ECALL_FROM_S: true
Expand Down
Loading
Loading