Module: RubyHDL::High

Defined in:
lib/HDLRuby/std/sequencer_sw.rb

Defined Under Namespace

Modules: SEnumerable Classes: Binary, Expression, Print, Ref, RefIndex, RefName, RefRange, Ruby, Sblock, SblockTop, Sbreak, Scall, Scontinue, Select, SequencerT, SfunctionT, Sif, SignalI, Siter, Sloop, Sreturn, Statement, Step, Sterminate, Swhile, Sync, Transmit, Type, TypeDef, TypeFloat, TypeGen, TypeSigned, TypeStruct, TypeTuple, TypeUnsigned, TypeVector, Unary, Value

Constant Summary collapse

SBLOCK_STACK =

The stack of SW blocks.

[ SblockTop.new ]
RUBY_OPERATOR =

The translation of operators into Ruby code.

{
  # Unary operators.
  :"-@" => "-(%{l})", :"+@" => "+(%{l})", :"~" => "~(%{l})",
  :abs => "(%{l}).abs",
  :boolean => "%{l}", :bit => "%{l}", 
  :signed => "%{l}", :unsigned => "(%{l}) & 0xFFFFFFFFFFFFFFFF",

  # Binary operators.
  :"+" => "(%{l})+(%{r})", :"-" => "(%{l})-(%{r})", 
  :"*" => "(%{l})*(%{r})", :"/" => "(%{l})/(%{r})", 
  :"%" => "(%{l})%%(%{r})", :"**" => "(%{l})**(%{r})",
  :"&" => "(%{l})&(%{r})", :"|" => "(%{l})|(%{r})", 
  :"^" => "(%{l})^(%{r})",
  :"<<" => "(%{l})<<(%{r})", :">>" => "(%{l})>>(%{r})",
  :"==" => "((%{l}) & %{m}==(%{r}) & %{m}) ? 1:0", 
  :"!=" => "((%{l}) & %{m}!=(%{r}) & %{m}) ? 1:0",
  :"<" => "((%{l}) & %{m}%{s} < (%{r}) & %{m}%{s}) ? 1:0", 
  :">" => "((%{l}) & %{m}%{s} > (%{r}) & %{m}%{s}) ? 1:0", 
  :"<=" => "((%{l}) & %{m}%{s} <=(%{r}) & %{m}%{s}) ? 1:0",
  :">=" => "((%{l}) & %{m}%{s} >=(%{r}) & %{m}%{s}) ? 1:0"
}
C_OPERATOR =

The translation of operators into C code.

{
  # Unary operators.
  :"-@" => "-(%s)", :"+@" => "+(%s)", :"~" => "~(%s)",
  :abs => "(%s).abs",
  :boolean => "%s", :bit => "%s", 
  :signed => "%s", :unsigned => "(%s) & 0xFFFFFFFFFFFFFFFF",

  # Binary operators.
  :"+" => "(%s)+(%s)", :"-" => "(%s)-(%s)",  :"*" => "(%s)*(%s)",
  :"/" => "(%s)/(%s)", :"%" => "(%s)%%(%s)", :"**" => "pow((%s),(%s))",
  :"&" => "(%s)&(%s)", :"|" => "(%s)|(%s)",  :"^" => "(%s)^(%s)",
  :"<<" => "(%s)<<(%s)", :">>" => "(%s)>>(%s)",
  :"==" => "(%s)==(%s)", :"!=" => "(%s)!=(%s)",
  :"<" => "(%s)<(%s)", :">" => "(%s)>(%s)", 
  :"<=" => "(%s)<=(%s)",:">=" => "(%s)>=(%s)"
}
Void =

The void type

define_type(:void)
Bit =

The bit type.

define_type(:bit)
Signed =

The signed bit type.

define_type(:signed)
Unsigned =

The unsigned bit type.

define_type(:unsigned)
Float =

The float bit type

define_type(:float)
StringT =

The string type

define_type(:string)
@@absoluteCounter =

The absolute name counter.

-1 # The absolute name counter.
@@uniq_names =
Set.new(Symbol.all_symbols.map {|sym| sym.to_s})

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.call_sblock(m, *args, &ruby_block) ⇒ Object

Calling a method from the stack.



170
171
172
173
174
175
176
177
178
179
180
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 170

