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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
/test/tmp/
/test/version_tmp/
/tmp/
/sim_lib/generated
IR.json
IR.yaml
/lib/Devices/serial.c

# Used by dotenv library to load environment variables.
# .env
Expand Down
37 changes: 5 additions & 32 deletions lib/ADL/builder.rb
Original file line number Diff line number Diff line change
@@ -1,35 +1,8 @@
require_relative "scope"
require "Common/scope"
require "Utility/type"

module SimInfra
class IrStmt
attr_reader :name, :oprnds, :attrs
def initialize(name, oprnds, attrs)
@name = name; @oprnds = oprnds; @attrs = attrs;
end

def to_h
{
name: @name,
oprnds: @oprnds.map { |o|
if o.class == Var || o.class == Constant
o.to_h
else
o
end
},
attrs: @attrs,
}
end

def self.from_h(h)
IrStmt.new(h[:name], h[:oprnds], h[:attrs])
end
end
end

# Basics
module SimInfra
module Protea
def assert(condition, msg = nil); raise msg if !condition; end

@@instructions = []
Expand Down Expand Up @@ -75,7 +48,7 @@ def self.from_h(h)
end

class InstructionInfoBuilder
include SimInfra
include Protea

def initialize(name, feature)
@info = InstructionInfo.new(name, feature)
Expand Down Expand Up @@ -127,7 +100,7 @@ def Instruction(name, &block)
end

class InterfaceBuilder
include SimInfra
include Protea

def function(name, output_types = [], input_types = [])
@@interface_functions << {:name => name, :return_types => output_types, :argument_types => input_types}
Expand Down Expand Up @@ -201,7 +174,7 @@ def RegFiles()
end

# * generate precise fields
module SimInfra
module Protea
class RegisterFileBuilder
def r32(sym, *args)
@info.regs << Register.new(sym, 32, args[0] ? [args[0]] : [])
Expand Down
4 changes: 2 additions & 2 deletions lib/ADL/base.rb → lib/Common/base.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative "value"
# Testing infra

module SimInfra
module Protea
# @@instructions -array of instruction description
# shows result of our tests in interactive Ruby (IRB) or standalone
def self.serialize(msg= nil)
Expand Down Expand Up @@ -44,7 +44,7 @@ def self.state
end

# reset state
def siminfra_reset_module_state; @@instructions = []; end
def Protea_reset_module_state; @@instructions = []; end

# mixin for global counter, function returns 0,1,2,....
module GlobalCounter
Expand Down
58 changes: 50 additions & 8 deletions lib/ADL/scope.rb → lib/Common/scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,41 @@
require_relative 'var'
require 'Utility/type'

module SimInfra
module Protea
class IrStmt
attr_reader :name, :oprnds, :attrs
def initialize(name, oprnds, attrs)
@name = name; @oprnds = oprnds; @attrs = attrs;
end

def to_h
{
name: @name,
oprnds: @oprnds.map { |o|
if o.class == Var || o.class == Constant
o.to_h
else
o
end
},
attrs: @attrs,
}
end

def self.from_h(h)
IrStmt.new(h[:name], h[:oprnds], h[:attrs])
end
end
end

module Protea
def assert(condition, msg = nil)
raise msg unless condition
end

class Scope
include GlobalCounter # used for temp variables IDs
include SimInfra
include Protea

attr_reader :tree, :vars, :parent, :mem

Expand All @@ -21,18 +48,19 @@ def initialize(parent)
end
# resolve allows to convert Ruby Integer constants to Constant instance

def var(name, type, attrs = nil)
method(name, type)
def var(name, type, attrs = nil, plod_type = Type::Empty.new())
method(name, type, nil, plod_type)
stmt :new_var, [@vars[name]], attrs # returns @vars[name]
end

def method(name, type, regset = nil)
@vars[name] = SimInfra::Var.new(self, name, type, regset) # return var
def method(name, type, regset = nil, plod_type = Type::Empty.new())
@vars[name] = Protea::Var.new(self, name, type, regset, plod_type) # return var
instance_eval "def #{name}(); return @vars[:#{name}]; end", __FILE__, __LINE__
@vars[name]
end

def rmethod(name, regset, type)
@vars[name] = SimInfra::Var.new(self, name, type, regset) # return var
@vars[name] = Protea::Var.new(self, name, type, regset) # return var
instance_eval "def #{name}(); return @vars[:#{name}]; end", __FILE__, __LINE__
end

Expand Down Expand Up @@ -152,7 +180,7 @@ def arlet(sym, regset, attrs, type, expr)

def branch(expr) = stmt(:branch, [expr])

