Commit e0fd6dbe authored by Rémi's avatar Rémi
Browse files

Update AdderGraphs -- Replace struct

parent 5552752b
name = "AdderGraphs"
uuid = "818587fb-0c22-4279-a2b9-8b16b5360b71"
version = "0.1.1"
version = "0.2.0"
module AdderGraphs
# OriginAdder: AdderNode(1, Vector{InputEdge}(), 0, 0, -1.0, 0)
mutable struct AdderNode
value::Int
inputs::Vector{Int}
input_shifts::Vector{Int}
subtraction::Vector{Bool}
truncatures::Vector{Int}
msbin::Vector{Int}
lsbin::Vector{Int}
msbout::Int
lsbout::Int
error::Int
inputs::Vector{InputEdge}
msb_out::Int
lsb_out::Int
error_out::Float64
nb_full_adders::Int
end
function origin_addernode()
return AdderNode(1, Vector{InputEdge}(), 0, 0, -1.0, 0)
end
function AdderNode(value::Int, inputs::Vector{InputEdge})
return AdderNode(value, inputs, 0, 0, -1.0, 0)
end
mutable struct InputEdge
input_adder::AdderNode
shift::Int
is_negative::Bool
end
mutable struct AdderGraph
origin::AdderNode
constants::Vector{AdderNode}
outputs::Vector{Int}
full_adders_computed::Bool
......@@ -23,47 +36,67 @@ mutable struct AdderGraph
data_paths::Bool
end
function AdderGraph()
return AdderGraph(Vector{AdderNode}(), Vector{Int}(), 0.0, false, false, false)
return AdderGraph(origin_addernode(), Vector{AdderNode}(), Vector{Int}(), 0.0, false, 0, 0, Vector{Int}(), Vector{Int}(), false, false)
end
function AdderGraph(v::Vector{Int})
return AdderGraph(Vector{AdderNode}(), v, 0.0, false, false, false)
return AdderGraph(origin_addernode(), Vector{AdderNode}(), v, 0.0, false, 0, 0, Vector{Int}(), Vector{Int}(), false, false)
end
function AdderGraph(c::Vector{AdderNode}, v::Vector{Int})
return AdderGraph(c, v, 0.0, false, false, false)
return AdderGraph(origin_addernode(), c, v, 0.0, false, 0, 0, Vector{Int}(), Vector{Int}(), false, false)
end
function AdderGraph(c::Vector{AdderNode})
return AdderGraph(c, Vector{Int}(), 0.0, false, false, false)
return AdderGraph(origin_addernode(), c, Vector{Int}(), 0.0, false, 0, 0, Vector{Int}(), Vector{Int}(), false, false)
end
function AdderNode(value::Int, inputs::Vector{Int}, input_shifts::Vector{Int}, subtraction::Vector{Bool})
return AdderNode(value, inputs, input_shifts, subtraction, zeros(Int, length(inputs)), zeros(Int, length(inputs)), zeros(Int, length(inputs)), -1, -1, -1, -1)
end
export AdderGraph
export AdderNode
export InputEdge
include("utils.jl")
include("addergraphfunctions.jl")
include("inputedge.jl")
include("addernode.jl")
include("addergraph.jl")
# Utils
export odd
# InputEdge
# AdderGraph
export length
export push_node!
export push_output!
export read_addergraph
export write_addergraph
export get_outputs
export are_data_paths_set
export compute_internal_msb_lsb!
export get_error_in
export set_error_in!
# AdderNode
export get_adder_msb
export get_adder_lsb
export get_adder_msbin
export get_adder_lsbin
export add_data_msb_lsb!
export add_data_msbin_lsbin!
export get_error_in
export set_error_in!
export odd
export set_adder_msb!
export set_adder_msb!
export set_adder_msbin!
export set_adder_msbin!
export get_previous_addernodes_value
export get_addernode_index_by_value
export get_previous_addernodes_index
export get_previous_addernodes
export get_input_shifts
export get_subtractions
export produce_addernode
end # module
......@@ -13,163 +13,44 @@ function push_node!(addergraph::AdderGraph, addernode::AdderNode)
return addergraph
end
function push_node!(addergraph::AdderGraph, inputs::Vector{InputEdge})
push_node!(addergraph, AdderNode(_compute_value_from_inputs(inputs), inputs))
end
function push_output!(addergraph::AdderGraph, output_value::Int)
push!(addergraph.outputs, output_value)
return addergraph
end
function get_outputs(addergraph::AdderGraph)
return addergraph.outputs
end
function get_error_in(addergraph::AdderGraph)
return addergraph.error_in
return get_adder_error(addergraph.origin)
end
function set_error_in!(addergraph::AdderGraph, error_in::Float64)
addergraph.error_in = error_in
set_adder_error!(addergraph.origin, error_in)
return addergraph
end
function are_data_paths_set(addergraph::AdderGraph)
return addergraph.data_paths
end
"""
get_adder_msb(addernode::AdderNode)
Return the msb out of the adder `addernode` or `nothing` if not specified yet.
"""
function get_adder_msb(addernode::AdderNode)
if !are_lsbmsb_set(addernode)
return nothing
end
return addernode.msbout
end
"""
get_adder_lsb(addernode::AdderNode)
Return the lsb out of the adder `addernode` or `nothing` if not specified yet.
"""
function get_adder_lsb(addernode::AdderNode)
if !are_lsbmsb_set(addernode)
return nothing
end
return addernode.lsbout
end
"""
get_adder_msbin(addernode::AdderNode)
Return the msb in of the adder `addernode` or `nothing` if not specified yet.
"""
function get_adder_msbin(addernode::AdderNode)
if !are_lsbmsb_set(addernode)
return nothing
end
return addernode.msbin
end
"""
get_adder_lsbin(addernode::AdderNode)
Return the lsb in of the adder `addernode` or `nothing` if not specified yet.
"""
function get_adder_lsbin(addernode::AdderNode)
if !are_lsbmsb_set(addernode)
return nothing
end
return addernode.lsbin
end
"""
get_adder_error(addernode::AdderNode)
Return the error out of the adder `addernode` or `-1` if not specified yet.
"""
function get_adder_error(addernode::AdderNode)
return addernode.error
end
function are_errors_computed(addergraph::AdderGraph)
return addergraph.errors_computed
end
#TODO add tests
"""
if !are_lsbmsb_set(addergraph)
for addernode in addergraph
@test get_adder_msb(addernode) == nothing
@test get_adder_lsb(addernode) == nothing
@test get_adder_msbin(addernode) == nothing
@test get_adder_lsbin(addernode) == nothing
end
end
if !are_errors_computed(addergraph)
for addernode in addergraph
@test get_adder_error(addernode) == -1
end
end
"""
function add_data_msb_lsb!(addernode::AdderNode, msb::Int, lsb::Int)
addernode.msbout = msb
addernode.lsbout = lsb
return addernode
end
function add_data_msbin_lsbin!(addernode::AdderNode, msb::Vector{Int}, lsb::Vector{Int})
addernode.msbin = msbin
addernode.lsbin = lsbin
return addernode
end
function get_outputs(addergraph::AdderGraph)
return addergraph.outputs
end
function get_value(addernode::AdderNode)
return addernode.value
end
function get_previous_addernodes_value(addernode::AdderNode)
return addernode.inputs
end
function get_input_shifts(addernode::AdderNode)
return addernode.input_shifts
end
function get_addernode_index_by_value(addergraph::AdderGraph, value::Int)
node_index = 0
addernodes = get_nodes(addergraph)
for i in 1:length(addernodes)
addernode = addernodes[i]
function get_addernode_by_value(addergraph::AdderGraph, value::Int)
for addernode in get_nodes(addergraph)
if get_value(addernode) == value
node_index = i
break
return addernode
end
end
return node_index
end
function get_previous_addernodes_index(addergraph::AdderGraph, addernode::AdderNode)
return get_addernode_index_by_value.(addergraph, get_previous_addernodes_value(addernode))
end
function get_previous_addernodes(addergraph::AdderGraph, addernode::AdderNode)
return inputs
return nothing
end
......@@ -188,7 +69,7 @@ function read_addergraph(s::String)
end
node_inputs = Vector{Int}(abs.(node_inputs_signed))
node_subtraction = Vector{Bool}(abs.(div.(sign.(node_inputs_signed).-1, 2)))
push_node!(addergraph, AdderNode(node_value, node_inputs, node_input_shifts, node_subtraction))
push_node!(addergraph, AdderNode(node_value, [InputEdge(get_addernode_by_value(node_inputs[i]), node_input_shifts[i], node_subtraction[i]) for i in 1:length(node_subtraction)]))
elseif startswith(val, "'O'")
push_output!(addergraph, parse(Int, split(val, ",")[2][2:(end-1)]))
end
......@@ -200,8 +81,8 @@ end
function write_addergraph(addergraph::AdderGraph)
depth_by_value = Dict([1 => 0])
maximum_depth = 0
for addernode in addergraph.constants
depth_by_value[get_value(addernode)] = max(depth_by_value[addernode.inputs[1]], depth_by_value[addernode.inputs[2]])+1
for addernode in get_nodes(addergraph)
depth_by_value[get_value(addernode)] = maximum(depth_by_value[get_input_addernode_values(addernode)[i]] for i in 1:length(get_input_addernode_values(addernode)))+1
if depth_by_value[get_value(addernode)] > maximum_depth
maximum_depth = depth_by_value[get_value(addernode)]
end
......@@ -231,14 +112,14 @@ function write_addergraph(addergraph::AdderGraph)
end
for addernodeind in length(addergraph):-1:1
addernode = get_nodes(addergraph)[addernodeind]
subtractfirst = ""
subtractsecond = ""
if addernode.subtraction[1]
subtractfirst = "-"
elseif addernode.subtraction[2]
subtractsecond = "-"
addernodes_index = get_previous_addernodes_index(addernode)
number_of_previous_nodes = length(addernodes_index)
adderstring *= "{'A',[$(get_value(addernode))],$(depth_by_value[get_value(addernode)])"
addernode_subtractions = get_subtractions(addernode)
for i in 1:number_of_previous_nodes
adderstring *= ",[$(addernode_subtractions[i] ? "-" : "")$(get_input_addernode_values(addernode)[i])],$(depth_by_value[get_input_addernode_values(addernode)[i]]),$(addernode.input_shifts[i])"
end
adderstring *= "{'A',[$(get_value(addernode))],$(depth_by_value[get_value(addernode)]),[$(subtractfirst)$(addernode.inputs[1])],$(depth_by_value[addernode.inputs[1]]),$(addernode.input_shifts[1]),[$(subtractsecond)$(addernode.inputs[2])],$(depth_by_value[addernode.inputs[2]]),$(addernode.input_shifts[2])}"
adderstring *= "}"
if addernodeind != 1
adderstring *= ","
end
......@@ -246,3 +127,4 @@ function write_addergraph(addergraph::AdderGraph)
adderstring *= "}"
return adderstring
end
# Getters
function get_value(addernode::AdderNode)
return addernode.value
end
"""
"""
function get_input_edges(addernode::AdderNode)
return addernode.inputs
end
"""
get_adder_msb(addernode::AdderNode)
Return the msb out of the adder `addernode`.
"""
function get_adder_msb(addernode::AdderNode)
return addernode.msb_out
end
"""
get_adder_lsb(addernode::AdderNode)
Return the lsb out of the adder `addernode`.
"""
function get_adder_lsb(addernode::AdderNode)
return addernode.lsb_out
end
"""
get_adder_error(addernode::AdderNode)
Return the error out of the adder `addernode` or `-1.0` if not specified yet.
"""
function get_adder_error(addernode::AdderNode)
return addernode.error_out
end
# Setters
"""
set_adder_msb(addernode::AdderNode, msb::Int)
Set the msb out of the adder `addernode` to `msb`.
"""
function set_adder_msb!(addernode::AdderNode, msb::Int)
addernode.msb_out = msb
return addernode
end
"""
set_adder_lsb(addernode::AdderNode, lsb::Int)
Set the lsb out of the adder `addernode` to `lsb`.
"""
function set_adder_lsb!(addernode::AdderNode, lsb::Int)
addernode.lsb_out = lsb
return addernode
end
function set_adder_error!(addernode::AdderNode, error_out::Float64)
addernode.error_out = error_out
return addernode
end
# Extract more information
"""
"""
function get_input_addernodes(addernode::AdderNode)
return get_input_addernode.(get_input_edges(addernode))
end
function get_input_addernode_values(addernode::AdderNode)
return get_value.(get_input_addernode.(get_input_edges(addernode)))
end
function get_input_shifts(addernode::AdderNode)
return get_input_shift.(get_input_edges(addernode))
end
function are_negative_inputs(addernode::AdderNode)
return is_negative_input.(get_input_edges(addernode))
end
"""
get_adder_msb_in(addernode::AdderNode)
Return the msb in of the adder `addernode`.
"""
function get_adder_msb_in(addernode::AdderNode)
return get_input_shifts(addernode) .+ get_adder_msb.(get_input_addernodes(addernode))
end
"""
get_adder_lsb_in(addernode::AdderNode)
Return the lsb in of the adder `addernode`.
"""
function get_adder_lsb_in(addernode::AdderNode)
return get_input_shifts(addernode) .+ get_adder_lsb.(get_input_addernodes(addernode))
end
# Generation
function produce_addernode(input_adders::Vector{AdderNode}, shifts::Vector{Int}, sign_switch::Vector{Bool})
@assert length(input_values) == length(shifts)
@assert length(shifts) == length(sign_switch)
inputs = [InputEdge(input_values[i], shifts[i], sign_switch[i]) for i in 1:length(sign_switch)]
addernode = AdderNode(_compute_value_from_inputs(inputs), inputs)
return addernode
end
"""
"""
function get_input_addernode(input_edge::InputEdge)
return input_edge.input_adder
end
function get_input_shift(input_edge::InputEdge)
return input_edge.shift
end
function is_negative_input(input_edge::InputEdge)
return input_edge.is_negative
end
function get_input_addernode_value(input_edge::InputEdge)
return get_value(get_input_addernode(input_edge))
end
......@@ -7,3 +7,20 @@ function odd(number::Int)
end
return number
end
function log2odd(number::Int)
return round(Int, log2(div(number, odd(number))))
end
function _compute_msb_lsb_from_msb_lsb(msb_lsb1::Tuple{Int, Int}, msb_lsb2::Tuple{Int, Int}, subtraction::Bool)
msb1, lsb1 = msb_lsb1
msb2, lsb2 = msb_lsb2
return (max(msb1, msb2)+(subtraction ? 0 : (min(msb1, msb2) < max(lsb1, lsb2) ? 0 : 1)), min(lsb1, lsb2))
end
function _compute_value_from_inputs(inputs::Vector{InputEdge})
return round(Int, sum((-1)^(is_negative(input_edge)) * get_input_addernode_value(input_edge) * 2.0^(get_input_shift(input_edge)) for input_edge in inputs))
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment