addergraph.jl 5.2 KB
Newer Older
Rémi's avatar
Rémi committed
1
import Base.length
Rémi's avatar
Rémi committed
2
import Base.isempty
Rémi's avatar
Rémi committed
3
4
5
6
7

function length(addergraph::AdderGraph)
    return length(addergraph.constants)
end

Rémi's avatar
Rémi committed
8
9
10
11
function isempty(addergraph::AdderGraph)
    return (length(addergraph.constants)+length(addergraph.outputs)==0)
end

Rémi's avatar
Rémi committed
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
function get_nodes(addergraph::AdderGraph)
    return addergraph.constants
end

function push_node!(addergraph::AdderGraph, addernode::AdderNode)
    push!(addergraph.constants, 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 get_adder_error(addergraph.origin)
end

function set_error_in!(addergraph::AdderGraph, error_in::Float64)
    set_adder_error!(addergraph.origin, error_in)
    return addergraph
end

function are_data_paths_set(addergraph::AdderGraph)
    return addergraph.data_paths
end

Rémi's avatar
Rémi committed
48
49
50
51
52
function set_data_paths!(addergraph::AdderGraph, data_paths_value::Bool=true)
    addergraph.data_paths=data_paths_value
    return addergraph
end

Rémi's avatar
Rémi committed
53
54
55
56
function are_errors_computed(addergraph::AdderGraph)
    return addergraph.errors_computed
end

Rémi's avatar
Rémi committed
57
58
59
60
61
62
63
64
65
66
67
68
69
70
function set_errors_computed!(addergraph::AdderGraph, errors_computed_value::Bool=true)
    addergraph.errors_computed = errors_computed_value
    return addergraph
end

function are_full_adders_computed(addergraph::AdderGraph)
    return addergraph.full_adders_computed
end

function set_full_adders_computed!(addergraph::AdderGraph, full_adders_computed_value::Bool=true)
    addergraph.full_adders_computed=full_adders_computed_value
    return addergraph
end

71
72
73
74
function get_origin(addergraph::AdderGraph)
    return addergraph.origin
end

Rémi's avatar
Rémi committed
75
76
77
78
function get_total_nb_full_adders(addergraph::AdderGraph)
    return sum(get_nb_full_adders(addernode) for addernode in get_nodes(addergraph))
end

Rémi's avatar
Rémi committed
79
function get_addernode_by_value(addergraph::AdderGraph, value::Int)
80
81
82
    if get_value(get_origin(addergraph)) == value
        return get_origin(addergraph)
    end
Rémi's avatar
Rémi committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
    for addernode in get_nodes(addergraph)
        if get_value(addernode) == value
            return addernode
        end
    end
    return nothing
end


function read_addergraph(s::String)
    addergraph = AdderGraph()
    adders_registers_outputs = split(s[3:(end-2)], "},{")
    for val in adders_registers_outputs
        if startswith(val, "'A'")
            node_details = split(val, ",")
            node_value = parse(Int, node_details[2][2:(end-1)])
            node_inputs_signed = Vector{Int}()
            node_input_shifts = Vector{Int}()
            for current_input in 1:div(length(node_details)-3, 3)
                push!(node_inputs_signed, parse(Int, node_details[3*current_input+1][2:(end-1)]))
                push!(node_input_shifts, parse(Int, node_details[3*current_input+3]))
            end
            node_inputs = Vector{Int}(abs.(node_inputs_signed))
            node_subtraction = Vector{Bool}(abs.(div.(sign.(node_inputs_signed).-1, 2)))
Rémi's avatar
Rémi committed
107
            push_node!(addergraph, AdderNode(node_value, [InputEdge(get_addernode_by_value(addergraph, node_inputs[i]), node_input_shifts[i], node_subtraction[i]) for i in 1:length(node_subtraction)]))
Rémi's avatar
Rémi committed
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
        elseif startswith(val, "'O'")
            push_output!(addergraph, parse(Int, split(val, ",")[2][2:(end-1)]))
        end
    end
    return addergraph
end


function write_addergraph(addergraph::AdderGraph)
    depth_by_value = Dict([1 => 0])
    maximum_depth = 0
    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
    end
    output_values = Vector{Int}()
    adderstring = "{"
    firstcoefnocomma = true
    coefficients = get_outputs(addergraph)
    for coefind in 1:length(coefficients)
        coef = coefficients[coefind]
        if coef != 0
            value = odd(abs(coef))
            if !(abs(coef) in output_values)
                push!(output_values, abs(coef))
                shift = round(Int, log2(abs(coef)/value))
                if !firstcoefnocomma
                    adderstring *= ","
                else
                    firstcoefnocomma = false
                end
                adderstring *= "{'O',[$(abs(coef))],$(maximum_depth+1),[$(value)],$(depth_by_value[value]),$(shift)}"
            end
        end
    end
Rémi's avatar
Rémi committed
145
146
147
148
149
    for addernode in get_nodes(addergraph)
        adderstring *= ",{'A',[$(get_value(addernode))],$(depth_by_value[get_value(addernode)])"
        for input_edge in get_input_edges(addernode)
            adderstring *= ",[$((-1)^(is_negative_input(input_edge))*get_input_addernode_value(input_edge))],"
            adderstring *= "$(depth_by_value[get_input_addernode_value(input_edge)]),$(get_input_shift(input_edge))"
Rémi's avatar
Rémi committed
150
151
152
153
154
155
        end
        adderstring *= "}"
    end
    adderstring *= "}"
    return adderstring
end