From 26b67a045f3fe3a6d52a6d2588aa239202fb576c Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Mon, 25 Jan 2021 18:23:36 +0100 Subject: ghdl.cc: handle gclk attributes on dff. For ghdl/ghdl#1610 Also attribute nets. --- src/ghdl.cc | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/src/ghdl.cc b/src/ghdl.cc index 933db24..413d371 100644 --- a/src/ghdl.cc +++ b/src/ghdl.cc @@ -31,6 +31,8 @@ USING_YOSYS_NAMESPACE using namespace GhdlSynth; +static Name_Id nameid_gclk = {0}; + // Convert an Sname_User to a string. Deals with extended names // Subroutine of to_str static std::string user_to_str(Name_Id id) @@ -581,6 +583,26 @@ static void add_formal_input(RTLIL::Module *module, std::vector & cell->setPort("\\Y", get_src(net_map, n)); } +static bool has_attribute_gclk(Net n) +{ + Instance inst = get_net_parent(n); + switch(get_id(inst)) { + case Id_Signal: + case Id_Isignal: + break; + default: + return false; + } + + Attribute attr = get_first_attribute (inst); + while (attr.id != 0) { + if (get_attribute_name(attr).id == nameid_gclk.id) + return true; + attr = get_attribute_next(attr); + } + return false; +} + static void import_module(RTLIL::Design *design, GhdlSynth::Module m) { Instance self_inst = get_self_instance (m); @@ -761,6 +783,7 @@ static void import_module(RTLIL::Design *design, GhdlSynth::Module m) break; case Id_Signal: case Id_Isignal: + break; case Id_Output: case Id_Port: case Id_Const_UB32: @@ -794,6 +817,43 @@ static void import_module(RTLIL::Design *design, GhdlSynth::Module m) } } + // Add attributes and names on wires. + for (Instance inst = get_first_instance(m); + is_valid(inst); + inst = get_next_instance(inst)) { + GhdlSynth::Module im = get_module(inst); + Module_Id id = get_id(im); + switch (id) { + case Id_Signal: + case Id_Isignal: + { + Net s = get_input_net(inst, 0); + RTLIL::Wire *w; + // The wire may have been created for an output + if (!is_set(net_map, s)) + break; + w = net_map.at(s.id); + + /* Do not rename ports. */ + if (w && !w->port_input && !w->port_output) { + Sname iname = get_instance_name(inst); + module->rename(w, to_str(iname)); + } + + // Attributes + for (Attribute attr = get_first_attribute (inst); + attr.id != 0; + attr = get_attribute_next(attr)) { + IdString id = build_attribute_id(attr); + w->attributes[id] = build_attribute_val(attr); + } + break; + } + default: + break; + } + } + // Create cells and connect. for (Instance inst = get_first_instance(m); is_valid(inst); @@ -965,8 +1025,13 @@ static void import_module(RTLIL::Design *design, GhdlSynth::Module m) case Id_Dff: case Id_Idff: { - Net clk = get_input_net(inst, 0); - module->addDff(to_str(iname), extract_clk_sig(net_map, clk), IN(1), OUT(0), extract_clk_pol(clk) == RTLIL::State::S1); + Net edge_clk = get_input_net(inst, 0); + Net clk = get_input_net(get_net_parent(edge_clk), 0); + RTLIL::SigSpec sig_clk = get_src(net_map, clk); + if (has_attribute_gclk(clk)) + module->addFf(to_str(iname), IN(1), OUT(0)); + else + module->addDff(to_str(iname), sig_clk, IN(1), OUT(0), extract_clk_pol(edge_clk) == RTLIL::State::S1); // For idff, the initial value is set on the output wire. if (id == Id_Idff) { net_map[get_output(inst, 0).id]->attributes["\\init"] = IN(2).as_const(); @@ -1036,17 +1101,6 @@ static void import_module(RTLIL::Design *design, GhdlSynth::Module m) break; case Id_Signal: case Id_Isignal: - { - // No cell is created for Id_Signal or Id_Isignal. - // But try to keep the name. - Net sig = get_input_net(inst, 0); - if (is_set(net_map, sig)) { - Wire *w = net_map.at(sig.id); - /* Do not rename ports. */ - if (w && !w->port_input && !w->port_output) - module->rename(w, to_str(iname)); - } - } break; case Id_Output: case Id_Port: @@ -1233,6 +1287,9 @@ struct GhdlPass : public Pass { if (!is_valid(top)) { log_cmd_error("vhdl import failed.\n"); } + // For the gclk attribute. + nameid_gclk = get_identifier("gclk"); + import_netlist(design, top); } } -- cgit v1.2.3