mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Merge pull request #3305 from jix/sva_value_change_logic
verific: Improve logic generated for SVA value change expressions
This commit is contained in:
		
						commit
						587e09d551
					
				
					 8 changed files with 121 additions and 11 deletions
				
			
		| 
						 | 
					@ -1557,17 +1557,25 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			SigSpec sig_d = net_map_at(inst->GetInput1());
 | 
								SigSpec sig_d = net_map_at(inst->GetInput1());
 | 
				
			||||||
			SigSpec sig_o = net_map_at(inst->GetOutput());
 | 
								SigSpec sig_o = net_map_at(inst->GetOutput());
 | 
				
			||||||
			SigSpec sig_q = module->addWire(new_verific_id(inst));
 | 
								SigSpec sig_dx = module->addWire(new_verific_id(inst), 2);
 | 
				
			||||||
 | 
								SigSpec sig_qx = module->addWire(new_verific_id(inst), 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (verific_verbose) {
 | 
								if (verific_verbose) {
 | 
				
			||||||
 | 
									log("    NEX with A=%s, B=0, Y=%s.\n",
 | 
				
			||||||
 | 
											log_signal(sig_d), log_signal(sig_dx[0]));
 | 
				
			||||||
 | 
									log("    EQX with A=%s, B=1, Y=%s.\n",
 | 
				
			||||||
 | 
											log_signal(sig_d), log_signal(sig_dx[1]));
 | 
				
			||||||
				log("    %sedge FF with D=%s, Q=%s, C=%s.\n", clocking.posedge ? "pos" : "neg",
 | 
									log("    %sedge FF with D=%s, Q=%s, C=%s.\n", clocking.posedge ? "pos" : "neg",
 | 
				
			||||||
						log_signal(sig_d), log_signal(sig_q), log_signal(clocking.clock_sig));
 | 
											log_signal(sig_dx), log_signal(sig_qx), log_signal(clocking.clock_sig));
 | 
				
			||||||
				log("    XNOR with A=%s, B=%s, Y=%s.\n",
 | 
									log("    EQ with A=%s, B=%s, Y=%s.\n",
 | 
				
			||||||
						log_signal(sig_d), log_signal(sig_q), log_signal(sig_o));
 | 
											log_signal(sig_dx), log_signal(sig_qx), log_signal(sig_o));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			clocking.addDff(new_verific_id(inst), sig_d, sig_q);
 | 
								module->addNex(new_verific_id(inst), sig_d, State::S0, sig_dx[0]);
 | 
				
			||||||
			module->addXnor(new_verific_id(inst), sig_d, sig_q, sig_o);
 | 
								module->addEqx(new_verific_id(inst), sig_d, State::S1, sig_dx[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								clocking.addDff(new_verific_id(inst), sig_dx, sig_qx, Const(1, 2));
 | 
				
			||||||
 | 
								module->addEq(new_verific_id(inst), sig_dx, sig_qx, sig_o);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!mode_keep)
 | 
								if (!mode_keep)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
| 
						 | 
					@ -1601,13 +1609,20 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma
 | 
				
			||||||
			SigBit sig_d = net_map_at(inst->GetInput1());
 | 
								SigBit sig_d = net_map_at(inst->GetInput1());
 | 
				
			||||||
			SigBit sig_o = net_map_at(inst->GetOutput());
 | 
								SigBit sig_o = net_map_at(inst->GetOutput());
 | 
				
			||||||
			SigBit sig_q = module->addWire(new_verific_id(inst));
 | 
								SigBit sig_q = module->addWire(new_verific_id(inst));
 | 
				
			||||||
 | 
								SigBit sig_d_no_x = module->addWire(new_verific_id(inst));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (verific_verbose)
 | 
								if (verific_verbose) {
 | 
				
			||||||
 | 
									log("    EQX with A=%s, B=%d, Y=%s.\n",
 | 
				
			||||||
 | 
											log_signal(sig_d), inst->Type() == PRIM_SVA_ROSE, log_signal(sig_d_no_x));
 | 
				
			||||||
				log("    %sedge FF with D=%s, Q=%s, C=%s.\n", clocking.posedge ? "pos" : "neg",
 | 
									log("    %sedge FF with D=%s, Q=%s, C=%s.\n", clocking.posedge ? "pos" : "neg",
 | 
				
			||||||
						log_signal(sig_d), log_signal(sig_q), log_signal(clocking.clock_sig));
 | 
											log_signal(sig_d_no_x), log_signal(sig_q), log_signal(clocking.clock_sig));
 | 
				
			||||||
 | 
									log("    EQ with A={%s, %s}, B={0, 1}, Y=%s.\n",
 | 
				
			||||||
 | 
											log_signal(sig_q), log_signal(sig_d_no_x), log_signal(sig_o));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			clocking.addDff(new_verific_id(inst), sig_d, sig_q);
 | 
								module->addEqx(new_verific_id(inst), sig_d, inst->Type() == PRIM_SVA_ROSE ? State::S1 : State::S0, sig_d_no_x);
 | 
				
			||||||
			module->addEq(new_verific_id(inst), {sig_q, sig_d}, Const(inst->Type() == PRIM_SVA_ROSE ? 1 : 2, 2), sig_o);
 | 
								clocking.addDff(new_verific_id(inst), sig_d_no_x, sig_q, State::S0);
 | 
				
			||||||
 | 
								module->addEq(new_verific_id(inst), {sig_q, sig_d_no_x}, Const(1, 2), sig_o);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!mode_keep)
 | 
								if (!mode_keep)
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								tests/sva/.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								tests/sva/.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -3,5 +3,6 @@
 | 
				
			||||||
/*_pass
 | 
					/*_pass
 | 
				
			||||||
/*_fail
 | 
					/*_fail
 | 
				
			||||||
/*.ok
 | 
					/*.ok
 | 
				
			||||||
 | 
					/*.fst
 | 
				
			||||||
/vhdlpsl[0-9][0-9]
 | 
					/vhdlpsl[0-9][0-9]
 | 
				
			||||||
/vhdlpsl[0-9][0-9].sby
 | 
					/vhdlpsl[0-9][0-9].sby
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,4 +10,5 @@ clean:
 | 
				
			||||||
	rm -rf $(addsuffix .ok,$(TESTS)) $(addsuffix .sby,$(TESTS)) $(TESTS)
 | 
						rm -rf $(addsuffix .ok,$(TESTS)) $(addsuffix .sby,$(TESTS)) $(TESTS)
 | 
				
			||||||
	rm -rf $(addsuffix _pass.sby,$(TESTS)) $(addsuffix _pass,$(TESTS))
 | 
						rm -rf $(addsuffix _pass.sby,$(TESTS)) $(addsuffix _pass,$(TESTS))
 | 
				
			||||||
	rm -rf $(addsuffix _fail.sby,$(TESTS)) $(addsuffix _fail,$(TESTS))
 | 
						rm -rf $(addsuffix _fail.sby,$(TESTS)) $(addsuffix _fail,$(TESTS))
 | 
				
			||||||
 | 
						rm -rf $(addsuffix .fst,$(TESTS))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,7 +57,9 @@ generate_sby() {
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if [ -f $prefix.sv ]; then
 | 
					if [ -f $prefix.ys ]; then
 | 
				
			||||||
 | 
						$PWD/../../yosys -q -e "Assert .* failed." -s $prefix.ys
 | 
				
			||||||
 | 
					elif [ -f $prefix.sv ]; then
 | 
				
			||||||
	generate_sby pass > ${prefix}_pass.sby
 | 
						generate_sby pass > ${prefix}_pass.sby
 | 
				
			||||||
	generate_sby fail > ${prefix}_fail.sby
 | 
						generate_sby fail > ${prefix}_fail.sby
 | 
				
			||||||
	sby --yosys $PWD/../../yosys -f ${prefix}_pass.sby
 | 
						sby --yosys $PWD/../../yosys -f ${prefix}_pass.sby
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								tests/sva/sva_value_change_changed.sv
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/sva/sva_value_change_changed.sv
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,17 @@
 | 
				
			||||||
 | 
					module top (
 | 
				
			||||||
 | 
						input clk,
 | 
				
			||||||
 | 
						input a, b
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
						default clocking @(posedge clk); endclocking
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert property (
 | 
				
			||||||
 | 
							$changed(b)
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`ifndef FAIL
 | 
				
			||||||
 | 
						assume property (
 | 
				
			||||||
 | 
							b !== 'x ##1 $changed(b)
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					`endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
							
								
								
									
										20
									
								
								tests/sva/sva_value_change_rose.sv
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								tests/sva/sva_value_change_rose.sv
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					module top (
 | 
				
			||||||
 | 
						input clk,
 | 
				
			||||||
 | 
						input a, b
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
						default clocking @(posedge clk); endclocking
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    wire a_copy;
 | 
				
			||||||
 | 
					    assign a_copy = a;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert property (
 | 
				
			||||||
 | 
							$rose(a) |-> b
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`ifndef FAIL
 | 
				
			||||||
 | 
						assume property (
 | 
				
			||||||
 | 
							$rose(a_copy) |-> b
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					`endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
							
								
								
									
										51
									
								
								tests/sva/sva_value_change_sim.sv
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								tests/sva/sva_value_change_sim.sv
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,51 @@
 | 
				
			||||||
 | 
					module top (
 | 
				
			||||||
 | 
						input clk
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					reg [7:0] counter = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					reg a = 0;
 | 
				
			||||||
 | 
					reg b = 1;
 | 
				
			||||||
 | 
					reg c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					wire a_fell; assign a_fell = $fell(a, @(posedge clk));
 | 
				
			||||||
 | 
					wire a_rose; assign a_rose = $rose(a, @(posedge clk));
 | 
				
			||||||
 | 
					wire a_stable; assign a_stable = $stable(a, @(posedge clk));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					wire b_fell; assign b_fell = $fell(b, @(posedge clk));
 | 
				
			||||||
 | 
					wire b_rose; assign b_rose = $rose(b, @(posedge clk));
 | 
				
			||||||
 | 
					wire b_stable; assign b_stable = $stable(b, @(posedge clk));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					wire c_fell; assign c_fell = $fell(c, @(posedge clk));
 | 
				
			||||||
 | 
					wire c_rose; assign c_rose = $rose(c, @(posedge clk));
 | 
				
			||||||
 | 
					wire c_stable; assign c_stable = $stable(c, @(posedge clk));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					always @(posedge clk) begin
 | 
				
			||||||
 | 
						counter <= counter + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						case (counter)
 | 
				
			||||||
 | 
							0: begin
 | 
				
			||||||
 | 
					            assert property ( $fell(a) && !$rose(a) && !$stable(a));
 | 
				
			||||||
 | 
					            assert property (!$fell(b) &&  $rose(b) && !$stable(b));
 | 
				
			||||||
 | 
					            assert property (!$fell(c) && !$rose(c) &&  $stable(c));
 | 
				
			||||||
 | 
					            a <= 1; b <= 1; c <= 1;
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
							1: begin a <= 0; b <= 1; c <= 'x; end
 | 
				
			||||||
 | 
							2: begin
 | 
				
			||||||
 | 
					            assert property ( $fell(a) && !$rose(a) && !$stable(a));
 | 
				
			||||||
 | 
					            assert property (!$fell(b) && !$rose(b) &&  $stable(b));
 | 
				
			||||||
 | 
					            assert property (!$fell(c) && !$rose(c) && !$stable(c));
 | 
				
			||||||
 | 
					            a <= 0; b <= 0; c <= 0;
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
							3: begin a <= 0; b <= 1; c <= 'x; end
 | 
				
			||||||
 | 
							4: begin
 | 
				
			||||||
 | 
					            assert property (!$fell(a) && !$rose(a) &&  $stable(a));
 | 
				
			||||||
 | 
					            assert property (!$fell(b) &&  $rose(b) && !$stable(b));
 | 
				
			||||||
 | 
					            assert property (!$fell(c) && !$rose(c) && !$stable(c));
 | 
				
			||||||
 | 
					            a <= 'x; b <= 'x; c <= 'x;
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
							5: begin a <= 0; b <= 1; c <= 'x; counter <= 0; end
 | 
				
			||||||
 | 
						endcase;
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
							
								
								
									
										3
									
								
								tests/sva/sva_value_change_sim.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								tests/sva/sva_value_change_sim.ys
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					read -sv sva_value_change_sim.sv
 | 
				
			||||||
 | 
					hierarchy -top top
 | 
				
			||||||
 | 
					sim -clock clk -fst sva_value_change_sim.fst
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue