diff options
| author | Eddie Hung <eddie@fpgeh.com> | 2019-09-19 14:02:55 -0700 | 
|---|---|---|
| committer | Eddie Hung <eddie@fpgeh.com> | 2019-09-19 14:02:55 -0700 | 
| commit | 429c9852cee3bd7f133944044c74c26b8f6a4209 (patch) | |
| tree | 5009432623c43d3e19127cb900560615585d105f | |
| parent | 2766465a2bf73fcd490a160a124b6167851f2d10 (diff) | |
| download | yosys-429c9852cee3bd7f133944044c74c26b8f6a4209.tar.gz yosys-429c9852cee3bd7f133944044c74c26b8f6a4209.tar.bz2 yosys-429c9852cee3bd7f133944044c74c26b8f6a4209.zip  | |
Add HOLD/RST support for SB_MAC16
| -rw-r--r-- | passes/pmgen/ice40_dsp.cc | 63 | ||||
| -rw-r--r-- | passes/pmgen/ice40_dsp.pmg | 122 | 
2 files changed, 116 insertions, 69 deletions
diff --git a/passes/pmgen/ice40_dsp.cc b/passes/pmgen/ice40_dsp.cc index 7592593a6..f3cc83699 100644 --- a/passes/pmgen/ice40_dsp.cc +++ b/passes/pmgen/ice40_dsp.cc @@ -33,13 +33,13 @@ void create_ice40_dsp(ice40_dsp_pm &pm)  	log("\n");  	log("ffA:    %s %s %s\n", log_id(st.ffA, "--"), log_id(st.ffAcemux, "--"), log_id(st.ffArstmux, "--"));  	log("ffB:    %s %s %s\n", log_id(st.ffB, "--"), log_id(st.ffBcemux, "--"), log_id(st.ffBrstmux, "--")); -	log("ffCD:   %s %s %s\n", log_id(st.ffCD, "--"), log_id(st.ffCDcemux, "--"), log_id(st.ffCDrstmux, "--")); +	log("ffCD:   %s %s\n", log_id(st.ffCD, "--"), log_id(st.ffCDcemux, "--"));  	log("mul:    %s\n", log_id(st.mul, "--")); -	log("ffFJKG: %s n/a %s\n", log_id(st.ffFJKG, "--"), log_id(st.ffFJKGrstmux, "--")); -	log("ffH:    %s n/a %s\n", log_id(st.ffH, "--"), log_id(st.ffHrstmux, "--")); +	log("ffFJKG: %s\n", log_id(st.ffFJKG, "--")); +	log("ffH:    %s\n", log_id(st.ffH, "--"));  	log("add:    %s\n", log_id(st.add, "--"));  	log("mux:    %s\n", log_id(st.mux, "--")); -	log("ffO:    %s\n", log_id(st.ffO, "--")); +	log("ffO:    %s %s %s\n", log_id(st.ffO, "--"), log_id(st.ffOcemux, "--"), log_id(st.ffOrstmux, "--"));  #endif  	log("Checking %s.%s for iCE40 DSP inference.\n", log_id(pm.module), log_id(st.mul)); @@ -98,13 +98,35 @@ void create_ice40_dsp(ice40_dsp_pm &pm)  	cell->setParam("\\C_REG", st.ffCD ? State::S1 : State::S0);  	cell->setParam("\\D_REG", st.ffCD ? State::S1 : State::S0); -	cell->setPort("\\AHOLD", State::S0); -	cell->setPort("\\BHOLD", State::S0); -	cell->setPort("\\CHOLD", State::S0); -	cell->setPort("\\DHOLD", State::S0); - -	cell->setPort("\\IRSTTOP", State::S0); -	cell->setPort("\\IRSTBOT", State::S0); +	SigSpec AHOLD, BHOLD, CDHOLD; +	if (st.ffAcemux) +		AHOLD = st.ffAcepol ? pm.module->Not(NEW_ID, st.ffAcemux->getPort("\\S")) : st.ffAcemux->getPort("\\S"); +	else +		AHOLD = State::S0; +	if (st.ffBcemux) +		BHOLD = st.ffBcepol ? pm.module->Not(NEW_ID, st.ffBcemux->getPort("\\S")) : st.ffBcemux->getPort("\\S"); +	else +		BHOLD = State::S0; +	if (st.ffCDcemux) +		CDHOLD = st.ffCDcepol ? pm.module->Not(NEW_ID, st.ffCDcemux->getPort("\\S")) : st.ffCDcemux->getPort("\\S"); +	else +		CDHOLD = State::S0; +	cell->setPort("\\AHOLD", AHOLD); +	cell->setPort("\\BHOLD", BHOLD); +	cell->setPort("\\CHOLD", CDHOLD); +	cell->setPort("\\DHOLD", CDHOLD); + +	SigSpec IRSTTOP, IRSTBOT; +	if (st.ffArstmux) +		IRSTTOP = st.ffArstpol ? st.ffArstmux->getPort("\\S") : pm.module->Not(NEW_ID, st.ffArstmux->getPort("\\S")); +	else +		IRSTTOP = State::S0; +	if (st.ffBrstmux) +		IRSTBOT = st.ffBrstpol ? st.ffBrstmux->getPort("\\S") : pm.module->Not(NEW_ID, st.ffBrstmux->getPort("\\S")); +	else +		IRSTBOT = State::S0; +	cell->setPort("\\IRSTTOP", IRSTTOP); +	cell->setPort("\\IRSTBOT", IRSTBOT);  	if (st.clock != SigBit())  	{ @@ -187,11 +209,21 @@ void create_ice40_dsp(ice40_dsp_pm &pm)  		cell->setPort("\\ADDSUBBOT", State::S0);  	} -	cell->setPort("\\ORSTTOP", State::S0); -	cell->setPort("\\ORSTBOT", State::S0); +	SigSpec OHOLD; +	if (st.ffOcemux) +		OHOLD = st.ffOcemux ? pm.module->Not(NEW_ID, st.ffOcemux->getPort("\\S")) : st.ffOcemux->getPort("\\S"); +	else +		OHOLD = State::S0; +	cell->setPort("\\OHOLDTOP", OHOLD); +	cell->setPort("\\OHOLDBOT", OHOLD); -	cell->setPort("\\OHOLDTOP", State::S0); -	cell->setPort("\\OHOLDBOT", State::S0); +	SigSpec ORST; +	if (st.ffOrstmux) +		ORST = st.ffOrstmux ? st.ffOrstmux->getPort("\\S") : pm.module->Not(NEW_ID, st.ffOrstmux->getPort("\\S")); +	else +		ORST = State::S0; +	cell->setPort("\\ORSTTOP", ORST); +	cell->setPort("\\ORSTBOT", ORST);  	SigSpec acc_reset = State::S0;  	if (st.mux) { @@ -200,7 +232,6 @@ void create_ice40_dsp(ice40_dsp_pm &pm)  		else  			acc_reset = pm.module->Not(NEW_ID, st.mux->getPort("\\S"));  	} -  	cell->setPort("\\OLOADTOP", acc_reset);  	cell->setPort("\\OLOADBOT", acc_reset); diff --git a/passes/pmgen/ice40_dsp.pmg b/passes/pmgen/ice40_dsp.pmg index 532995da7..01e344767 100644 --- a/passes/pmgen/ice40_dsp.pmg +++ b/passes/pmgen/ice40_dsp.pmg @@ -9,8 +9,8 @@ state <IdString> addAB muxAB  state <bool> ffAcepol ffBcepol ffCDcepol ffOcepol  state <bool> ffArstpol ffBrstpol ffCDrstpol ffOrstpol -state <Cell*> ffA ffAcemux ffArstmux ffB ffBcemux ffBrstmux ffCD ffCDcemux ffCDrstmux -state <Cell*> ffFJKG ffFJKGrstmux ffH ffHrstmux ffO ffOcemux ffOrstmux +state <Cell*> ffA ffAcemux ffArstmux ffB ffBcemux ffBrstmux ffCD ffCDcemux +state <Cell*> ffFJKG ffH ffO ffOcemux ffOrstmux  // subpattern  state <SigSpec> argQ argD @@ -105,75 +105,79 @@ code argQ ffB ffBcemux ffBrstmux ffBcepol ffBrstpol sigB clock clock_pol  	}  endcode -code argD ffFJKG ffFJKGrstmux sigH sigO clock clock_pol +code argD ffFJKG sigH sigO clock clock_pol  	if (nusers(sigH) == 2 &&  			(mul->type != \SB_MAC16 ||  			 (!param(mul, \TOP_8x8_MULT_REG).as_bool() && !param(mul, \BOT_8x8_MULT_REG).as_bool() && !param(mul, \PIPELINE_16x16_MULT_REG1).as_bool() && !param(mul, \PIPELINE_16x16_MULT_REG1).as_bool()))) {  		argD = sigH;  		subpattern(out_dffe);  		if (dff) { -			ffFJKG = dff; -			clock = dffclock; -			clock_pol = dffclock_pol; -			if (dffrstmux) -				ffFJKGrstmux = dffrstmux;  			// F/J/K/G do not have a CE-like (hold) input  			if (dffcemux) -				reject; +				goto reject_ffFJKG;  			// Reset signal of F/J (IRSTTOP) and K/G (IRSTBOT)  			//   shared with A and B -			if ((ffArstmux != NULL) != (ffFJKGrstmux != NULL)) -				reject; -			if ((ffBrstmux != NULL) != (ffFJKGrstmux != NULL)) -				reject; +			if ((ffArstmux != NULL) != (dffrstmux != NULL)) +				goto reject_ffFJKG; +			if ((ffBrstmux != NULL) != (dffrstmux != NULL)) +				goto reject_ffFJKG;  			if (ffArstmux) { -				if (port(ffArstmux, \S) != port(ffFJKGrstmux, \S)) -					reject; +				if (port(ffArstmux, \S) != port(dffrstmux, \S)) +					goto reject_ffFJKG;  				if (ffArstpol != dffrstpol) -					reject; +					goto reject_ffFJKG;  			}  			if (ffBrstmux) { -				if (port(ffBrstmux, \S) != port(ffFJKGrstmux, \S)) -					reject; +				if (port(ffBrstmux, \S) != port(dffrstmux, \S)) +					goto reject_ffFJKG;  				if (ffBrstpol != dffrstpol) -					reject; +					goto reject_ffFJKG;  			} +			ffFJKG = dff; +			clock = dffclock; +			clock_pol = dffclock_pol;  			sigH = dffQ;  		}  	} + +	if (0) { +reject_ffFJKG: ; +	}  endcode -code argD ffH ffHrstmux sigH sigO clock clock_pol -	if (nusers(sigH) == 2 && +code argD ffH sigH sigO clock clock_pol +	if (ffFJKG && nusers(sigH) == 2 &&  			(mul->type != \SB_MAC16 || !param(mul, \PIPELINE_16x16_MULT_REG2).as_bool())) {  		argD = sigH;  		subpattern(out_dffe);  		if (dff) { -			ffH = dff; -			clock = dffclock; -			clock_pol = dffclock_pol; -			if (dffrstmux) -				ffHrstmux = dffrstmux;  			// H does not have a CE-like (hold) input  			if (dffcemux) -				reject; +				goto reject_ffH;  			// Reset signal of H (IRSTBOT) shared with B -			if ((ffBrstmux != NULL) != (ffHrstmux != NULL)) -				reject; +			if ((ffBrstmux != NULL) != (dffrstmux != NULL)) +				goto reject_ffH;  			if (ffBrstmux) { -				if (port(ffBrstmux, \S) != port(ffHrstmux, \S)) -					reject; +				if (port(ffBrstmux, \S) != port(dffrstmux, \S)) +					goto reject_ffH;  				if (ffBrstpol != dffrstpol) -					reject; +					goto reject_ffH;  			} +			ffH = dff; +			clock = dffclock; +			clock_pol = dffclock_pol;  			sigH = dffQ;  		}  	} +	if (0) { +reject_ffH: ; +	} +  	sigO = sigH;  endcode @@ -274,26 +278,46 @@ code argD ffO ffOcemux ffOrstmux ffOcepol ffOrstpol sigO sigCD clock clock_pol c  	}  endcode -code argQ ffCD ffCDcemux ffCDrstmux ffCDcepol ffCDrstpol sigCD clock clock_pol +code argQ ffCD ffCDcemux ffCDcepol ffCDrstpol sigCD clock clock_pol  	if (!sigCD.empty() &&  			(mul->type != \SB_MAC16 || (!param(mul, \C_REG).as_bool() && !param(mul, \D_REG).as_bool()))) {  		argQ = sigCD;  		subpattern(in_dffe);  		if (dff) { -			ffCD = dff; -			clock = dffclock; -			clock_pol = dffclock_pol; -			if (dffrstmux) { -				ffCDrstmux = dffrstmux; -				ffCDrstpol = dffrstpol; -			}  			if (dffcemux) {  				ffCDcemux = dffcemux;  				ffCDcepol = dffcepol;  			} + +			// Reset signal of C (IRSTTOP) and D (IRSTBOT) +			//   shared with A and B +			if ((ffArstmux != NULL) != (dffrstmux != NULL)) +				goto reject_ffCD; +			if ((ffBrstmux != NULL) != (dffrstmux != NULL)) +				goto reject_ffCD; +			if (ffArstmux) { +				if (port(ffArstmux, \S) != port(dffrstmux, \S)) +					goto reject_ffCD; +				if (ffArstpol != dffrstpol) +					goto reject_ffCD; +			} +			if (ffBrstmux) { +				if (port(ffBrstmux, \S) != port(dffrstmux, \S)) +					goto reject_ffCD; +				if (ffBrstpol != dffrstpol) +					goto reject_ffCD; +			} + +			ffCD = dff; +			clock = dffclock; +			clock_pol = dffclock_pol;  			sigCD = dffD;  		}  	} + +	if (0) { +reject_ffCD: ; +	}  endcode  code sigCD @@ -418,6 +442,9 @@ arg argD argQ clock clock_pol  code  	dff = nullptr; +	for (auto c : argD.chunks()) +		if (c.wire->get_bool_attribute(\keep)) +			reject;  endcode  match ffcemux @@ -434,7 +461,7 @@ match ffcemux  	index <SigBit> port(ffcemux, BA)[offset] === argD[0]  	// Check that the rest of argD is present -	filter GetSize(BA) >= offset + GetSize(argD) +	filter GetSize(port(ffcemux, BA)) >= offset + GetSize(argD)  	filter port(ffcemux, BA).extract(offset, GetSize(argD)) == argD  	set ffoffset offset @@ -448,12 +475,6 @@ code argD argQ  	dffcemux = ffcemux;  	if (ffcemux) {  		SigSpec BA = port(ffcemux, ffcepol ? \B : \A); -		if (ffoffset + GetSize(argD) > GetSize(BA)) -			reject; -		for (int i = 1; i < GetSize(argD); i++) -			if (BA[ffoffset+i] != argD[i]) -				reject; -  		SigSpec Y = port(ffcemux, \Y);  		argQ = argD;  		argD.replace(BA, Y); @@ -480,7 +501,7 @@ match ffrstmux  	// Check that offset is consistent  	filter !ffcemux || ffoffset == offset  	// Check that the rest of argD is present -	filter GetSize(AB) >= offset + GetSize(argD) +	filter GetSize(port(ffrstmux, AB)) >= offset + GetSize(argD)  	filter port(ffrstmux, AB).extract(offset, GetSize(argD)) == argD  	set ffoffset offset @@ -519,8 +540,6 @@ match ff  	filter !ffcemux || port(ff, \Q).extract(offset, GetSize(argQ)) == argQ  	set ffoffset offset - -	semioptional  endmatch  code argQ @@ -531,7 +550,6 @@ code argQ  			if (param(ff, \CLK_POLARITY).as_bool() != clock_pol)  				reject;  		} -  		SigSpec D = port(ff, \D);  		SigSpec Q = port(ff, \Q);  		if (!ffcemux) { @@ -540,8 +558,6 @@ code argQ  		}  		for (auto c : argQ.chunks()) { -			if (c.wire->get_bool_attribute(\keep)) -				reject;  			Const init = c.wire->attributes.at(\init, State::Sx);  			if (!init.is_fully_undef() && !init.is_fully_zero())  				reject;  | 