def self.call_sblock(m,*args,&ruby_block)
    SBLOCK_STACK.reverse_each do |sblock|
      if sblock.callable?(m) then
        # return sblock.callable(m,*args,&ruby_block)
        res = sblock.callable(m,*args,&ruby_block)
        return res
      end
    end
    # Method not found.
    method_missing(m,*args,&ruby_block)
end

.define_type(name) ⇒ Object

Defines a basic type +name+.



1065
1066
1067
1068
1069
1070
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 1065

def self.define_type(name)
  name = name.to_sym
  type = Type.new(name)
  self.send(:define_method,name) { type }
  return type
end

.global_sblockObject



153
154
155
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 153

def self.global_sblock
  SBLOCK_STACK[0]
end

.pop_sblockObject



165
166
167
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 165

def self.pop_sblock
  SBLOCK_STACK.pop
end

.push_sblock(sblock) ⇒ Object



161
162
163
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 161

def self.push_sblock(sblock)
  SBLOCK_STACK << sblock
end

.top_sblockObject



157
158
159
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 157

def self.top_sblock
  SBLOCK_STACK[-1]
end

.uniq_name(base = "") ⇒ Object

Generates an absolute uniq name.



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 25

def self.uniq_name(base = "")
  @@absoluteCounter += 1
  name = base.to_s + ":#{@@absoluteCounter}"
  if @@uniq_names.include?(name) then
    # The symbol exists, try again.
    return self.uniq_name
  else
    @@uniq_names.add(name)
    return name.to_sym
  end
end

Instance Method Details

#inner(*names) ⇒ Object

Create a 1-bit inner signal.



3935
3936
3937
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 3935

def inner(*names)
  return [1].inner(*names)
end

#input(*names) ⇒ Object

Create a 1-bit input signal.



3925
3926
3927
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 3925

def input(*names)
  return [1].input(*names)
end

#output(*names) ⇒ Object

Create a 1-bit output signal.



3930
3931
3932
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 3930

def output(*names)
  return [1].output(*names)
end

#sdef(name, &ruby_block) ⇒ Object

Create a new function named +name+, built using block +ruby_block+.



3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 3940

def sdef(name,&ruby_block)
  name = name.to_sym
  # Get the arguments of the ruby_block.
  block_args = ruby_block.parameters.map {|typ,name| name.to_s }
  # Create function.
  cur_sblock = RubyHDL::High.top_sblock
  # Register the call.
  cur_sblock.register(name.to_sym) do |*args|
    # Create the function.
    # Get the current sequencer.
    cur_seq = RubyHDL::High.top_sblock.sequencer
    # Get the function from the sequencer if any.
    function = cur_seq.sfunction(name)
    unless function then
      # There were no function for the sequencer, create it.
      # Execute the ruby block in a sequencer environment for building
      # the sblock.
      sblock = Sblock.new(cur_seq,&ruby_block)
      # Create the arguments.
      block_args.each_with_index do |block_arg,i|
        # puts "args[#{i}]=(#{args[i].name},#{args[i].type})"
        sblock.make_inners(args[i].type,block_arg.to_sym)
      end
      # Create the function.
      function = SfunctionT.new(name,sblock,*block_args)
      # Add it to the current sequencer.
      cur_seq.add_sfunction(name,function)
    end
    # And create the call
    Scall.new(function,cur_seq,*args)
  end
end

#sequencer(clk = nil, start = nil, &ruby_block) ⇒ Object

Create a new sequencer block, with clock counter +clk+ and run control +start+



3918
3919
3920
3921
3922
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 3918

def sequencer(clk = nil, start = nil, &ruby_block)
  # Ensure the clock is global.
  clk.global! if clk
  return SequencerT.new(clk,start,&ruby_block)
end

#struct(content) ⇒ Object

Creates an unnamed structure type from a +content+.



1710
1711
1712
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 1710

def struct(content)
  return TypeStruct.new(:"",:little,content)
end

#typedef(name, &ruby_block) ⇒ Object

Declares a high-level generic type named +name+, and using +ruby_block+ for construction.



1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 1718

def typedef(name, &ruby_block)
  # Ensure there is a block.
  ruby_block = proc {} unless block_given?
  type = TypeGen.new(name,&ruby_block)
  define_singleton_method(name.to_sym) do |*args|
    if (args.size < ruby_block.arity) then
      # Not enough arguments get generic type as is.
      type
    else
      # There are arguments, specialize the type.
      gtype = type.generate(*args)
      # And add it as a local type of the system.
      RubyHDL::High.top_sblock.add_type(gtype)
      gtype
    end
  end
end