axi_tdl 0.0.9 → 0.0.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/gem-push.yml +44 -0
- data/.github/workflows/ruby.yml +35 -0
- data/.gitignore +3 -1
- data/.travis.yml +9 -0
- data/Gemfile +4 -0
- data/README.EN.md +322 -0
- data/README.md +24 -20
- data/Rakefile +2 -6
- data/axi_tdl.gemspec +5 -6
- data/lib/axi/AXI4/axi4_direct_B1.sv +23 -23
- data/lib/axi/AXI4/axi4_dpram_cache.sv +33 -33
- data/lib/axi/AXI4/axis_to_axi4_wr.rb +1 -0
- data/lib/axi/AXI4/axis_to_axi4_wr.sv +20 -20
- data/lib/axi/AXI4/packet_partition/axi4_partition_rd_verb.sv +32 -32
- data/lib/axi/AXI4/packet_partition/data_inf_partition.rb +2 -0
- data/lib/axi/AXI4/packet_partition/data_inf_partition.sv +71 -71
- data/lib/axi/AXI4/wide_axis_to_axi4_wr.rb +2 -1
- data/lib/axi/AXI4/wide_axis_to_axi4_wr.sv +23 -23
- data/lib/axi/AXI_stream/axi_stream_split_channel.rb +7 -1
- data/lib/axi/AXI_stream/axis_head_cut_verb.sv +6 -2
- data/lib/axi/AXI_stream/axis_insert_copy.rb +18 -4
- data/lib/axi/AXI_stream/axis_sim_master_model.rb +28 -0
- data/lib/axi/AXI_stream/axis_sim_slaver_model.rb +26 -0
- data/lib/axi/AXI_stream/axis_sim_verify_by_coe.sv +101 -0
- data/lib/axi/AXI_stream/axis_split_channel_verb.rb +2 -0
- data/lib/axi/common/common_ram_sim_wrapper.sv +9 -9
- data/lib/axi/common/common_ram_wrapper.sv +12 -12
- data/lib/axi/data_interface/data_inf_c/data_c_pipe_sync_seam.sv +26 -26
- data/lib/axi/data_interface/data_inf_c/data_c_sim_master_model.sv +69 -0
- data/lib/axi/data_interface/data_inf_c/data_c_sim_slaver_model.sv +58 -0
- data/lib/axi/data_interface/data_inf_c/logic_sim_model.sv +64 -0
- data/lib/axi/techbench/tb_axi_stream_split_channel.rb +69 -0
- data/lib/axi/techbench/tb_axi_stream_split_channel.sv +149 -0
- data/lib/axi/techbench/tb_axis_split_channel_verb.rb +69 -0
- data/lib/axi/techbench/tb_axis_split_channel_verb.sv +125 -0
- data/lib/axi_tdl.rb +1 -0
- data/lib/axi_tdl/version.rb +1 -1
- data/lib/tdl/auto_script/autogensdl.rb +16 -5
- data/lib/tdl/axi4/axi4_interconnect_verb.rb +4 -2
- data/lib/tdl/basefunc.rb +1 -0
- data/lib/tdl/class_hdl/hdl_always_comb.rb +4 -3
- data/lib/tdl/class_hdl/hdl_always_ff.rb +49 -8
- data/lib/tdl/class_hdl/hdl_assign.rb +5 -3
- data/lib/tdl/class_hdl/hdl_block_ifelse.rb +11 -9
- data/lib/tdl/class_hdl/hdl_foreach.rb +2 -2
- data/lib/tdl/class_hdl/hdl_function.rb +4 -2
- data/lib/tdl/class_hdl/hdl_generate.rb +5 -4
- data/lib/tdl/class_hdl/hdl_initial.rb +11 -10
- data/lib/tdl/class_hdl/hdl_module_def.rb +18 -1
- data/lib/tdl/class_hdl/hdl_redefine_opertor.rb +35 -14
- data/lib/tdl/class_hdl/hdl_struct.rb +1 -1
- data/lib/tdl/class_hdl/hdl_verify.rb +1 -1
- data/lib/tdl/elements/originclass.rb +6 -1
- data/lib/tdl/elements/parameter.rb +1 -1
- data/lib/tdl/examples/10_random/exp_random.sv +3 -3
- data/lib/tdl/examples/11_test_unit/dve.tcl +155 -2
- data/lib/tdl/examples/11_test_unit/exp_test_unit.rb +9 -8
- data/lib/tdl/examples/11_test_unit/exp_test_unit.sv +1 -1
- data/lib/tdl/examples/11_test_unit/modules/sub_md0.rb +6 -3
- data/lib/tdl/examples/11_test_unit/modules/sub_md0.sv +5 -5
- data/lib/tdl/examples/11_test_unit/modules/sub_md1.rb +9 -4
- data/lib/tdl/examples/11_test_unit/modules/sub_md1.sv +5 -5
- data/lib/tdl/examples/11_test_unit/tb_exp_test_unit.sv +1 -3
- data/lib/tdl/examples/11_test_unit/tu0.sv +9 -9
- data/lib/tdl/examples/11_test_unit/tu1.sv +1 -1
- data/lib/tdl/examples/1_define_module/exmple_md.sv +12 -12
- data/lib/tdl/examples/2_hdl_class/tmp/always_comb_test.sv +60 -60
- data/lib/tdl/examples/2_hdl_class/tmp/always_ff_test.sv +2 -2
- data/lib/tdl/examples/2_hdl_class/tmp/case_test.sv +17 -17
- data/lib/tdl/examples/2_hdl_class/tmp/head_pkg_module.sv +9 -9
- data/lib/tdl/examples/2_hdl_class/tmp/simple_assign_test.sv +1 -1
- data/lib/tdl/examples/2_hdl_class/tmp/state_case_test.sv +10 -10
- data/lib/tdl/examples/2_hdl_class/tmp/test_foreach.sv +3 -3
- data/lib/tdl/examples/2_hdl_class/tmp/test_function.sv +7 -7
- data/lib/tdl/examples/2_hdl_class/tmp/test_initial_assert.sv +3 -3
- data/lib/tdl/examples/2_hdl_class/tmp/test_module.sv +2 -2
- data/lib/tdl/examples/2_hdl_class/tmp/test_module_var.sv +2 -2
- data/lib/tdl/examples/2_hdl_class/tmp/test_package.sv +4 -5
- data/lib/tdl/examples/2_hdl_class/tmp/test_package2.sv +4 -4
- data/lib/tdl/examples/2_hdl_class/tmp/test_struct_function.sv +2 -2
- data/lib/tdl/examples/2_hdl_class/tmp/test_vcs_string.sv +1 -1
- data/lib/tdl/examples/2_hdl_class/tmp/text_generate.sv +7 -7
- data/lib/tdl/examples/4_generate/test_generate.sv +11 -11
- data/lib/tdl/examples/5_logic_combin/test_logic_combin.sv +3 -3
- data/lib/tdl/examples/7_module_with_package/body_package.sv +3 -4
- data/lib/tdl/examples/7_module_with_package/example_pkg.sv +4 -4
- data/lib/tdl/examples/7_module_with_package/head_package.sv +3 -4
- data/lib/tdl/examples/8_top_module/tb_test_top.sv +1 -2
- data/lib/tdl/examples/9_itegration/tb_test_tttop.sv +2 -2
- data/lib/tdl/examples/9_itegration/test_tttop.sv +3 -3
- data/lib/tdl/exlib/axis_eth_ex.rb +95 -0
- data/lib/tdl/exlib/axis_verify.rb +264 -0
- data/lib/tdl/exlib/clock_reset_verify.rb +29 -0
- data/lib/tdl/exlib/dve_tcl.rb +30 -11
- data/lib/tdl/exlib/itegration.rb +15 -3
- data/lib/tdl/exlib/logic_verify.rb +88 -0
- data/lib/tdl/exlib/test_point.rb +96 -94
- data/lib/tdl/exlib/test_point.rb.bak +293 -0
- data/lib/tdl/rebuild_ele/ele_base.rb +1 -1
- data/lib/tdl/sdlmodule/sdlmodlule_path_db.rb +34 -0
- data/lib/tdl/sdlmodule/sdlmodule.rb +18 -14
- data/lib/tdl/sdlmodule/sdlmodule_draw.rb +81 -16
- data/lib/tdl/sdlmodule/test_unit_module.rb +272 -33
- data/lib/tdl/sdlmodule/test_unit_module.rb.bak +143 -0
- data/lib/tdl/sdlmodule/top_module.rb +53 -48
- data/lib/tdl/sdlmodule/top_module.rb.bak +547 -0
- data/lib/tdl/tdl.rb +19 -4
- metadata +36 -137
- data/Gemfile.lock +0 -28
- data/lib/axi/AXI_stream/axi_stream_split_channel.sv +0 -149
- data/lib/axi/AXI_stream/axis_head_cut_verc.sv +0 -242
- data/lib/axi/AXI_stream/axis_insert_copy.sv +0 -66
- data/lib/axi/AXI_stream/axis_pipe_sync_seam.sv +0 -48
- data/lib/axi/AXI_stream/axis_rom_contect_sim.sv +0 -113
- data/lib/axi/AXI_stream/axis_split_channel_verb.sv +0 -62
@@ -0,0 +1,143 @@
|
|
1
|
+
class TestUnitModule < SdlModule
|
2
|
+
attr_accessor :dve_wave_signals
|
3
|
+
|
4
|
+
def initialize(name: "tdlmodule",out_sv_path: nil)
|
5
|
+
super(name: name,out_sv_path: out_sv_path)
|
6
|
+
@dve_wave_signals = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_unit_init(&block)
|
10
|
+
Initial do
|
11
|
+
to_down_pass <= 1.b0
|
12
|
+
initial_exec("wait(from_up_pass)")
|
13
|
+
initial_exec("$root.#{TopModule.current.techbench.module_name}.test_unit_region = \"#{module_name}\"")
|
14
|
+
block.call
|
15
|
+
to_down_pass <= 1.b1
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_to_dve_wave(tp,&block)
|
20
|
+
# @dve_wave_signals ||= []
|
21
|
+
# tps.each do |e|
|
22
|
+
# # dve_wave_signals << e.root_ref.sub("$root.","Sim:")
|
23
|
+
# @dve_wave_signals << e
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
@dve_wave_signals << tp
|
27
|
+
tp.tp_instance.filter_block = block if block_given?
|
28
|
+
# unless tp.is_a?(AxiTdl::SdlModuleActiveBaseElm)
|
29
|
+
# raise TdlError.new(" `#{tp.to_s}` is not AxiTdl::SdlModuleActiveBaseElm !!! ")
|
30
|
+
# end
|
31
|
+
# tp.instance_variable_set("@dve_wave_filter_block", block)
|
32
|
+
|
33
|
+
@dve_wave_signals
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class TdlTestUnit < TdlBuild
|
38
|
+
# return ClassHDL::AnonyModule.new
|
39
|
+
def self.method_missing(method,*args,&block)
|
40
|
+
|
41
|
+
sdlm = TestUnitModule.new(name: method,out_sv_path: args[0])
|
42
|
+
|
43
|
+
si = sdlm.input - "from_up_pass"
|
44
|
+
so = sdlm.output.logic - "to_down_pass"
|
45
|
+
|
46
|
+
@@package_names ||= []
|
47
|
+
sdlm.head_import_packages = []
|
48
|
+
sdlm.head_import_packages += @@package_names
|
49
|
+
|
50
|
+
@@package_names.each do |e|
|
51
|
+
sdlm.require_package(e,false) if e
|
52
|
+
end
|
53
|
+
@@package_names = []
|
54
|
+
sdlm.instance_exec(&block)
|
55
|
+
|
56
|
+
if args[0] && File.exist?(args[0])
|
57
|
+
sdlm.gen_sv_module
|
58
|
+
else
|
59
|
+
sdlm.origin_sv = true
|
60
|
+
end
|
61
|
+
sdlm
|
62
|
+
end
|
63
|
+
|
64
|
+
# def self.collect_unit(tu)
|
65
|
+
# @@__collect_units__ ||= []
|
66
|
+
# @@__collect_units__ << tu
|
67
|
+
# end
|
68
|
+
|
69
|
+
# def self.echo_units
|
70
|
+
# @@__collect_units__ ||= []
|
71
|
+
# index = 1
|
72
|
+
|
73
|
+
# rels = []
|
74
|
+
# @@__collect_units__.each do |ue|
|
75
|
+
# rels << " [#{index}] #{ue.origin.module_name}"
|
76
|
+
# index += 1
|
77
|
+
# end
|
78
|
+
# rels.join("\n")
|
79
|
+
# end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
class TopModule
|
84
|
+
public
|
85
|
+
def add_test_unit(*args)
|
86
|
+
@_test_unit_collect_ ||= []
|
87
|
+
@_test_unit_collect_ = @_test_unit_collect_ + args
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def _exec_add_test_unit
|
93
|
+
@_test_unit_collect_ ||= []
|
94
|
+
args = @_test_unit_collect_
|
95
|
+
self.techbench.instance_exec(args) do |args|
|
96
|
+
index = 0
|
97
|
+
last_index = 0
|
98
|
+
logic.string - 'test_unit_region'
|
99
|
+
logic[args.size] - 'unit_pass_u'
|
100
|
+
logic[args.size] - 'unit_pass_d'
|
101
|
+
|
102
|
+
nqq = args.size <= 1
|
103
|
+
args.each do |tu|
|
104
|
+
if tu.is_a? SdlModule
|
105
|
+
_inst_name_ = tu.module_name
|
106
|
+
else
|
107
|
+
_inst_name_ = tu.to_s
|
108
|
+
end
|
109
|
+
|
110
|
+
# puts _inst_name_
|
111
|
+
# puts SdlModule.call_module(_inst_name_).class
|
112
|
+
tu_inst = Instance(_inst_name_,"test_unit_#{index}") do |h|
|
113
|
+
h.input.from_up_pass (nqq ? unit_pass_u : unit_pass_u[index])
|
114
|
+
h.output.logic.to_down_pass (nqq ? unit_pass_d : unit_pass_d[index])
|
115
|
+
end
|
116
|
+
|
117
|
+
# TdlTestUnit.collect_unit tu_inst
|
118
|
+
TopModule.current.test_unit.collect_unit tu_inst
|
119
|
+
|
120
|
+
## 添加dve wave 信号
|
121
|
+
TopModule.current.test_unit.dve_wave(name: _inst_name_, signals: tu_inst.origin.dve_wave_signals )
|
122
|
+
|
123
|
+
if index == 0
|
124
|
+
Assign do
|
125
|
+
unless nqq
|
126
|
+
unit_pass_u[index] <= 1.b1
|
127
|
+
else
|
128
|
+
unit_pass_u <= 1.b1
|
129
|
+
end
|
130
|
+
end
|
131
|
+
else
|
132
|
+
|
133
|
+
Assign do
|
134
|
+
unit_pass_u[index] <= unit_pass_d[last_index]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
last_index = index
|
138
|
+
index += 1
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
@@ -431,9 +431,11 @@ class TopModule
|
|
431
431
|
# sdlm.gen_sv_module
|
432
432
|
sdlm.gen_sv_module_verb
|
433
433
|
unless sdlm.vcs_path
|
434
|
-
sdlm.test_unit.gen_dve_tcl(File.join(args[0],"dve.tcl"))
|
434
|
+
# sdlm.test_unit.gen_dve_tcl(File.join(args[0],"dve.tcl"))
|
435
|
+
SdlModule.gen_dev_wave_tcl File.join(args[0],"dve.tcl")
|
435
436
|
else
|
436
|
-
sdlm.test_unit.gen_dve_tcl(File.join(sdlm.vcs_path,"dve.tcl"))
|
437
|
+
# sdlm.test_unit.gen_dve_tcl(File.join(sdlm.vcs_path,"dve.tcl"))
|
438
|
+
SdlModule.gen_dev_wave_tcl File.join(sdlm.vcs_path,"dve.tcl")
|
437
439
|
end
|
438
440
|
sdlm.create_xdc
|
439
441
|
else
|
@@ -450,55 +452,57 @@ class TopModule
|
|
450
452
|
end
|
451
453
|
|
452
454
|
## 給TopModule 添加单元测试 方法
|
453
|
-
module TdlSpace
|
454
|
-
|
455
|
+
# module TdlSpace
|
456
|
+
# class TopModuleTestUnitRef
|
455
457
|
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
458
|
+
# def collect_unit(tu)
|
459
|
+
# @__collect_units__ ||= []
|
460
|
+
# @__collect_units__ << tu
|
461
|
+
# end
|
460
462
|
|
461
|
-
|
462
|
-
|
463
|
-
|
463
|
+
# def echo_units
|
464
|
+
# @__collect_units__ ||= []
|
465
|
+
# index = 1
|
464
466
|
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
end
|
467
|
+
# rels = []
|
468
|
+
# # __collect = TdlTestPoint.inst_collect.select { |e| e.target.belong_to_module.top_tb_ref? }
|
469
|
+
# # @__collect_units__.each do |ue|
|
470
|
+
# # tp_str = ue.origin.dve_wave_signals.select do |e|
|
471
|
+
# # e.respond_to? :tp_instance
|
472
|
+
# # end.map do |ele|
|
473
|
+
# # unless __collect.index(ele.tp_instance)
|
474
|
+
# # puts ele.name
|
475
|
+
# # end
|
476
|
+
# # " ->#{__collect.index(ele.tp_instance)+1}< :: #{ele.tp_instance.name} || #{ele.tp_instance.file}:#{ele.tp_instance.line}"
|
477
|
+
# # end.join("\n")
|
478
|
+
|
479
|
+
# # rels << " [#{index}] #{ue.origin.module_name} ::<TestPoints> \n#{tp_str}"
|
480
|
+
# # index += 1
|
481
|
+
# # end
|
482
|
+
# rels.join("\n")
|
483
|
+
# end
|
484
|
+
|
485
|
+
# def dve_wave(name: '', signals: []) #name => SdlModule instance name
|
486
|
+
# return unless signals
|
487
|
+
# @_dev_wave_ ||= Hash.new
|
488
|
+
# @_dev_wave_[name.to_s] = signals ## Signal is TdlTestPoint
|
489
|
+
# end
|
490
|
+
|
491
|
+
# def gen_dve_tcl(filename)
|
492
|
+
# File.open(filename,'w') do |f|
|
493
|
+
# f.puts TdlSpace.gen_dev_wave_tcl(@_dev_wave_ || Hash.new)
|
494
|
+
# end
|
495
|
+
# end
|
496
|
+
|
497
|
+
# end
|
498
|
+
# end
|
499
|
+
|
500
|
+
# class TopModule
|
501
|
+
# def test_unit
|
502
|
+
# @__test_unit__ ||= TdlSpace::TopModuleTestUnitRef.new
|
503
|
+
# end
|
504
|
+
|
505
|
+
# end
|
502
506
|
|
503
507
|
## 判断 是否被顶层引用
|
504
508
|
class SdlModule
|
@@ -522,6 +526,7 @@ class SdlModule
|
|
522
526
|
end
|
523
527
|
|
524
528
|
def top_tb_ref?
|
529
|
+
return false unless TopModule.current
|
525
530
|
if self == TopModule.current.techbench
|
526
531
|
return true
|
527
532
|
end
|
@@ -0,0 +1,547 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
class TopModule < SdlModule
|
3
|
+
|
4
|
+
attr_accessor :techbench,:sim,:constraint
|
5
|
+
@@curr_top_module = nil
|
6
|
+
def initialize(name:"tdlmodule",out_sv_path:nil)
|
7
|
+
@@curr_top_module = self
|
8
|
+
# set sim env
|
9
|
+
@sim = TopModule.sim
|
10
|
+
@out_sv_path = out_sv_path
|
11
|
+
# console_argvs
|
12
|
+
# TopModule.sim = @sim
|
13
|
+
@constraint = ConstraintsVerb.new
|
14
|
+
|
15
|
+
if @sim
|
16
|
+
rewrite_to_warning(out_sv_path,"#{name}.sv")
|
17
|
+
|
18
|
+
name = "#{name}_sim"
|
19
|
+
else
|
20
|
+
rewrite_to_warning(out_sv_path,"#{name}_sim.sv")
|
21
|
+
end
|
22
|
+
|
23
|
+
@techbench = TechBenchModule.new(name:"tb_#{name}",out_sv_path:out_sv_path)
|
24
|
+
rtl_top_module = super(name:name,out_sv_path:out_sv_path)
|
25
|
+
@techbench.Instance(name,"rtl_top")
|
26
|
+
rtl_top_module
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.current
|
30
|
+
@@curr_top_module
|
31
|
+
end
|
32
|
+
|
33
|
+
def pins
|
34
|
+
@pins_params
|
35
|
+
end
|
36
|
+
|
37
|
+
def load_pins(pins_file)
|
38
|
+
pins_params = YAML::load(File.open(pins_file))
|
39
|
+
|
40
|
+
pins_params = recur_pins_hash(pins_params)
|
41
|
+
|
42
|
+
pins_params.define_singleton_method("[]") do |index|
|
43
|
+
pins_params.fetch(index.to_s)
|
44
|
+
end
|
45
|
+
|
46
|
+
@pins_params = pins_params
|
47
|
+
end
|
48
|
+
|
49
|
+
def recur_pins_hash(hash)
|
50
|
+
new_hash = {}
|
51
|
+
hash.each do |k,v|
|
52
|
+
if v.is_a? Hash
|
53
|
+
hash[k] = recur_pins_hash(v)
|
54
|
+
else
|
55
|
+
if v.is_a?(String) && v=~/\s/
|
56
|
+
hash[k] = v.split(/\s+/)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
new_hash[k.to_sym] = hash[k]
|
60
|
+
end
|
61
|
+
return hash.merge(new_hash)
|
62
|
+
end
|
63
|
+
|
64
|
+
def console_argvs
|
65
|
+
# hash = Parser.parse(ARGV)
|
66
|
+
hash = $argvs_hash
|
67
|
+
if hash[:sim]
|
68
|
+
@sim = hash[:sim]
|
69
|
+
end
|
70
|
+
|
71
|
+
bi = Proc.new do
|
72
|
+
bp = File.join(@out_sv_path,"program_files/")
|
73
|
+
Dir.mkdir(bp) unless File.exist? bp
|
74
|
+
bp
|
75
|
+
end
|
76
|
+
|
77
|
+
if hash[:gold]
|
78
|
+
@constraint.image(type: :gold,next_addr:hash[:next_cfg_addr],bitpath:bi.call)
|
79
|
+
elsif hash[:update]
|
80
|
+
@constraint.image(type: :update,bitpath:bi.call)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def rewrite_to_warning(path,file_name)
|
85
|
+
unless path
|
86
|
+
_out_sv_path = './'
|
87
|
+
else
|
88
|
+
_out_sv_path = path
|
89
|
+
end
|
90
|
+
|
91
|
+
path_file_name = File.join(_out_sv_path,file_name)
|
92
|
+
|
93
|
+
return unless File.exist? path_file_name
|
94
|
+
|
95
|
+
basename = File.basename(path_file_name,'.sv')
|
96
|
+
|
97
|
+
File.open(path_file_name,'w') do |f|
|
98
|
+
str =
|
99
|
+
"
|
100
|
+
`timescale 1ns/1ps
|
101
|
+
module #{basename}();
|
102
|
+
initial begin
|
103
|
+
#(1us);
|
104
|
+
$warning(\"Check TopModule.sim,please!!!\");
|
105
|
+
$stop;
|
106
|
+
end
|
107
|
+
endmodule\n"
|
108
|
+
f.puts str
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
public
|
114
|
+
|
115
|
+
def gen_sv_module
|
116
|
+
if @sim
|
117
|
+
Tdl.Puts "INFO: JUST GEN SV[#{@module_name}] FOR SIM "
|
118
|
+
else
|
119
|
+
Tdl.Puts "INFO: JUST GEN TechBench Modules,NO SIM"
|
120
|
+
end
|
121
|
+
super
|
122
|
+
# @techbench.gen_sv_module
|
123
|
+
|
124
|
+
# exec auto gen sub TechBenchModule
|
125
|
+
TechBenchModule.gen_sv_module
|
126
|
+
end
|
127
|
+
|
128
|
+
def mix_itegrations
|
129
|
+
## 执行动态link itgt
|
130
|
+
# puts implicit_itgt_collect
|
131
|
+
self.link_eval
|
132
|
+
self.index_inst
|
133
|
+
# if implicit_itgt_collect
|
134
|
+
# ## 执行 itgt inst
|
135
|
+
# implicit_itgt_collect.reverse.each do |itgt|
|
136
|
+
# itgt.inst unless itgt.init_inst
|
137
|
+
# end
|
138
|
+
# end
|
139
|
+
#
|
140
|
+
# ## 执行 itgt inst
|
141
|
+
# @_itgt_collect_.each do |itgt|
|
142
|
+
# itgt.inst unless itgt.init_inst
|
143
|
+
# end
|
144
|
+
## 执行 itegration_verb 里面的silence
|
145
|
+
@_itgt_collect_.each do |itgt|
|
146
|
+
itgt.silence_procs_run if itgt.respond_to?('silence_procs_run')
|
147
|
+
end
|
148
|
+
|
149
|
+
if implicit_itgt_collect
|
150
|
+
## 执行 itegration_verb 里面的silence
|
151
|
+
implicit_itgt_collect.each do |itgt|
|
152
|
+
itgt.silence_procs_run if itgt.respond_to?('silence_procs_run')
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
## 生成 itgt下的子模块文件
|
157
|
+
# gen_children_modules
|
158
|
+
@_itgt_collect_.each do |itgt|
|
159
|
+
itgt.gen_children_modules()
|
160
|
+
end
|
161
|
+
|
162
|
+
if implicit_itgt_collect
|
163
|
+
## 执行 itegration_verb 里面的silence
|
164
|
+
implicit_itgt_collect.each do |itgt|
|
165
|
+
itgt.gen_children_modules()
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
def gen_sv_module_verb
|
172
|
+
mix_itegrations
|
173
|
+
## 添加测试用例 实例化
|
174
|
+
_exec_add_test_unit() if TopModule.sim
|
175
|
+
|
176
|
+
gen_sv_module
|
177
|
+
end
|
178
|
+
|
179
|
+
def parse_pin_prop(prop=nil)
|
180
|
+
return [prop["pins"],prop["iostd"],prop["pulltype"],prop["drive"]]
|
181
|
+
end
|
182
|
+
|
183
|
+
def Input(name,dsize:1,dimension:[],pin:[],iostd:[],pin_prop:nil)
|
184
|
+
pin,iostd,pulltype,drive = parse_pin_prop(pin_prop) if pin_prop
|
185
|
+
a = super(name,dsize:dsize,dimension:dimension,pin:pin,iostd:iostd,pin_prop:pin_prop)
|
186
|
+
@constraint.add_property(a,pin,iostd,pulltype,drive)
|
187
|
+
a
|
188
|
+
end
|
189
|
+
|
190
|
+
def Output(name,dsize:1,dimension:[],pin:[],iostd:[],pin_prop:nil)
|
191
|
+
pin,iostd,pulltype,drive = parse_pin_prop(pin_prop) if pin_prop
|
192
|
+
a = super(name,dsize:dsize,dimension:dimension,pin:pin,iostd:iostd,pin_prop:pin_prop)
|
193
|
+
@constraint.add_property(a,pin,iostd,pulltype,drive)
|
194
|
+
a
|
195
|
+
end
|
196
|
+
|
197
|
+
def Inout(name,dsize:1,dimension:[],pin:[],iostd:[],pin_prop:nil)
|
198
|
+
pin,iostd,pulltype,drive = parse_pin_prop(pin_prop) if pin_prop
|
199
|
+
a = super(name,dsize:dsize,dimension:dimension,pin:pin,iostd:iostd)
|
200
|
+
@constraint.add_property(a,pin,iostd,pulltype,drive)
|
201
|
+
a
|
202
|
+
end
|
203
|
+
|
204
|
+
def Clock(name,freqM:100,port: :input,pin:[],iostd:[],dsize:1,pin_prop:nil)
|
205
|
+
pin,iostd,pulltype,drive = parse_pin_prop(pin_prop) if pin_prop
|
206
|
+
a = super(name,port:port,freqM:freqM,pin:pin,iostd:iostd,dsize:dsize,pin_prop:pin_prop)
|
207
|
+
@constraint.add_property(a,pin,iostd,pulltype,drive)
|
208
|
+
a
|
209
|
+
end
|
210
|
+
|
211
|
+
def Reset(name,port: :input,active:"low",pin:[],iostd:[],dsize:1,pin_prop:nil)
|
212
|
+
pin,iostd,pulltype,drive = parse_pin_prop(pin_prop) if pin_prop
|
213
|
+
a = super(name,port:port,active:active,pin:pin,iostd:iostd,dsize:dsize,pin_prop:pin_prop)
|
214
|
+
@constraint.add_property(a,pin,iostd,pulltype,drive)
|
215
|
+
a
|
216
|
+
end
|
217
|
+
|
218
|
+
def create_xdc
|
219
|
+
return if @sim
|
220
|
+
fname = "#{module_name}_constraints.xdc"
|
221
|
+
fname = File.join(@out_sv_path,fname)
|
222
|
+
File.open(fname,'w') do |f|
|
223
|
+
f.puts @constraint.xds
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def create_add_file_tcl
|
228
|
+
return if @sim
|
229
|
+
fname = "#{module_name}_add_files.tcl"
|
230
|
+
fname = File.join(@out_sv_path,fname)
|
231
|
+
File.open(fname,'w') do |f|
|
232
|
+
f.puts("add_files \\")
|
233
|
+
# f.puts Tdl.all_file_paths.map{ |e| e[1].gsub("\\",'/') }.join("\\\n")
|
234
|
+
f.puts Tdl.all_file_paths.map{ |k,v| v.gsub("\\",'/') }.join("\\\n")
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
# def self.root_ref_signal(basele,&block) # return proc becuse top module may not be created
|
239
|
+
# if basele.is_a? BaseElm
|
240
|
+
# Proc.new do
|
241
|
+
# @@root_ref_array = []
|
242
|
+
|
243
|
+
# unless block_given?
|
244
|
+
# self.recur_ref(basele.belong_to_module,basele.signal)
|
245
|
+
# else
|
246
|
+
# self.recur_ref(basele.belong_to_module,yield(basele))
|
247
|
+
# end
|
248
|
+
|
249
|
+
# if @@root_ref_array.any?
|
250
|
+
# @@root_ref_array.first
|
251
|
+
# else
|
252
|
+
# NqString.new("")
|
253
|
+
# end
|
254
|
+
# end
|
255
|
+
# else
|
256
|
+
# raise TdlError.new("#{basele} is a #{basele.class} . Type ERROR")
|
257
|
+
# basele.to_s
|
258
|
+
# end
|
259
|
+
# end
|
260
|
+
|
261
|
+
# def self.root_ref_inst(sub_inst,port_key) # return proc becuse top module may not be created
|
262
|
+
# unless sub_inst.is_a? SdlInst
|
263
|
+
# raise TdlError.new("[KEY:#{port_key}]root_ref_inst of #{@module_name} must be a SdlInst")
|
264
|
+
# end
|
265
|
+
# Proc.new do
|
266
|
+
# basele = sub_inst[port_key]
|
267
|
+
# if basele.is_a? BaseElm
|
268
|
+
# @@root_ref_array = []
|
269
|
+
# self.recur_ref(basele.belong_to_module,basele.signal)
|
270
|
+
# if @@root_ref_array.any?
|
271
|
+
# @@root_ref_array.first
|
272
|
+
# else
|
273
|
+
# basele.to_s
|
274
|
+
# end
|
275
|
+
# elsif basele.is_a? Proc
|
276
|
+
# basele.call
|
277
|
+
# else
|
278
|
+
# basele
|
279
|
+
# end
|
280
|
+
# end
|
281
|
+
# end
|
282
|
+
|
283
|
+
# def self.root_ref_proc(block=nil) # return proc becuse top module may not be created
|
284
|
+
# Proc.new do
|
285
|
+
# if block_given?
|
286
|
+
# basele = yield
|
287
|
+
# else
|
288
|
+
# basele = block.call
|
289
|
+
# end
|
290
|
+
|
291
|
+
# if basele.is_a? BaseElm
|
292
|
+
# @@root_ref_array = []
|
293
|
+
# self.recur_ref(basele.belong_to_module,basele.signal)
|
294
|
+
# if @@root_ref_array.any?
|
295
|
+
# @@root_ref_array.first
|
296
|
+
# else
|
297
|
+
# NqString.new("")
|
298
|
+
# end
|
299
|
+
# else
|
300
|
+
# basele
|
301
|
+
# end
|
302
|
+
# end
|
303
|
+
# end
|
304
|
+
|
305
|
+
# def self.root_ref_signals(basele) # return proc becuse top module may not be created
|
306
|
+
# if basele is_a? BaseElm
|
307
|
+
# Proc.new do
|
308
|
+
# @@root_ref_array = []
|
309
|
+
# self.recur_ref(basele.belong_to_module,basele.signal)
|
310
|
+
# @@root_ref_array
|
311
|
+
# end
|
312
|
+
# else
|
313
|
+
# Proc.new { basele }
|
314
|
+
# end
|
315
|
+
# end
|
316
|
+
|
317
|
+
# def self.recur_ref(sdlmodule,collect_str)
|
318
|
+
# if sdlmodule.is_a? TopModule
|
319
|
+
# @@root_ref_array << "$root.#{sdlmodule.techbench.module_name}.#{sdlmodule.instanced_and_parent_module.keys.first}.#{collect_str}"
|
320
|
+
# else
|
321
|
+
# return nil unless sdlmodule.instanced_and_parent_module
|
322
|
+
# sdlmodule.instanced_and_parent_module.each do |k_inst,v_module|
|
323
|
+
# next_collect_str = "#{k_inst}.#{collect_str}"
|
324
|
+
# self.recur_ref(v_module,next_collect_str)
|
325
|
+
# end
|
326
|
+
# end
|
327
|
+
# end
|
328
|
+
|
329
|
+
def self.define_global(name,default_value)
|
330
|
+
# RedefOpertor.with_normal_operators do
|
331
|
+
self.class_variable_set("@@#{name.to_s}",default_value)
|
332
|
+
|
333
|
+
self.define_singleton_method(name.to_s) do
|
334
|
+
self.class_variable_get("@@#{name.to_s}")
|
335
|
+
end
|
336
|
+
|
337
|
+
self.define_singleton_method("#{name.to_s}=") do |a|
|
338
|
+
self.class_variable_set("@@#{name.to_s}",a)
|
339
|
+
end
|
340
|
+
# end
|
341
|
+
end
|
342
|
+
|
343
|
+
define_global("sim",nil)
|
344
|
+
|
345
|
+
end
|
346
|
+
## 添加 itegration verb
|
347
|
+
class TopModule
|
348
|
+
|
349
|
+
attr_accessor :implicit_itgt_collect
|
350
|
+
# attr_accessor :cal_inst_index_proc
|
351
|
+
|
352
|
+
def itgt_collect
|
353
|
+
@_itgt_collect_
|
354
|
+
end
|
355
|
+
|
356
|
+
def add_itegration(itgt_class,nickname:nil,param:{},pins_map:{},implicit:false)
|
357
|
+
@_itgt_collect_ ||= []
|
358
|
+
if pins_map.is_a? Hash
|
359
|
+
pins_map_f = pins_map
|
360
|
+
else
|
361
|
+
pins_map_f = self.pins[pins_map.to_s] || {}
|
362
|
+
end
|
363
|
+
|
364
|
+
ist = Kernel.const_get(itgt_class).new(nickname,pins_map_f,self)
|
365
|
+
@_itgt_collect_ << ist unless implicit
|
366
|
+
# ist.top_module = self
|
367
|
+
param.each do |k,v|
|
368
|
+
ist.send("#{k}=",v)
|
369
|
+
end
|
370
|
+
|
371
|
+
## 加入新的itgt时,自动link itgt
|
372
|
+
# ist.link_eval
|
373
|
+
# puts "------------------"
|
374
|
+
# ist.names_pool_inst
|
375
|
+
## 如果itgt没有上级 link 和 不是隐性添加 则直接例化
|
376
|
+
# if nickname != "implicit"
|
377
|
+
col = ist.class.get_itgt_var('itegration_link_collect',[])
|
378
|
+
if col && col.empty?
|
379
|
+
ist.inst unless ist.init_inst
|
380
|
+
ist.init_inst = true
|
381
|
+
ist.inst_index = 0
|
382
|
+
end
|
383
|
+
# end
|
384
|
+
# ist.inst
|
385
|
+
return ist
|
386
|
+
end
|
387
|
+
|
388
|
+
def link_eval
|
389
|
+
@_itgt_collect_ ||= []
|
390
|
+
|
391
|
+
@_itgt_collect_.each do |i|
|
392
|
+
i.link_eval
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
def index_inst
|
397
|
+
curr_collect = (implicit_itgt_collect || []) | @_itgt_collect_
|
398
|
+
|
399
|
+
curr_collect.each do |e|
|
400
|
+
if e.init_inst
|
401
|
+
e.cal_inst_index(0)
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
curr_collect = curr_collect.sort { |a, b| a.inst_index <=> b.inst_index }
|
406
|
+
|
407
|
+
curr_collect.each {|e| e.inst unless e.init_inst }
|
408
|
+
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
## 添加 missing
|
413
|
+
|
414
|
+
class TopModule
|
415
|
+
## vcs path
|
416
|
+
attr_accessor :vcs_path
|
417
|
+
def self.method_missing(method,*args,&block)
|
418
|
+
|
419
|
+
sdlm = TopModule.new(name: method,out_sv_path: args[0])
|
420
|
+
@@package_names ||= []
|
421
|
+
sdlm.head_import_packages = []
|
422
|
+
sdlm.head_import_packages += @@package_names
|
423
|
+
|
424
|
+
@@package_names.each do |e|
|
425
|
+
sdlm.require_package(e,false) if e
|
426
|
+
end
|
427
|
+
@@package_names = []
|
428
|
+
sdlm.instance_exec(&block)
|
429
|
+
|
430
|
+
if args[0] && File.exist?(args[0])
|
431
|
+
# sdlm.gen_sv_module
|
432
|
+
sdlm.gen_sv_module_verb
|
433
|
+
unless sdlm.vcs_path
|
434
|
+
sdlm.test_unit.gen_dve_tcl(File.join(args[0],"dve.tcl"))
|
435
|
+
else
|
436
|
+
sdlm.test_unit.gen_dve_tcl(File.join(sdlm.vcs_path,"dve.tcl"))
|
437
|
+
end
|
438
|
+
sdlm.create_xdc
|
439
|
+
else
|
440
|
+
sdlm.origin_sv = true
|
441
|
+
end
|
442
|
+
sdlm
|
443
|
+
end
|
444
|
+
## 定义模块时添加 package
|
445
|
+
|
446
|
+
def self.with_package(*args)
|
447
|
+
@@package_names += args
|
448
|
+
return self
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
## 給TopModule 添加单元测试 方法
|
453
|
+
module TdlSpace
|
454
|
+
class TopModuleTestUnitRef
|
455
|
+
|
456
|
+
def collect_unit(tu)
|
457
|
+
@__collect_units__ ||= []
|
458
|
+
@__collect_units__ << tu
|
459
|
+
end
|
460
|
+
|
461
|
+
def echo_units
|
462
|
+
@__collect_units__ ||= []
|
463
|
+
index = 1
|
464
|
+
|
465
|
+
rels = []
|
466
|
+
__collect = TdlTestPoint.inst_collect.select { |e| e.target.belong_to_module.top_tb_ref? }
|
467
|
+
@__collect_units__.each do |ue|
|
468
|
+
tp_str = ue.origin.dve_wave_signals.select do |e|
|
469
|
+
e.respond_to? :tp_instance
|
470
|
+
end.map do |ele|
|
471
|
+
unless __collect.index(ele.tp_instance)
|
472
|
+
puts ele.name
|
473
|
+
end
|
474
|
+
" ->#{__collect.index(ele.tp_instance)+1}< :: #{ele.tp_instance.name} || #{ele.tp_instance.file}:#{ele.tp_instance.line}"
|
475
|
+
end.join("\n")
|
476
|
+
|
477
|
+
rels << " [#{index}] #{ue.origin.module_name} ::<TestPoints> \n#{tp_str}"
|
478
|
+
index += 1
|
479
|
+
end
|
480
|
+
rels.join("\n")
|
481
|
+
end
|
482
|
+
|
483
|
+
def dve_wave(name: '', signals: [])
|
484
|
+
return unless signals
|
485
|
+
@_dev_wave_ ||= Hash.new
|
486
|
+
@_dev_wave_[name.to_s] = signals ## Signal is TdlTestPoint
|
487
|
+
end
|
488
|
+
|
489
|
+
def gen_dve_tcl(filename)
|
490
|
+
File.open(filename,'w') do |f|
|
491
|
+
f.puts TdlSpace.gen_dev_wave_tcl(@_dev_wave_ || Hash.new)
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
class TopModule
|
499
|
+
def test_unit
|
500
|
+
@__test_unit__ ||= TdlSpace::TopModuleTestUnitRef.new
|
501
|
+
end
|
502
|
+
|
503
|
+
end
|
504
|
+
|
505
|
+
## 判断 是否被顶层引用
|
506
|
+
class SdlModule
|
507
|
+
|
508
|
+
def top_module_ref?
|
509
|
+
if self == TopModule.current.techbench
|
510
|
+
return true
|
511
|
+
end
|
512
|
+
instanced_and_parent_module.values.each do |pm|
|
513
|
+
if pm.is_a?(TopModule)
|
514
|
+
return true
|
515
|
+
else
|
516
|
+
if pm.instanced_and_parent_module.any?
|
517
|
+
if pm.top_module_ref?
|
518
|
+
return true
|
519
|
+
end
|
520
|
+
end
|
521
|
+
end
|
522
|
+
end
|
523
|
+
return false
|
524
|
+
end
|
525
|
+
|
526
|
+
def top_tb_ref?
|
527
|
+
return false unless TopModule.current
|
528
|
+
if self == TopModule.current.techbench
|
529
|
+
return true
|
530
|
+
end
|
531
|
+
instanced_and_parent_module.values.each do |pm|
|
532
|
+
if pm == TopModule.current.techbench ##pm.is_a?(TechBenchModule)
|
533
|
+
return true
|
534
|
+
else
|
535
|
+
if pm.instanced_and_parent_module.any?
|
536
|
+
if pm.top_tb_ref?
|
537
|
+
return true
|
538
|
+
end
|
539
|
+
end
|
540
|
+
end
|
541
|
+
end
|
542
|
+
return false
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
|
547
|
+
|