Class: Idl::AryRangeAssignmentAst

Inherits:
AstNode
  • Object
show all
Includes:
Executable
Defined in:
lib/idl/ast.rb

Overview

represents an array range assignement

for example:

vec[8:0] = 8'd0

Instance Method Summary collapse

Constructor Details

#initialize(input, interval, variable, msb, lsb, write_value) ⇒ AryRangeAssignmentAst

Returns a new instance of AryRangeAssignmentAst.



1871
1872
1873
# File 'lib/idl/ast.rb', line 1871

def initialize(input, interval, variable, msb, lsb, write_value)
  super(input, interval, [variable, msb, lsb, write_value])
end

Instance Method Details

#execute(symtab) ⇒ void

This method returns an undefined value.

“execute” the statement by updating the variables in the symbol table

Parameters:

  • symtab (SymbolTable)

    The symbol table for the context

Raises:

  • ValueError if some part of the statement cannot be executed at compile time



1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
# File 'lib/idl/ast.rb', line 1908

def execute(symtab)
  return if variable.type(symtab).global?

  value_result = value_try do
    var_val = variable.value(symtab)

    msb_val = msb.value(symtab)
    lsb_val = lsb.value(symtab)

    type_error "MSB (#{msb_val}) is <= LSB (#{lsb_val})" if msb_val <= lsb_val

    rval_val = write_value.value(symtab)

    mask = ((1 << msb_val) - 1) << lsb_val

    var_val &= ~mask

    var_val | ((rval_val << lsb_val) & mask)
    symtab.add(variable.name, Var.new(variable.name, variable.type(symtab), var_val))
    :ok
  end
  value_else(value_result) do
    symtab.add(variable.name, Var.new(variable.name, variable.type(symtab)))
    value_error "Either the range or right-hand side of an array range assignemnt is unknown"
  end
end

#execute_unknown(symtab) ⇒ void

This method returns an undefined value.

“execute” the statement, forcing any variable assignments to an unknown state This is used down unknown conditional paths.

Parameters:

  • symtab (SymbolTable)

    The symbol table for the context

Raises:

  • ValueError if some part of the statement cannot be executed at compile time



1936
1937
1938
# File 'lib/idl/ast.rb', line 1936

def execute_unknown(symtab)
  symtab.add(variable.name, Var.new(variable.name, variable.type(symtab)))
end

#lsbObject



1868
# File 'lib/idl/ast.rb', line 1868

def lsb = @children[2]

#msbObject



1867
# File 'lib/idl/ast.rb', line 1867

def msb = @children[1]

#rhsObject



1903
1904
1905
# File 'lib/idl/ast.rb', line 1903

def rhs
  write_value
end

#to_idlString

Return valid IDL representation of the node (and its subtree)

Returns:

  • (String)

    IDL code for the node



1941
# File 'lib/idl/ast.rb', line 1941

def to_idl = "#{variable.to_idl}[#{msb.to_idl}:#{lsb.to_idl}] = #{write_value.to_idl}"

#type_check(symtab) ⇒ void

This method returns an undefined value.

type check this node and all children

Calls to #type and/or #value may depend on type_check being called first with the same symtab. If not, those functions may raise an AstNode::InternalError

Parameters:

Raises:



1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
# File 'lib/idl/ast.rb', line 1876

def type_check(symtab)
  variable.type_check(symtab)
  type_error "#{varible.text_value} must be integral" unless variable.type(symtab).kind == :bits
  type_errpr "Assigning to a constant" if variable.type(symtab).const?

  msb.type_check(symtab)
  lsb.type_check(symtab)

  type_error "MSB must be integral" unless msb.type(symtab).integral?
  type_error "LSB must be integral" unless lsb.type(symtab).integral?

  value_result = value_try do
    msb_value = msb.value(symtab)
    lsb_value = lsb.value(symtab)

    type_error "MSB must be > LSB" unless msb_value > lsb_value
    type_error "MSB is out of range" if msb_value >= variable.type(symtab).width
  end
  # OK, don't have to know the value

  write_value.type_check(symtab)

  unless write_value.type(symtab).integral?
    type_error "Incompatible type in range assignment"
  end
end

#variableObject



1866
# File 'lib/idl/ast.rb', line 1866

def variable = @children[0]

#write_valueObject



1869
# File 'lib/idl/ast.rb', line 1869

def write_value = @children[3]