mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			177 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| design -reset
 | |
| read_verilog <<EOT
 | |
| module test(input a, output [7:0] y);
 | |
| assign y = a * 0;
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| equiv_opt -assert opt_expr -fine
 | |
| design -load postopt
 | |
| # The multiplication by zero should be replaced with constant zero
 | |
| select -assert-count 0 t:$mul
 | |
| 
 | |
| ## opt.opt_expr.mul_shift
 | |
| 
 | |
| design -reset
 | |
| read_verilog <<EOT
 | |
| module test(input [7:0] a, output [15:0] y, output [15:0] z);
 | |
| assign y = a * 8; // Multiply by 2^3 (power of 2)
 | |
| assign z = 8 * a;
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| equiv_opt -assert opt_expr -fine
 | |
| design -load postopt
 | |
| # The multiplication by 8 should be replaced with a shift by const
 | |
| select -assert-count 0 t:$mul
 | |
| # No shift operator cells should be present
 | |
| select -assert-count 0 t:$shl
 | |
| 
 | |
| design -reset
 | |
| read_verilog <<EOT
 | |
| module test(input [7:0] a, output [7:0] y);
 | |
| assign y = a / 4; // Division by 2^2 (power of 2)
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| equiv_opt -assert opt_expr -fine
 | |
| design -load postopt
 | |
| # The division by 4 should be replaced with a shift by const
 | |
| select -assert-count 0 t:$div
 | |
| 
 | |
| design -reset
 | |
| read_verilog <<EOT
 | |
| module test(input [7:0] a, output [7:0] y);
 | |
| assign y = a / 0; // Division by zero should be replaced with x
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| opt_expr -fine
 | |
| # The division by zero should be removed
 | |
| select -assert-count 0 t:$div
 | |
| # No cells should be left as it's replaced with constant undef
 | |
| select -assert-none t:*
 | |
| 
 | |
| design -reset
 | |
| read_verilog <<EOT
 | |
| module test(input s, output y);
 | |
| assign y = s ? 1'b1 : 1'b0; // This is equivalent to just 's'
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| equiv_opt -assert opt_expr -fine -mux_bool
 | |
| design -load postopt
 | |
| # The mux should be removed completely
 | |
| select -assert-count 0 t:$mux
 | |
| # No additional cells needed - direct connection
 | |
| select -assert-none t:*
 | |
| 
 | |
| design -reset
 | |
| read_verilog <<EOT
 | |
| module test(input s, output y);
 | |
| assign y = s ? 1'b0 : 1'b1; // This is equivalent to '!s'
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| equiv_opt -assert opt_expr -fine -mux_bool
 | |
| design -load postopt
 | |
| # The mux should be converted to a not gate
 | |
| select -assert-count 0 t:$mux
 | |
| select -assert-count 1 t:$not
 | |
| 
 | |
| design -reset
 | |
| read_verilog <<EOT
 | |
| module test(input [3:0] a, input [3:0] b, output y);
 | |
| assign y = (a == b); // Test equality optimization
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| equiv_opt -assert opt_expr -fine
 | |
| design -load postopt
 | |
| # Check for optimization of equality comparison
 | |
| select -assert-count 1 t:$eq
 | |
| 
 | |
| # opt.opt_expr.eqneq.*
 | |
| 
 | |
| design -reset
 | |
| read_verilog -noopt <<EOT
 | |
| module test(output y1, y2, y3, y4);
 | |
| // Compare two constants that are guaranteed to be different
 | |
| assign y1 = 2'b01 == 2'b10;
 | |
| assign y2 = 2'b01 != 2'b10;
 | |
| assign y3 = 2'b01 !== 2'b10;
 | |
| assign y4 = 2'b01 === 2'b10;
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| equiv_opt -assert opt_expr
 | |
| select -assert-count 1 t:$eq
 | |
| design -load postopt
 | |
| # The comparison of different constants should be replaced with constant 0
 | |
| select -assert-count 0 t:$eq
 | |
| # No other cells should be present (just the constant driver)
 | |
| select -assert-none t:*
 | |
| 
 | |
| # opt.opt_expr.invert.double
 | |
| 
 | |
| design -reset
 | |
| read_verilog -noopt <<EOT
 | |
| module test(input a, output y);
 | |
| // Double negation should be optimized away
 | |
| wire not_a;
 | |
| assign not_a = ~a;
 | |
| assign y = ~not_a;
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| equiv_opt -assert opt_expr
 | |
| select -assert-count 2 t:$not
 | |
| design -load postopt
 | |
| # Both NOT gates should be eliminated
 | |
| opt_clean -purge
 | |
| select -assert-count 0 t:$not
 | |
| # No other cells should be present
 | |
| select -assert-none t:*
 | |
| 
 | |
| # opt.opt_expr.reduce_xnor_not
 | |
| 
 | |
| design -reset
 | |
| read_verilog -noopt <<EOT
 | |
| module test(input a, output y);
 | |
| assign y = ~^a; // XNOR reduction of a single bit
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| equiv_opt -assert opt_expr -full
 | |
| design -load postopt
 | |
| select -assert-count 0 t:$reduce_xnor
 | |
| select -assert-count 1 t:$not
 | |
| 
 | |
| ## opt.opt_expr.mod_mask
 | |
| 
 | |
| design -reset
 | |
| read_verilog -noopt <<EOT
 | |
| module test(input [7:0] a, output [7:0] y);
 | |
| assign y = a % 8; // Modulo by power of 2
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| select -assert-count 1 t:$mod
 | |
| equiv_opt -assert opt_expr -full
 | |
| design -load postopt
 | |
| select -assert-count 0 t:$mod
 | |
| select -assert-count 0 t:$and
 | |
| 
 | |
| ## opt.opt_expr.eqneq.empty (indirectly)
 | |
| 
 | |
| design -reset
 | |
| read_verilog -noopt <<EOT
 | |
| module test(output [7:0] y1);
 | |
| assign y1 = 7'b1 == 7'b1;
 | |
| endmodule
 | |
| EOT
 | |
| 
 | |
| select -assert-count 1 t:$eq
 | |
| equiv_opt -assert opt_expr -full
 | |
| design -load postopt
 | |
| select -assert-count 0 t:$eq
 |