|
|
@@ -1,53 +1,45 @@
|
|
|
+@enum Structure LI HI HO HOmod
|
|
|
|
|
|
-@enum Structure LI HI HO
|
|
|
-
|
|
|
-function build_devstone(type::Structure, name::String, depth::Int, width::Int, int_delay::Float64, ext_delay::Float64, stats::Bool=false)
|
|
|
- if depth < 1 || width < 1
|
|
|
- error("Invalid depth or width")
|
|
|
- end
|
|
|
-
|
|
|
- top_model = CoupledDEVS(name)
|
|
|
- has_out_port = type == HI || type == HO
|
|
|
+# Port Config
|
|
|
+function setup_ports!(top_model::CoupledDEVS, type::Structure)
|
|
|
+ has_out_port = type in (HI, HO, HOmod)
|
|
|
|
|
|
add_in_port!(top_model, :i_in)
|
|
|
if has_out_port
|
|
|
add_out_port!(top_model, :o_out)
|
|
|
end
|
|
|
- if type == HO
|
|
|
+ if type in (HO, HOmod)
|
|
|
add_in_port!(top_model, :i_in2)
|
|
|
+ end
|
|
|
+ if type == HO
|
|
|
add_out_port!(top_model, :o_out2)
|
|
|
end
|
|
|
|
|
|
- # Leaf
|
|
|
- if depth == 1
|
|
|
- p_time = round(rand() + 1.0, digits=3)
|
|
|
- atom = add_submodel!(top_model, "Atomic_0_0", DelayedAtomic;
|
|
|
- inbox=(; i_in=Union{Generate, A2A}[]),
|
|
|
- out_ports=has_out_port ? Set([:o_out]) : Set{Symbol}(),
|
|
|
- int_delay=int_delay, ext_delay=ext_delay, prep_time=p_time,
|
|
|
- has_out_port, stats=stats)
|
|
|
-
|
|
|
- connect!(top_model, self.i_in, atom.i_in)
|
|
|
- if has_out_port
|
|
|
- connect!(top_model, atom.o_out, self.o_out)
|
|
|
- end
|
|
|
+ return has_out_port
|
|
|
+end
|
|
|
|
|
|
- return top_model
|
|
|
- end
|
|
|
-
|
|
|
- child_name = "Coupled_$(depth - 1)"
|
|
|
- child_coupled = build_devstone(type, child_name, depth - 1, width, int_delay, ext_delay, stats)
|
|
|
- child = add_submodel!(top_model, child_name, child_coupled)
|
|
|
+# Depth 1
|
|
|
+function build_leaf_node(name::String, type::Structure, int_delay::Float64, ext_delay::Float64, stats::Bool)
|
|
|
+ top_model = CoupledDEVS(name)
|
|
|
+ has_out_port = setup_ports!(top_model, type)
|
|
|
|
|
|
- connect!(top_model, self.i_in, child.i_in)
|
|
|
- if type == HO
|
|
|
- connect!(top_model, self.i_in, child.i_in2)
|
|
|
- end
|
|
|
+ p_time = round(rand() + 1.0, digits=3)
|
|
|
+ atom = add_submodel!(top_model, "Atomic_0_0", DelayedAtomic;
|
|
|
+ inbox=(; i_in=Union{Generate, A2A}[]),
|
|
|
+ out_ports=has_out_port ? Set([:o_out]) : Set{Symbol}(),
|
|
|
+ int_delay=int_delay, ext_delay=ext_delay, prep_time=p_time,
|
|
|
+ has_out_port=has_out_port, stats=stats)
|
|
|
|
|
|
+ connect!(top_model, self.i_in, atom.i_in)
|
|
|
if has_out_port
|
|
|
- connect!(top_model, child.o_out, self.o_out)
|
|
|
+ connect!(top_model, atom.o_out, self.o_out)
|
|
|
end
|
|
|
|
|
|
+ return top_model
|
|
|
+end
|
|
|
+
|
|
|
+# Create Atomics (LI, HI, HO)
|
|
|
+function build_atomics!(top_model::CoupledDEVS, depth::Int, width::Int, int_delay::Float64, ext_delay::Float64, has_out_port::Bool, stats::Bool)
|
|
|
width_models = ModelRef[]
|
|
|
for idx in 0:(width - 2)
|
|
|
p_time = 1.0 - round(rand() * (0.5 / width) + (idx / width), digits=3)
|
|
|
@@ -61,36 +53,136 @@ function build_devstone(type::Structure, name::String, depth::Int, width::Int, i
|
|
|
|
|
|
push!(width_models, atom)
|
|
|
end
|
|
|
+ return width_models
|
|
|
+end
|
|
|
|
|
|
- if type == LI
|
|
|
- for atom in width_models
|
|
|
- connect!(top_model, self.i_in, atom.i_in)
|
|
|
- end
|
|
|
+# Routing
|
|
|
+function route_LI!(top_model::CoupledDEVS, width_models::Vector{ModelRef})
|
|
|
+ for atom in width_models
|
|
|
+ connect!(top_model, self.i_in, atom.i_in)
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+function route_HI!(top_model::CoupledDEVS, width_models::Vector{ModelRef})
|
|
|
+ for atom in width_models
|
|
|
+ connect!(top_model, self.i_in, atom.i_in)
|
|
|
+ end
|
|
|
+ for i in 1:(length(width_models) - 1)
|
|
|
+ connect!(top_model, width_models[i].o_out, width_models[i + 1].i_in)
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+function route_HO!(top_model::CoupledDEVS, width_models::Vector{ModelRef})
|
|
|
+ for i in 1:(length(width_models) - 1)
|
|
|
+ curr_atom = width_models[i]
|
|
|
+ next_atom = width_models[i + 1]
|
|
|
+
|
|
|
+ connect!(top_model, curr_atom.o_out, next_atom.i_in)
|
|
|
+ connect!(top_model, self.i_in2, curr_atom.i_in)
|
|
|
+ connect!(top_model, curr_atom.o_out, self.o_out2)
|
|
|
+ end
|
|
|
|
|
|
- elseif type == HI
|
|
|
- for atom in width_models
|
|
|
- connect!(top_model, self.i_in, atom.i_in)
|
|
|
+ if !isempty(width_models)
|
|
|
+ last_atom = width_models[end]
|
|
|
+ connect!(top_model, self.i_in2, last_atom.i_in)
|
|
|
+ connect!(top_model, last_atom.o_out, self.o_out2)
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+# Create HOmod Structure---
|
|
|
+function build_HOmod!(top_model::CoupledDEVS, child::ModelRef, depth::Int, width::Int, int_delay::Float64, ext_delay::Float64, stats::Bool)
|
|
|
+ if width < 2
|
|
|
+ return
|
|
|
+ end
|
|
|
+
|
|
|
+ atomics = Dict{Int, Vector{ModelRef}}()
|
|
|
+
|
|
|
+ # create grid
|
|
|
+ for i in 0:(width - 1)
|
|
|
+ atomics[i] = ModelRef[]
|
|
|
+ min_row_idx = i < 2 ? 0 : i - 1
|
|
|
+
|
|
|
+ for j in min_row_idx:(width - 2)
|
|
|
+ atomic_name = "A$(i)_$(j)"
|
|
|
+
|
|
|
+ atom = add_submodel!(top_model, atomic_name, DelayedAtomic;
|
|
|
+ inbox=(; i_in=Union{Generate, A2A}[]),
|
|
|
+ out_ports=Set([:o_out]),
|
|
|
+ int_delay=int_delay, ext_delay=ext_delay, prep_time=1.0,
|
|
|
+ has_out_port=true, stats=stats)
|
|
|
+
|
|
|
+ push!(atomics[i], atom)
|
|
|
end
|
|
|
+ end
|
|
|
|
|
|
- # Chain atomics
|
|
|
- for i in 1:(length(width_models) - 1)
|
|
|
- connect!(top_model, width_models[i].o_out, width_models[i + 1].i_in)
|
|
|
+ for atom in atomics[0]
|
|
|
+ connect!(top_model, self.i_in2, atom.i_in)
|
|
|
+ end
|
|
|
+ for i in 1:(width - 1)
|
|
|
+ if !isempty(atomics[i])
|
|
|
+ connect!(top_model, self.i_in2, atomics[i][1].i_in)
|
|
|
end
|
|
|
+ end
|
|
|
+
|
|
|
+ for atom in atomics[0]
|
|
|
+ connect!(top_model, atom.o_out, child.i_in2)
|
|
|
+ end
|
|
|
|
|
|
- elseif type == HO
|
|
|
- for i in 1:(length(width_models) - 1)
|
|
|
- curr_atom = width_models[i]
|
|
|
- next_atom = width_models[i + 1]
|
|
|
+ if haskey(atomics, 1) && haskey(atomics, 0)
|
|
|
+ for atom1 in atomics[1]
|
|
|
+ for atom0 in atomics[0]
|
|
|
+ connect!(top_model, atom1.o_out, atom0.i_in)
|
|
|
+ end
|
|
|
+ end
|
|
|
+ end
|
|
|
|
|
|
- connect!(top_model, curr_atom.o_out, next_atom.i_in)
|
|
|
- connect!(top_model, self.i_in2, curr_atom.i_in)
|
|
|
- connect!(top_model, curr_atom.o_out, self.o_out2)
|
|
|
+ for i in 2:(width - 1)
|
|
|
+ for j in 1:length(atomics[i])
|
|
|
+ connect!(top_model, atomics[i][j].o_out, atomics[i-1][j+1].i_in)
|
|
|
end
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
+function build_devstone(type::Structure, name::String, depth::Int, width::Int, int_delay::Float64, ext_delay::Float64, stats::Bool=false)
|
|
|
+ if depth < 1 || width < 1
|
|
|
+ error("Invalid depth or width")
|
|
|
+ end
|
|
|
+
|
|
|
+ # Base Case
|
|
|
+ if depth == 1
|
|
|
+ return build_leaf_node(name, type, int_delay, ext_delay, stats)
|
|
|
+ end
|
|
|
+
|
|
|
+ # Recursive
|
|
|
+ top_model = CoupledDEVS(name)
|
|
|
+ has_out_port = setup_ports!(top_model, type)
|
|
|
+
|
|
|
+ child_name = "Coupled_$(depth - 1)"
|
|
|
+ child_coupled = build_devstone(type, child_name, depth - 1, width, int_delay, ext_delay, stats)
|
|
|
+ child = add_submodel!(top_model, child_name, child_coupled)
|
|
|
+
|
|
|
+ # Connect Parent to Child
|
|
|
+ connect!(top_model, self.i_in, child.i_in)
|
|
|
+ if type == HO
|
|
|
+ connect!(top_model, self.i_in, child.i_in2)
|
|
|
+ end
|
|
|
+ if has_out_port
|
|
|
+ connect!(top_model, child.o_out, self.o_out)
|
|
|
+ end
|
|
|
|
|
|
- if length(width_models) > 0
|
|
|
- last_atom = width_models[end]
|
|
|
- connect!(top_model, self.i_in2, last_atom.i_in)
|
|
|
- connect!(top_model, last_atom.o_out, self.o_out2)
|
|
|
+ # Sub-topology Generation & Routing
|
|
|
+ if type == HOmod
|
|
|
+ build_HOmod!(top_model, child, depth, width, int_delay, ext_delay, stats)
|
|
|
+ else
|
|
|
+ width_models = build_atomics!(top_model, depth, width, int_delay, ext_delay, has_out_port, stats)
|
|
|
+
|
|
|
+ if type == LI
|
|
|
+ route_LI!(top_model, width_models)
|
|
|
+ elseif type == HI
|
|
|
+ route_HI!(top_model, width_models)
|
|
|
+ elseif type == HO
|
|
|
+ route_HO!(top_model, width_models)
|
|
|
end
|
|
|
end
|
|
|
|