Module: RubyHDL::High

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

Defined Under Namespace

Modules: SEnumerable Classes: Binary, Expression, 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.



161
162
163
164
165
166
167
168
169
170
171
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 161

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+.



1051
1052
1053
1054
1055
1056
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 1051

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

.global_sblockObject



144
145
146
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 144

def self.global_sblock
  SBLOCK_STACK[0]
end

.pop_sblockObject



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

def self.pop_sblock
  SBLOCK_STACK.pop
end

.push_sblock(sblock) ⇒ Object



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

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

.top_sblockObject



148
149
150
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 148

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.



3858
3859
3860
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 3858

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

#input(*names) ⇒ Object

Create a 1-bit input signal.



3848
3849
3850
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 3848

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

#output(*names) ⇒ Object

Create a 1-bit output signal.



3853
3854
3855
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 3853

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

#sdef(name, &ruby_block) ⇒ Object

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



3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 3863

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+



3841
3842
3843
3844
3845
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 3841

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+.



1696
1697
1698
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 1696

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.



1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 1704

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