0

我通过主流程文件中的选项哈希传递了一些参数:

Flow.create(environment: :ws, interface: 'MyTestLibrary::Interface', lib_version: Origen.top_level.lib_version) do
  import "components/bist"
  import "components/func"
  pass 1, softbin: 55
end

问题是当调用其他子流时选项不会保持不变。这是第一次调用测试接口时的撬动会话:

    14: def initialize(options = {})
    15:   options = {
    16:     lib_version: nil
    18:   }.merge!(options)
 => 19:   binding.pry
[1] pry(#<MyTestLibrary::Interface>)> options
=> {:lib_version=>"3.14", :environment=>:ws, :interface=>"MyTestLibrary::Interface"}

但是,这是第二次命中相同断点时的 pry 会话:

[1] pry(#<MyTestLibrary::Interface>)> options
=> {:lib_version=>nil}

我想我有几个问题:

  1. 主要流程选项不应该对子流程保持不变,而不需要对用户进行额外的工作吗?
  2. 为什么要重新初始化接口?似乎每个生成命令应该只发生一次。

提前谢谢

  • 编辑 *

@Ginty,您在回答中说:

就传递到顶级流程的选项而言,实际上并不能保证将它们传递给初始化。相反,如果接口想要拦截它们,则应该创建启动和关闭方法:

但是在文档中,我看到以下内容:

要运行一个接口,它必须实现您的流程将调用的所有方法。还习惯于创建一个初始化方法,该方法将捕获传递给 Flow.create 的任何选项(例如在我们的流示例中将环境声明为探针)。

此外,启动方法看起来像是在接口初始化后运行的回调。在接口完成初始化之前,我使用选项散列传递的信息是必需的。这不是造成下游用户不需要担心的脆弱的运行顺序依赖性吗?问候

4

1 回答 1

1

假设我们有两个顶级流和一个流组件:

# program/prb1.rb
Flow.create interface: 'MyApp::Interface', temperature: 25 do
  import 'components/ram'
end

# program/prb2.rb
Flow.create interface: 'MyApp::Interface', temperature: 125 do
  import 'components/ram'
end

# program/components/_ram.rb
Flow.create do |options|

end

而这个界面:

module MyApp
  class Interface
    include OrigenTesters::ProgramGenerators

    def initialize(options = {})
      puts "New interface!"
      puts "The temperature is: #{options[:temperature]}"
      super
    end
  end
end

然后,如果我们通过在程序目录上运行 prog gen 来生成两个流origen p program,那么我们会看到接口被实例化了两次,每个顶级流一次:

$ origen p program
[INFO]       0.006[0.006]    || **********************************************************************
[INFO]       0.010[0.004]    || Generating... prb1.rb
New interface!
The temperature is: 25
[INFO]       0.024[0.014]    || Generating... prb2.rb
New interface!
The temperature is: 125
[INFO]       0.052[0.028]    || Writing... prb1.tf
[INFO]       0.053[0.001]    || *** NEW FILE *** To save it:  cp output/testflow/mfh.testflow.group/prb1.tf .ref/prb1.tf
[INFO]       0.054[0.000]    || **********************************************************************
[INFO]       0.058[0.004]    || Writing... prb2.tf
[INFO]       0.059[0.001]    || *** NEW FILE *** To save it:  cp output/testflow/mfh.testflow.group/prb2.tf .ref/prb2.tf
[INFO]       0.059[0.000]    || **********************************************************************
Referenced pattern list written to: list/referenced.list
[INFO]       0.061[0.002]    || *** NEW FILE *** To save it:  cp list/referenced.list .ref/referenced.list
[INFO]       0.061[0.000]    || **********************************************************************

因此,从输出中我们可以看到创建了接口的两个实例,每个生成的顶级流一个,传递给的选项Pattern.create被传递到接口的初始化方法。

请注意,当顶级流导入子流/组件时,不会实例化新接口。

原来,每次Flow.create遇到都会创建一个新的接口实例,也就是重新加载目标的时间。我们这样做是因为我们在早期实现中看到了目标在整个流程中持续存在的问题。这导致一些流生成顺序依赖性开始蔓延到某些应用程序中,例如,当您独立生成 prb1.rb 与与其他流同时生成它时,prb1.rb 的输出是不同的。因此,通过每次都从头开始,它消除了根据您的目标之前所做的事情而无意更改流输出的可能性。

但最终,我们发现在生成完整的顶级流的上下文中,我们确实需要一些持久状态来用于跟踪测试编号等事情。所以为了妥协,我们保持目标刷新每一次Flow.create,但只有在遇到新的顶级时才刷新界面Flow.create

到目前为止,这在实践中运行良好。但是,如果您觉得您需要一个为整个 Origen 程序生成命令持续存在的接口,那么您可能遇到了我们没有设想到的用例,或者可能有另一种方法可以实现您想要实现的目标.

如果需要,请打开另一个问题以提供更多详细信息。

于 2017-09-18T13:53:18.890 回答