Module: RubyHDL::High

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

Defined Under Namespace

Modules: SEnumerable Classes: Binary, Expression, Hif, 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"
}
PYTHON_OPERATOR =
{
  # 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})",
  :"==" => "1 if ((%{l}) & %{m}==(%{r}) & %{m}) else 0", 
  :"!=" => "1 if ((%{l}) & %{m}!=(%{r}) & %{m}) else 0",
  :"<" => "1 if ((%{l}) & %{m}%{s} < (%{r}) & %{m}%{s}) else 0", 
  :">" => "1 if ((%{l}) & %{m}%{s} > (%{r}) & %{m}%{s}) else 0", 
  :"<=" => "1 if ((%{l}) & %{m}%{s} <=(%{r}) & %{m}%{s}) else 0",
  :">=" => "1 if ((%{l}) & %{m}%{s} >=(%{r}) & %{m}%{s}) else 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+.



1106
1107
1108
1109
1110
1111
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 1106

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.



4301
4302
4303
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4301

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

#input(*names) ⇒ Object

Create a 1-bit input signal.



4291
4292
4293
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4291

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

#output(*names) ⇒ Object

Create a 1-bit output signal.



4296
4297
4298
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4296

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

#sdef(name, &ruby_block) ⇒ Object

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



4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4306

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+



4284
4285
4286
4287
4288
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4284

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



1762
1763
1764
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 1762

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.



1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 1770

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