private def tmpvar(type) = var("_tmp#{next_counter}".to_sym, type)
private def tmpvar(type, plod_type = Type::Empty.new()) = var("_tmp#{next_counter}".to_sym, type, nil, plod_type)
# stmtadds statement into tree and retursoperand[0]
# which result in near all cases
def stmt(name, operands, attrs = nil)
Expand All @@ -173,6 +201,20 @@ def read_transform(operation_name, op)
end
end

# PLOD specific part

def get_field(expr, lsb, type) = stmt(:get_field, [tmpvar(type), expr, lsb])


def get_container_element(plod_type, container, idx) = stmt(:get, [tmpvar(plod_type.name, plod_type), container, idx])

def insert_var(name, var)
var.scope = self
@vars[name] = var
instance_eval "def #{name}(); return @vars[:#{name}]; end", __FILE__, __LINE__
var
end

def to_h
{
tree: @tree.map(&:to_h)
Expand Down
71 changes: 71 additions & 0 deletions lib/Common/type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# frozen_string_literal: true

# Main module of Protea
module Protea
# Value class is a super class of Variable or Constant.
module Type
# Base module for every type
module TypeObject end

# TODO
module EmptyInterface end

def self.TypeObject(type_name, *fields_with_inter)
interface = EmptyInterface

if fields_with_inter.last.is_a?(Module)
interface = fields_with_inter.last
fields_with_inter.pop
end

Class.new(Struct.new(*fields_with_inter)) do
include TypeObject

define_method(:name) do
field_names = {}

to_h.each do |key, value|
field_names[key] = value.to_s
end

type_name = type_name.to_s
(type_name % field_names).to_sym
end

define_method(:to_s) do
name
end

define_method(:inject) do |var|
var.extend(interface)
end
end
end

# Empty type for ADL var
Empty = TypeObject(:empty)

# Just Int
Int = TypeObject(:int)

# TODO
module ArrayInter
def get(index)
@scope.get_container_element(plod_type.stored_type, self, index)
end

def set(index, value)
@scope.stmt(:set, [self, index, value])
end

def +(value)
@scope.stmt(:let, [self, value])
end
end

Array = TypeObject('%{stored_type}[%{size}]', :stored_type, :size, ArrayInter)

# Analogue of array
Bitvector = TypeObject('b%{size}', :size)
end
end
2 changes: 1 addition & 1 deletion lib/ADL/value.rb → lib/Common/value.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module SimInfra
module Protea
# Value class is a super class of Variable or Constant.
class Value
# If value is nil then Value represents a variable.
Expand Down
34 changes: 19 additions & 15 deletions lib/ADL/var.rb → lib/Common/var.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
require_relative 'base'
require_relative 'type'
require 'Utility/type'

module SimInfra
module Protea
class Var
include SimInfra
attr_reader :scope, :name, :type, :regset
include Protea
attr_reader :name, :regset, :plod_type
attr_accessor :scope, :type

def initialize(scope, name, type, regset = nil)
def initialize(scope, name, type, regset = nil, plod_type = Type::Empty.new())
@scope = scope
@name = name
@type = type
@regset = regset
@plod_type = plod_type
@plod_type.inject(self)
end

# Syntax "var[]=value" is used to assign variable
Expand All @@ -37,7 +41,7 @@ def self.from_h(h, scope)
end
end

module SimInfra
module Protea
#
class Var
def +(other) = @scope.add(self, other)
Expand All @@ -60,16 +64,16 @@ def s = @scope.cast(self, ('s' + Utility.get_type(@type).bitsize.to_s).to_sym)
def b = @scope.cast(self, ('b' + Utility.get_type(@type).bitsize.to_s).to_sym)
def r(regset) = @scope.get_reg(self, regset, ('r' + Utility.get_type(@type).bitsize.to_s).to_sym)

def method_missing(name, *regset)
if regset.empty?
instance_eval "def #{name}(); @scope.cast(self, (#{name}).to_sym); end", __FILE__, __LINE__
@scope.cast(self, name.to_sym)
else
instance_eval "def #{name}(regset); @scope.get_reg(self, regset, (#{name}).to_sym); end", __FILE__,
__LINE__ - 1
@scope.get_reg(self, *regset, name.to_sym)
end
end
# def method_missing(name, *regset)
# if regset.empty?
# instance_eval "def #{name}(); @scope.cast(self, (#{name}).to_sym); end", __FILE__, __LINE__
# @scope.cast(self, name.to_sym)
# else
# instance_eval "def #{name}(regset); @scope.get_reg(self, regset, (#{name}).to_sym); end", __FILE__,
# __LINE__ - 1
# @scope.get_reg(self, *regset, name.to_sym)
# end
# end

def set_regset(regset)
@regset = regset
Expand Down
Loading