diff options
| author | Tristan Gingold <tgingold@free.fr> | 2021-01-25 18:23:36 +0100 | 
|---|---|---|
| committer | Tristan Gingold <tgingold@free.fr> | 2021-01-25 18:32:41 +0100 | 
| commit | 26b67a045f3fe3a6d52a6d2588aa239202fb576c (patch) | |
| tree | c5124b8e5aca2d69dc5d7df596ab10c0075d8cd5 /src | |
| parent | fdfdc927a129bce9c007dd69958987e340275001 (diff) | |
| download | ghdl-yosys-plugin-26b67a045f3fe3a6d52a6d2588aa239202fb576c.tar.gz ghdl-yosys-plugin-26b67a045f3fe3a6d52a6d2588aa239202fb576c.tar.bz2 ghdl-yosys-plugin-26b67a045f3fe3a6d52a6d2588aa239202fb576c.zip | |
ghdl.cc: handle gclk attributes on dff.  For ghdl/ghdl#1610
Also attribute nets.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ghdl.cc | 83 | 
1 files 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<RTLIL::Wire *> &  	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);  		}  	} | 
