From a2fdd8547e061811eaaa6a6bd88ff387624432da Mon Sep 17 00:00:00 2001 From: uslstenn Date: Sun, 7 Jun 2026 18:38:13 +0300 Subject: [PATCH 1/4] [lib] Memory ifaces dynamic registry supported * Memory interfaces registration was supported * Minor formatting --- lib/ADL/base.rb | 27 ++++++++++++++++++--- lib/ADL/builder.rb | 60 +++++++++++++++++++++++----------------------- lib/ADL/scope.rb | 15 ++++++++++-- 3 files changed, 67 insertions(+), 35 deletions(-) diff --git a/lib/ADL/base.rb b/lib/ADL/base.rb index 4eb5910..baa65aa 100644 --- a/lib/ADL/base.rb +++ b/lib/ADL/base.rb @@ -4,12 +4,33 @@ module SimInfra # @@instructions -array of instruction description # shows result of our tests in interactive Ruby (IRB) or standalone + @@regfiles = [] unless defined?(@@regfiles) + @@interface_functions = [] unless defined?(@@interface_functions) + @@instructions = [] unless defined?(@@instructions) + + def self.register_memory_interface(name, return_types, argument_types) + # check whether the interface has already been registered before + exists = @@interface_functions.any? do |f| + f[:name] == name && + f[:return_types] == return_types && + f[:argument_types] == argument_types + end + unless exists + @@interface_functions << { + name: name, + return_types: return_types, + argument_types: argument_types, + kind: :memory + } + end + end + def self.serialize(msg= nil) require 'yaml' yaml_data = YAML.dump( { regfiles: @@regfiles.map(&:to_h), - interface_functions: @@interface_functions.map(&:to_h), + interface_functions: @@interface_functions.map { |f| f.reject { |k| k == :kind } }, instructions: @@instructions.map(&:to_h), } ) @@ -17,10 +38,10 @@ def self.serialize(msg= nil) end def self.state - yaml_data = YAML.dump( + YAML.dump( { regfiles: @@regfiles.map(&:to_h), - interface_functions: @@interface_functions.map(&:to_h), + interface_functions: @@interface_functions.map { |f| f.reject { |k| k == :kind } }, instructions: @@instructions.map(&:to_h), } ) diff --git a/lib/ADL/builder.rb b/lib/ADL/builder.rb index 9c31471..e15ec5d 100644 --- a/lib/ADL/builder.rb +++ b/lib/ADL/builder.rb @@ -29,7 +29,7 @@ def self.from_h(h) end # Basics -module SimInfra +module SimInfra def assert(condition, msg = nil); raise msg if !condition; end @@instructions = [] @@ -75,15 +75,16 @@ def self.from_h(h) class InstructionInfoBuilder include SimInfra - def initialize(name, feature) - @info = InstructionInfo.new(name, feature) - @info.code = Scope.new(nil) + def initialize(name, feature) + @info = InstructionInfo.new(name, feature) + @info.code = Scope.new(nil) @@interface_functions.each do |func| + next if func[:kind] == :memory if !func[:return_types].empty? @info.code.instance_eval "def #{func[:name]}(*args) in_s = *args.map { |a| resolve_const(a) } - in_stmt = [tmpvar(#{func[:return_types][0]})] + in_stmt = [tmpvar(#{func[:return_types][0]})] in_stmt.concat(in_s) return stmt :#{func[:name]}, in_stmt end @@ -101,10 +102,10 @@ def initialize(name, feature) end def encoding(frmt, fields, *args) - @info.fields = fields - @info.frmt= frmt - map args - + @info.fields = fields + @info.frmt= frmt + map args + sum_bits = 0 for f in fields sum_bits += Utility.get_type(f.value.type).bitsize @@ -132,7 +133,6 @@ def Function(name, output_types = [], input_types = []) def Interface(&blck) bldr = InterfaceBuilder.new() - bldr.instance_eval &blck end @@ -176,27 +176,27 @@ def self.from_h(h) end @@regfiles = [] -class RegisterFileBuilder - attr_reader :info - - def initialize(name) - @info = RegisterFileInfo.new(name) - @info.regs = [] - end - - def method_missing(name, *args) - if name.to_s.start_with?('r') - size = name.to_s[1..].to_i - instance_eval "def #{name}(sym, *args); @info.regs << Register.new(sym, #{size}, args.size > 0 ? args : []); end", __FILE__, __LINE__ - @info.regs << Register.new(args[0], size, args.size > 1 ? args[1..] : []) - else - error "Unknown method #{name}" + class RegisterFileBuilder + attr_reader :info + + def initialize(name) + @info = RegisterFileInfo.new(name) + @info.regs = [] + end + + def method_missing(name, *args) + if name.to_s.start_with?('r') + size = name.to_s[1..].to_i + instance_eval "def #{name}(sym, *args); @info.regs << Register.new(sym, #{size}, args.size > 0 ? args : []); end", __FILE__, __LINE__ + @info.regs << Register.new(args[0], size, args.size > 1 ? args[1..] : []) + else + error "Unknown method #{name}" + end + end + + def zero = :zero + def pc = :pc end - end - - def zero = :zero - def pc = :pc -end def RegisterFile(name, &block) bldr = RegisterFileBuilder.new(name) diff --git a/lib/ADL/scope.rb b/lib/ADL/scope.rb index 2175a7e..bfa1a99 100644 --- a/lib/ADL/scope.rb +++ b/lib/ADL/scope.rb @@ -106,8 +106,19 @@ def zext(a, type) = stmt(:zext, [tmpvar(type), a]) def get_reg(expr, regset, type) = rlet("_reg_#{next_counter}".to_sym, regset, type, expr) def write(rfile, reg, expr) = stmt(:write, [rfile, reg, expr]) - def writeMem(addr, expr) = stmt(:writeMem, [addr, expr]) - def readMem(addr, type) = stmt(:readMem, [tmpvar(type), addr]) + + def writeMem(addr, expr) + arg_types = [addr.type, expr.type].map { |t| t.is_a?(Symbol) ? t : t.type } + SimInfra.register_memory_interface(:writeMem, [], arg_types) + stmt(:writeMem, [addr, expr]) + end + + def readMem(addr, type) + arg_types = [addr.type] + SimInfra.register_memory_interface(:readMem, [type], arg_types) + v = tmpvar(type) + stmt(:readMem, [v, addr]) + end def read(rfile, reg) v = tmpvar(:b32) From 0da294366bb11028ae55ee85395733242366b7a0 Mon Sep 17 00:00:00 2001 From: uslstenn Date: Mon, 15 Jun 2026 16:50:03 +0300 Subject: [PATCH 2/4] [ADL, ser] Memory Interface names weere committed on ADL side * :writeMem, :readMem statements were preserved for native simulator gen (backward compatibility) * Memory Interfaces (function names) were set as statement attributes --- lib/ADL/base.rb | 4 ++-- lib/ADL/scope.rb | 24 +++++++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/lib/ADL/base.rb b/lib/ADL/base.rb index baa65aa..f33fb2b 100644 --- a/lib/ADL/base.rb +++ b/lib/ADL/base.rb @@ -30,7 +30,7 @@ def self.serialize(msg= nil) yaml_data = YAML.dump( { regfiles: @@regfiles.map(&:to_h), - interface_functions: @@interface_functions.map { |f| f.reject { |k| k == :kind } }, + interface_functions: @@interface_functions.map(&:to_h), instructions: @@instructions.map(&:to_h), } ) @@ -41,7 +41,7 @@ def self.state YAML.dump( { regfiles: @@regfiles.map(&:to_h), - interface_functions: @@interface_functions.map { |f| f.reject { |k| k == :kind } }, + interface_functions: @@interface_functions.map(&:to_h), instructions: @@instructions.map(&:to_h), } ) diff --git a/lib/ADL/scope.rb b/lib/ADL/scope.rb index bfa1a99..0ebd1d6 100644 --- a/lib/ADL/scope.rb +++ b/lib/ADL/scope.rb @@ -107,17 +107,31 @@ def get_reg(expr, regset, type) = rlet("_reg_#{next_counter}".to_sym, regset, ty def write(rfile, reg, expr) = stmt(:write, [rfile, reg, expr]) + def memory_interface_name(base_name, types) + suffix = nil + if base_name == :readMem + type = types.first + suffix = type.to_s.match(/\d+/)[0] if type && type.to_s =~ /b\d+|r\d+/ + elsif base_name == :writeMem + type = types[1] if types.size > 1 + suffix = type.to_s.match(/\d+/)[0] if type && type.to_s =~ /b\d+|r\d+/ + end + suffix ? "#{base_name}#{suffix}".to_sym : base_name + end + def writeMem(addr, expr) - arg_types = [addr.type, expr.type].map { |t| t.is_a?(Symbol) ? t : t.type } - SimInfra.register_memory_interface(:writeMem, [], arg_types) - stmt(:writeMem, [addr, expr]) + arg_types = [addr.type, expr.type] + iface_name = memory_interface_name(:writeMem, arg_types) + SimInfra.register_memory_interface(iface_name, [], arg_types) + stmt(:writeMem, [addr, expr], iface_name) end def readMem(addr, type) arg_types = [addr.type] - SimInfra.register_memory_interface(:readMem, [type], arg_types) + iface_name = memory_interface_name(:readMem, [type]) + iface = SimInfra.register_memory_interface(iface_name, [type], arg_types) v = tmpvar(type) - stmt(:readMem, [v, addr]) + stmt(:readMem, [v, addr], iface_name) end def read(rfile, reg) From 8138f09905db6df85000e441e111653dcda0187f Mon Sep 17 00:00:00 2001 From: uslstenn Date: Mon, 15 Jun 2026 16:57:28 +0300 Subject: [PATCH 3/4] [simgen] CPU State codegen was unified * TODO: * move cpu_state.rb into common part of the sim gen scripting * Memory Access implementations were temporarily placed into arch specific sim library cpu_state_ext.cc --- sim_gen/CPUState/cpu_state.rb | 2 +- sim_lib/Target/RISCV/cpu_state_ext.cc | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/sim_gen/CPUState/cpu_state.rb b/sim_gen/CPUState/cpu_state.rb index f7d97c1..820620f 100644 --- a/sim_gen/CPUState/cpu_state.rb +++ b/sim_gen/CPUState/cpu_state.rb @@ -164,7 +164,7 @@ module SimGen module CPUState module Header module_function - + def generate_cpu_state(input_ir) pc_decl = Helper.generate_pc_decl(input_ir[:regfiles]) pc_functions = Helper.generate_pc_functions(input_ir[:regfiles]) diff --git a/sim_lib/Target/RISCV/cpu_state_ext.cc b/sim_lib/Target/RISCV/cpu_state_ext.cc index 4389d9e..1140fc3 100644 --- a/sim_lib/Target/RISCV/cpu_state_ext.cc +++ b/sim_lib/Target/RISCV/cpu_state_ext.cc @@ -1,4 +1,5 @@ #include "cpu_state.hh" +#include namespace prot::state { @@ -13,4 +14,26 @@ void CPU::sysCall() { } } +void CPU::writeMem8(uint32_t addr, uint8_t value) { + m_memory->write(addr, value); +} + +void CPU::writeMem16(uint32_t addr, uint16_t value) { + m_memory->write(addr, value); +} + +void CPU::writeMem32(uint32_t addr, uint32_t value) { + m_memory->write(addr, value); +} + +uint8_t CPU::readMem8(uint32_t addr) { return m_memory->read(addr); } + +uint16_t CPU::readMem16(uint32_t addr) { + return m_memory->read(addr); +} + +uint32_t CPU::readMem32(uint32_t addr) { + return m_memory->read(addr); +} + } // namespace prot::state From 23603a773dd5173f9b95b99f05a367e3d2eb6228 Mon Sep 17 00:00:00 2001 From: uslsteen Date: Tue, 27 Oct 2026 15:54:33 +0300 Subject: [PATCH 4/4] [ADL] Updated Interfaces registry & processing --- lib/ADL/base.rb | 17 ----------------- lib/ADL/builder.rb | 12 +++++++++--- lib/ADL/scope.rb | 34 ++++++++++++++-------------------- lib/Target/RISC-V/32I.rb | 8 +++++++- 4 files changed, 30 insertions(+), 41 deletions(-) diff --git a/lib/ADL/base.rb b/lib/ADL/base.rb index f33fb2b..469dd62 100644 --- a/lib/ADL/base.rb +++ b/lib/ADL/base.rb @@ -8,23 +8,6 @@ module SimInfra @@interface_functions = [] unless defined?(@@interface_functions) @@instructions = [] unless defined?(@@instructions) - def self.register_memory_interface(name, return_types, argument_types) - # check whether the interface has already been registered before - exists = @@interface_functions.any? do |f| - f[:name] == name && - f[:return_types] == return_types && - f[:argument_types] == argument_types - end - unless exists - @@interface_functions << { - name: name, - return_types: return_types, - argument_types: argument_types, - kind: :memory - } - end - end - def self.serialize(msg= nil) require 'yaml' yaml_data = YAML.dump( diff --git a/lib/ADL/builder.rb b/lib/ADL/builder.rb index e15ec5d..6525f98 100644 --- a/lib/ADL/builder.rb +++ b/lib/ADL/builder.rb @@ -53,9 +53,9 @@ def to_h fields: @fields.map { |f| f.to_h }, frmt: @frmt, asm_str: @asm_str, + feature: @feature, code: @code.to_h, map: @map.to_h, - feature: @feature, } end @@ -126,8 +126,14 @@ def Instruction(name, &block) class InterfaceBuilder include SimInfra - def Function(name, output_types = [], input_types = []) - @@interface_functions << {:name => name, :return_types => output_types, :argument_types => input_types} + def Function(name, return_types: [], argument_types: [], attrs: [], kind: nil) + @@interface_functions << { + name: name, + return_types: return_types, + argument_types: argument_types, + attrs: attrs, + kind: kind, + } end end diff --git a/lib/ADL/scope.rb b/lib/ADL/scope.rb index 0ebd1d6..1c82fc3 100644 --- a/lib/ADL/scope.rb +++ b/lib/ADL/scope.rb @@ -107,31 +107,25 @@ def get_reg(expr, regset, type) = rlet("_reg_#{next_counter}".to_sym, regset, ty def write(rfile, reg, expr) = stmt(:write, [rfile, reg, expr]) - def memory_interface_name(base_name, types) - suffix = nil - if base_name == :readMem - type = types.first - suffix = type.to_s.match(/\d+/)[0] if type && type.to_s =~ /b\d+|r\d+/ - elsif base_name == :writeMem - type = types[1] if types.size > 1 - suffix = type.to_s.match(/\d+/)[0] if type && type.to_s =~ /b\d+|r\d+/ - end - suffix ? "#{base_name}#{suffix}".to_sym : base_name - end - def writeMem(addr, expr) - arg_types = [addr.type, expr.type] - iface_name = memory_interface_name(:writeMem, arg_types) - SimInfra.register_memory_interface(iface_name, [], arg_types) - stmt(:writeMem, [addr, expr], iface_name) + iface = @@interface_functions.find do |f| + f[:kind] == :memory && + f[:name].to_s.start_with?('writeMem') && + f[:argument_types] == [addr.type, expr.type] + end + raise "no memory interface declared for writeMem of #{expr.type}" unless iface + stmt(:writeMem, [addr, expr], iface[:name]) end def readMem(addr, type) - arg_types = [addr.type] - iface_name = memory_interface_name(:readMem, [type]) - iface = SimInfra.register_memory_interface(iface_name, [type], arg_types) + iface = @@interface_functions.find do |f| + f[:kind] == :memory && + f[:name].to_s.start_with?('readMem') && + f[:return_types] == [type] + end + raise "no memory interface declared for readMem of #{type}" unless iface v = tmpvar(type) - stmt(:readMem, [v, addr], iface_name) + stmt(:readMem, [v, addr], iface[:name]) end def read(rfile, reg) diff --git a/lib/Target/RISC-V/32I.rb b/lib/Target/RISC-V/32I.rb index 95523dd..890ac1a 100644 --- a/lib/Target/RISC-V/32I.rb +++ b/lib/Target/RISC-V/32I.rb @@ -7,7 +7,13 @@ module RV32I extend SimInfra Interface { - Function(:sysCall) + Function(:sysCall, kind: :cpu) + Function(:readMem8, return_types: [:b8], argument_types: [:b32], kind: :memory) + Function(:readMem16, return_types: [:b16], argument_types: [:b32], kind: :memory) + Function(:readMem32, return_types: [:b32], argument_types: [:b32], kind: :memory) + Function(:writeMem8, argument_types: [:b32, :b8], kind: :memory) + Function(:writeMem16, argument_types: [:b32, :b16], kind: :memory) + Function(:writeMem32, argument_types: [:b32, :r32], kind: :memory) } RegisterFile(:XRegs) {