Class: RubyHDL::High::SequencerT

Inherits:
Object
  • Object
show all
Defined in:
lib/HDLRuby/std/sequencer_sw.rb

Overview

Describes a SW implementation of a sequencer.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(clk = nil, start = nil, &ruby_block) ⇒ SequencerT

Create a new sequencer block, with clock counter +clk+ and run control +start+. Note: if +clk+ is not provided no clock counter will be generate.



4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4791

def initialize(clk = nil, start = nil, &ruby_block)
  # Sets the clock counter and start control.
  @clk = clk
  @start = start
  if @start then
    this = self
    # Make @start a controlling signal.
    @start.define_singleton_method(:<=,val) do
      this.resume if val.to_i == 1
    end
  end
  # Create a set of sfunction used in the sequencer.
  @sfunctions = {}
  # Create the main block.
  @blk = RubyHDL::High::Sblock.new(self,&ruby_block)
  # Build the Ruby code.
  @source = ""
  @code = nil
  self.build_ruby
end

Instance Attribute Details

#clkObject (readonly)

The clock counter.



4786
4787
4788
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4786

def clk
  @clk
end

#sourceObject (readonly)

The source code (in ruby).



4783
4784
4785
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4783

def source
  @source
end

Instance Method Details

#add_sfunction(name, sfunction) ⇒ Object

Add a sfunction.



4813
4814
4815
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4813

def add_sfunction(name,sfunction)
  @sfunctions[name.to_sym] = sfunction
end

#alive?Boolean

Check is the sequencer can still be resumed.

Returns:

  • (Boolean)


5012
5013
5014
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 5012

def alive?
  @code.alive?
end

#build_rubyObject

Build the ruby code.



4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4828

def build_ruby
  this = self
  @source = <<-BUILD
#{RubyHDL::High.global_sblock.each_signal.map do |signal|
  # puts "for signal=#{signal.name} with type=#{signal.type}"
  case signal.dir
  when :input
    signal.to_ruby + " = RubyHDL.#{signal.name}"
  else
    signal.to_ruby + " ||= " + 
      (signal.array? ? "[*#{signal.value? ? signal.value : "nil"}]" : signal.value? ? signal.value.inspect : "0")
  end
end.join("\n")}

#{@sfunctions.map {|n,f| f.to_ruby }.join("\n\n")}

Fiber.new do
#{@blk.to_ruby}
end
BUILD
  # puts "building code_txt=" + @source
  # self.reset!
end

#clk_up(count = 1) ⇒ Object

Generate a clock up of +count+ cycles if any clock.



4969
4970
4971
4972
4973
4974
4975
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4969

def clk_up(count = 1)
  if @clk then
    return "#{clk.to_ruby} += #{count.to_i}"
  else
    return ""
  end
end

#clk_up_c(count = 1) ⇒ Object

Generate a clock up of +count+ cycles if any clock for C code.



4978
4979
4980
4981
4982
4983
4984
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4978

def clk_up_c(count = 1)
  if @clk then
    return "#{clk.to_c} += #{count.to_i};"
  else
    return ""
  end
end

#clk_up_python(l = "", count = 1) ⇒ Object

Generate a clock up of +count+ cycles if any clock.



4987
4988
4989
4990
4991
4992
4993
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4987

def clk_up_python(l="", count = 1)
  if @clk then
    return "#{l}#{clk.to_python} += #{count.to_i}"
  else
    return ""
  end
end

#reset!Object

Resets the sequencer.



5007
5008
5009
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 5007

def reset!
  @code = TOPLEVEL_BINDING.eval(@source)
end

#resumeObject Also known as: call

Executes the sequencer.



4999
5000
5001
5002
5003
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4999

def resume
  reset! unless @code
  # @code.call
  @code.resume
end

#sfunction(name) ⇒ Object

Get a sfunction by name.



4823
4824
4825
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4823

def sfunction(name)
  return @sfunctions[name.to_sym]
end

#sfunction?(name) ⇒ Boolean

Check if a sfunction is present.

Returns:

  • (Boolean)


4818
4819
4820
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4818

def sfunction?(name)
  return @sfunctions.key?(name.to_sym)
end

#to_cObject

Convert to C code.



4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4858

def to_c
  typ = nil
  res = <<-BUILDC
#include <stdio.h>

#{RubyHDL::High.global_sblock.each_signal.map do |signal|
  typ = signal.type
  if signal.value? then
    if signal.array? then
      typ.base.to_c + " " + signal.to_c + "[#{typ.size}]" " = {" + 
        signal.value.inspect[1..-2] + "};"
    else
      typ.to_c + " " + signal.to_c + "=" + signal.value.inspect + ";"
    end
  else
    if signal.array? then
      typ.base.to_c + " " + signal.to_c + "[#{typ.size}]" + " =" + typ.to_c_init + ";"
    else
      typ.to_c + " " + signal.to_c + "=" + typ.to_c_init + ";"
    end
  end
end.join("\n")}

#{@sfunctions.map {|n,f| f.to_c }.join("\n\n")}

void sequencer() #{@blk.to_c}
BUILDC
  return res
end

#to_python(l = "") ⇒ Object

Convert to Python code.



4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4889

def to_python(l = "")
  typ = nil
  res = <<-BUILDPYTHON
#{RubyHDL::High.global_sblock.each_signal.map do |signal|
  typ = signal.type
  if signal.value? then
    if signal.array? then
      res = signal.to_python + "= [0] * #{signal.type.range.size}"
      signal.value.each_with_index do |v,i|
        res += "\n" + signal.to_python + "[#{i}=#{v.to_python}]"
      end
      res
    else
      signal.to_python + "=" + signal.value.inspect
    end
  else
    if signal.array? then
      signal.to_python + " = " + typ.to_python_init
    else
      signal.to_python + "=" + typ.to_python_init
    end
  end
end.join("\n")}

#{@sfunctions.map {|n,f| f.to_c }.join("\n\n")}

def sequencer():
#{RubyHDL::High.global_sblock.each_signal.map do |signal|
   "  global #{signal.to_python}"
end.join("\n")}
#{@blk.to_python("  ")}
BUILDPYTHON
  return res
end

#to_rubyObject

Get the Ruby code.



4853
4854
4855
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4853

def to_ruby
  return @code
end

#to_tf(l = "") ⇒ Object

Convert to TensorFlow code.



4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
# File 'lib/HDLRuby/std/sequencer_sw.rb', line 4926

def to_tf(l = "")
  typ = nil
  res = <<-BUILDTF
#{RubyHDL::High.global_sblock.each_signal.map do |signal|
  typ = signal.type
  if signal.value? then
    if signal.array? then
      res = signal.to_tf + "= [0] * #{signal.type.range.size}"
      signal.value.each_with_index do |v,i|
        res += "\n" + signal.to_tf + "[#{i}]=#{v.to_tf}"
      end
      res
    else
      signal.to_tf + "=" + signal.value.inspect
    end
  else
    if signal.array? then
      signal.to_tf + " = " + typ.to_tf_init
    else
      signal.to_tf + "=" + typ.to_tf_init
    end
  end
end.join("\n")}

#{@sfunctions.map {|n,f| f.to_c }.join("\n\n")}

@tf.function
def sequencer():
#{RubyHDL::High.global_sblock.each_signal.map do |signal|
   "  global #{signal.to_tf}"
end.join("\n")}
#{@blk.to_tf("  ")}
BUILDTF
  return res
end