mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +00:00 
			
		
		
		
	fix bus ioff inference
This commit is contained in:
		
							parent
							
								
									2241a65f78
								
							
						
					
					
						commit
						9da4fe747e
					
				
					 2 changed files with 91 additions and 8 deletions
				
			
		| 
						 | 
					@ -39,13 +39,14 @@ struct QlIoffPass : public Pass {
 | 
				
			||||||
				if (!(e_const && r_const && s_const))
 | 
									if (!(e_const && r_const && s_const))
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				auto d_sig = modwalker.sigmap(cell->getPort(ID::D));
 | 
									SigSpec d = cell->getPort(ID::D);
 | 
				
			||||||
				if (d_sig.is_wire() && d_sig.as_wire()->port_input) {
 | 
									if (GetSize(d) != 1) continue;
 | 
				
			||||||
 | 
									SigBit d_sig = modwalker.sigmap(d[0]);
 | 
				
			||||||
 | 
									if (d_sig.is_wire() && d_sig.wire->port_input) {
 | 
				
			||||||
					log_debug("Cell %s is potentially eligible for promotion to input IOFF.\n", cell->name.c_str());
 | 
										log_debug("Cell %s is potentially eligible for promotion to input IOFF.\n", cell->name.c_str());
 | 
				
			||||||
					// check that d_sig has no other consumers
 | 
										// check that d_sig has no other consumers
 | 
				
			||||||
					if (GetSize(d_sig) != 1) continue;
 | 
					 | 
				
			||||||
					pool<ModWalker::PortBit> portbits;
 | 
										pool<ModWalker::PortBit> portbits;
 | 
				
			||||||
					modwalker.get_consumers(portbits, d_sig[0]);
 | 
										modwalker.get_consumers(portbits, d_sig);
 | 
				
			||||||
					if (GetSize(portbits) > 1) {
 | 
										if (GetSize(portbits) > 1) {
 | 
				
			||||||
						log_debug("not promoting: d_sig has other consumers\n");
 | 
											log_debug("not promoting: d_sig has other consumers\n");
 | 
				
			||||||
						continue;
 | 
											continue;
 | 
				
			||||||
| 
						 | 
					@ -53,13 +54,14 @@ struct QlIoffPass : public Pass {
 | 
				
			||||||
					cells_to_replace.insert(cell);
 | 
										cells_to_replace.insert(cell);
 | 
				
			||||||
					continue; // no need to check Q if we already put it on the list
 | 
										continue; // no need to check Q if we already put it on the list
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				auto q_sig = modwalker.sigmap(cell->getPort(ID::Q));
 | 
									SigSpec q = cell->getPort(ID::Q);
 | 
				
			||||||
				if (q_sig.is_wire() && q_sig.as_wire()->port_output) {
 | 
									if (GetSize(q) != 1) continue;
 | 
				
			||||||
 | 
									SigBit q_sig = modwalker.sigmap(q[0]);
 | 
				
			||||||
 | 
									if (q_sig.is_wire() && q_sig.wire->port_output) {
 | 
				
			||||||
					log_debug("Cell %s is potentially eligible for promotion to output IOFF.\n", cell->name.c_str());
 | 
										log_debug("Cell %s is potentially eligible for promotion to output IOFF.\n", cell->name.c_str());
 | 
				
			||||||
					// check that q_sig has no other consumers
 | 
										// check that q_sig has no other consumers
 | 
				
			||||||
					if (GetSize(q_sig) != 1) continue;
 | 
					 | 
				
			||||||
					pool<ModWalker::PortBit> portbits;
 | 
										pool<ModWalker::PortBit> portbits;
 | 
				
			||||||
					modwalker.get_consumers(portbits, q_sig[0]);
 | 
										modwalker.get_consumers(portbits, q_sig);
 | 
				
			||||||
					if (GetSize(portbits) > 0) {
 | 
										if (GetSize(portbits) > 0) {
 | 
				
			||||||
						log_debug("not promoting: q_sig has other consumers\n");
 | 
											log_debug("not promoting: q_sig has other consumers\n");
 | 
				
			||||||
						continue;
 | 
											continue;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,18 @@ EOF
 | 
				
			||||||
synth_quicklogic -family qlf_k6n10f -top top
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
select -assert-count 1 t:dff
 | 
					select -assert-count 1 t:dff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					design -reset
 | 
				
			||||||
 | 
					# test: acceptable for output IOFF promotion
 | 
				
			||||||
 | 
					read_verilog <<EOF
 | 
				
			||||||
 | 
					module top (input clk, input [3:0] a, output reg [3:0] o);
 | 
				
			||||||
 | 
					    always @(posedge clk) begin
 | 
				
			||||||
 | 
					        o <= ~a;
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
 | 
					select -assert-count 4 t:dff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
design -reset
 | 
					design -reset
 | 
				
			||||||
# test: acceptable for input IOFF promotion
 | 
					# test: acceptable for input IOFF promotion
 | 
				
			||||||
read_verilog <<EOF
 | 
					read_verilog <<EOF
 | 
				
			||||||
| 
						 | 
					@ -23,6 +35,20 @@ EOF
 | 
				
			||||||
synth_quicklogic -family qlf_k6n10f -top top
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
select -assert-count 1 t:dff
 | 
					select -assert-count 1 t:dff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					design -reset
 | 
				
			||||||
 | 
					# test: acceptable for input IOFF promotion
 | 
				
			||||||
 | 
					read_verilog <<EOF
 | 
				
			||||||
 | 
					module top (input clk, input [3:0] a, output [3:0] o);
 | 
				
			||||||
 | 
					    reg [3:0] r;
 | 
				
			||||||
 | 
					    always @(posedge clk) begin
 | 
				
			||||||
 | 
					        r <= a;
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    assign o = ~r;
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
 | 
					select -assert-count 4 t:dff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
design -reset
 | 
					design -reset
 | 
				
			||||||
# test: acceptable for either IOFF promotion
 | 
					# test: acceptable for either IOFF promotion
 | 
				
			||||||
read_verilog <<EOF
 | 
					read_verilog <<EOF
 | 
				
			||||||
| 
						 | 
					@ -47,6 +73,18 @@ EOF
 | 
				
			||||||
synth_quicklogic -family qlf_k6n10f -top top
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
select -assert-count 0 t:dff
 | 
					select -assert-count 0 t:dff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					design -reset
 | 
				
			||||||
 | 
					# test: not acceptable for output IOFF promotion: output signal is used
 | 
				
			||||||
 | 
					read_verilog <<EOF
 | 
				
			||||||
 | 
					module top (input clk, input [3:0] a, output reg [3:0] o);
 | 
				
			||||||
 | 
					    always @(posedge clk) begin
 | 
				
			||||||
 | 
					        o <= ~a | o;
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
 | 
					select -assert-count 0 t:dff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
design -reset
 | 
					design -reset
 | 
				
			||||||
# test: not acceptable for input IOFF promotion: input signal is used
 | 
					# test: not acceptable for input IOFF promotion: input signal is used
 | 
				
			||||||
read_verilog <<EOF
 | 
					read_verilog <<EOF
 | 
				
			||||||
| 
						 | 
					@ -62,6 +100,21 @@ EOF
 | 
				
			||||||
synth_quicklogic -family qlf_k6n10f -top top
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
select -assert-count 0 t:dff
 | 
					select -assert-count 0 t:dff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					design -reset
 | 
				
			||||||
 | 
					# test: not acceptable for input IOFF promotion: input signal is used
 | 
				
			||||||
 | 
					read_verilog <<EOF
 | 
				
			||||||
 | 
					module top (input clk, input [3:0] a, output [3:0] o, output [3:0] p);
 | 
				
			||||||
 | 
					    reg [3:0] r;
 | 
				
			||||||
 | 
					    always @(posedge clk) begin
 | 
				
			||||||
 | 
					        r <= a;
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    assign o = ~r;
 | 
				
			||||||
 | 
					    assign p = ~a;
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
 | 
					select -assert-count 0 t:dff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
design -reset
 | 
					design -reset
 | 
				
			||||||
# test: not acceptable for IOFF promotion: FF has reset
 | 
					# test: not acceptable for IOFF promotion: FF has reset
 | 
				
			||||||
read_verilog <<EOF
 | 
					read_verilog <<EOF
 | 
				
			||||||
| 
						 | 
					@ -77,6 +130,21 @@ EOF
 | 
				
			||||||
synth_quicklogic -family qlf_k6n10f -top top
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
select -assert-count 0 t:dff
 | 
					select -assert-count 0 t:dff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					design -reset
 | 
				
			||||||
 | 
					# test: not acceptable for IOFF promotion: FF has reset
 | 
				
			||||||
 | 
					read_verilog <<EOF
 | 
				
			||||||
 | 
					module top (input clk, input rst, input [3:0] a, output reg [3:0] o);
 | 
				
			||||||
 | 
					    always @(posedge clk) begin
 | 
				
			||||||
 | 
					        if (rst)
 | 
				
			||||||
 | 
					            o <= 4'b0;
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            o <= a;
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
 | 
					select -assert-count 0 t:dff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
design -reset
 | 
					design -reset
 | 
				
			||||||
# test: not acceptable for IOFF promotion: FF has enable
 | 
					# test: not acceptable for IOFF promotion: FF has enable
 | 
				
			||||||
read_verilog <<EOF
 | 
					read_verilog <<EOF
 | 
				
			||||||
| 
						 | 
					@ -89,3 +157,16 @@ endmodule
 | 
				
			||||||
EOF
 | 
					EOF
 | 
				
			||||||
synth_quicklogic -family qlf_k6n10f -top top
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
select -assert-count 0 t:dff
 | 
					select -assert-count 0 t:dff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					design -reset
 | 
				
			||||||
 | 
					# test: not acceptable for IOFF promotion: FF has enable
 | 
				
			||||||
 | 
					read_verilog <<EOF
 | 
				
			||||||
 | 
					module top (input clk, input en, input [3:0] a, output reg [3:0] o);
 | 
				
			||||||
 | 
					    always @(posedge clk) begin
 | 
				
			||||||
 | 
					        if (en)
 | 
				
			||||||
 | 
					            o <= a;
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
					synth_quicklogic -family qlf_k6n10f -top top
 | 
				
			||||||
 | 
					select -assert-count 0 t:dff
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue