Class: Idl::AryRangeAssignmentAst

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

Overview

represents an array range assignment

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.



1876
1877
1878
# File 'lib/idl/ast.rb', line 1876

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



1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
# File 'lib/idl/ast.rb', line 1913

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 assignment 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



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

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

#lsbObject



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

def lsb = @children[2]

#msbObject



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

def msb = @children[1]

#rhsObject



1908
1909
1910
# File 'lib/idl/ast.rb', line 1908

def rhs
  write_value
end

#to_idlString

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

Returns:

  • (String)

    IDL code for the node



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

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:



1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
# File 'lib/idl/ast.rb', line 1881

def type_check(symtab)
  variable.type_check(symtab)
  type_error "#{variable.text_value} must be integral" unless variable.type(symtab).kind == :bits
  type_error "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



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

def variable = @children[0]

#write_valueObject



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

def write_value = @children[3]