mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Merge branch 'YosysHQ:main' into main
This commit is contained in:
		
						commit
						6e88c689f2
					
				
					 20 changed files with 196 additions and 24 deletions
				
			
		
							
								
								
									
										8
									
								
								.github/workflows/test-compile.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/test-compile.yml
									
										
									
									
										vendored
									
									
								
							|  | @ -32,9 +32,9 @@ jobs: | |||
|           # oldest supported | ||||
|           - 'clang-14' | ||||
|           - 'gcc-10' | ||||
|           # newest | ||||
|           - 'clang' | ||||
|           - 'gcc' | ||||
|           # newest, make sure to update maximum standard step to match | ||||
|           - 'clang-18' | ||||
|           - 'gcc-13' | ||||
|         include: | ||||
|           # macOS | ||||
|           - os: macos-13 | ||||
|  | @ -72,7 +72,7 @@ jobs: | |||
| 
 | ||||
|       # maximum standard, only on newest compilers | ||||
|       - name: Build C++20 | ||||
|         if: ${{ matrix.compiler == 'clang' || matrix.compiler == 'gcc'}} | ||||
|         if: ${{ matrix.compiler == 'clang-18' || matrix.compiler == 'gcc-13' }} | ||||
|         shell: bash | ||||
|         run: | | ||||
|           make config-$CC_SHORT | ||||
|  |  | |||
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -164,7 +164,7 @@ ifeq ($(OS), Haiku) | |||
| CXXFLAGS += -D_DEFAULT_SOURCE | ||||
| endif | ||||
| 
 | ||||
| YOSYS_VER := 0.47+116 | ||||
| YOSYS_VER := 0.47+149 | ||||
| 
 | ||||
| # Note: We arrange for .gitcommit to contain the (short) commit hash in
 | ||||
| # tarballs generated with git-archive(1) using .gitattributes. The git repo
 | ||||
|  |  | |||
|  | @ -242,7 +242,7 @@ Processes | |||
| 
 | ||||
| Declares a process, with zero or more attributes, with the given identifier in | ||||
| the enclosing module. The body of a process consists of zero or more | ||||
| assignments, exactly one switch, and zero or more syncs. | ||||
| assignments followed by zero or more switches and zero or more syncs. | ||||
| 
 | ||||
| See :ref:`sec:rtlil_process` for an overview of processes. | ||||
| 
 | ||||
|  | @ -250,7 +250,7 @@ See :ref:`sec:rtlil_process` for an overview of processes. | |||
| 
 | ||||
|     <process>       ::= <attr-stmt>* <proc-stmt> <process-body> <proc-end-stmt> | ||||
|     <proc-stmt>     ::= process <id> <eol> | ||||
|     <process-body>  ::= <assign-stmt>* <switch>? <assign-stmt>* <sync>* | ||||
|     <process-body>  ::= <assign-stmt>* <switch>* <sync>* | ||||
|     <assign-stmt>   ::= assign <dest-sigspec> <src-sigspec> <eol> | ||||
|     <dest-sigspec>  ::= <sigspec> | ||||
|     <src-sigspec>   ::= <sigspec> | ||||
|  | @ -262,8 +262,8 @@ Switches | |||
| Switches test a signal for equality against a list of cases. Each case specifies | ||||
| a comma-separated list of signals to check against. If there are no signals in | ||||
| the list, then the case is the default case. The body of a case consists of zero | ||||
| or more switches and assignments. Both switches and cases may have zero or more | ||||
| attributes. | ||||
| or more assignments followed by zero or more switches. Both switches and cases | ||||
| may have zero or more attributes. | ||||
| 
 | ||||
| .. code:: BNF | ||||
| 
 | ||||
|  | @ -272,7 +272,7 @@ attributes. | |||
|     <case>              ::= <attr-stmt>* <case-stmt> <case-body> | ||||
|     <case-stmt>         ::= case <compare>? <eol> | ||||
|     <compare>           ::= <sigspec> (, <sigspec>)* | ||||
|     <case-body>         ::= (<switch> | <assign-stmt>)* | ||||
|     <case-body>         ::= <assign-stmt>* <switch>* | ||||
|     <switch-end-stmt>   ::= end <eol> | ||||
| 
 | ||||
| Syncs | ||||
|  |  | |||
|  | @ -56,6 +56,9 @@ if os.getenv("READTHEDOCS"): | |||
|     else: | ||||
|         release = yosys_ver | ||||
|         todo_include_todos = False | ||||
| elif os.getenv("YOSYS_DOCS_RELEASE") is not None: | ||||
|     release = yosys_ver | ||||
|     todo_include_todos = False | ||||
| else: | ||||
|     release = yosys_ver | ||||
|     todo_include_todos = True | ||||
|  | @ -87,5 +90,9 @@ def setup(app: Sphinx) -> None: | |||
|     from util.RtlilLexer import RtlilLexer | ||||
|     app.add_lexer("RTLIL", RtlilLexer) | ||||
| 
 | ||||
|     from furo_ys.lexers.YoscryptLexer import YoscryptLexer | ||||
|     app.add_lexer("yoscrypt", YoscryptLexer) | ||||
|     try: | ||||
|         from furo_ys.lexers.YoscryptLexer import YoscryptLexer | ||||
|         app.add_lexer("yoscrypt", YoscryptLexer) | ||||
|     except ModuleNotFoundError: | ||||
|         from pygments.lexers.special import TextLexer | ||||
|         app.add_lexer("yoscrypt", TextLexer) | ||||
|  |  | |||
|  | @ -31,6 +31,11 @@ void rtlil_frontend_yyerror(char const *s) | |||
| 	YOSYS_NAMESPACE_PREFIX log_error("Parser error in line %d: %s\n", rtlil_frontend_yyget_lineno(), s); | ||||
| } | ||||
| 
 | ||||
| void rtlil_frontend_yywarning(char const *s) | ||||
| { | ||||
| 	YOSYS_NAMESPACE_PREFIX log_warning("In line %d: %s\n", rtlil_frontend_yyget_lineno(), s); | ||||
| } | ||||
| 
 | ||||
| YOSYS_NAMESPACE_BEGIN | ||||
| 
 | ||||
| struct RTLILFrontend : public Frontend { | ||||
|  |  | |||
|  | @ -42,6 +42,7 @@ YOSYS_NAMESPACE_END | |||
| extern int rtlil_frontend_yydebug; | ||||
| int rtlil_frontend_yylex(void); | ||||
| void rtlil_frontend_yyerror(char const *s); | ||||
| void rtlil_frontend_yywarning(char const *s); | ||||
| void rtlil_frontend_yyrestart(FILE *f); | ||||
| int rtlil_frontend_yyparse(void); | ||||
| int rtlil_frontend_yylex_destroy(void); | ||||
|  |  | |||
|  | @ -344,6 +344,16 @@ assign_stmt: | |||
| 	TOK_ASSIGN sigspec sigspec EOL { | ||||
| 		if (attrbuf.size() != 0) | ||||
| 			rtlil_frontend_yyerror("dangling attribute"); | ||||
| 
 | ||||
| 		// See https://github.com/YosysHQ/yosys/pull/4765 for discussion on this | ||||
| 		// warning | ||||
| 		if (!switch_stack.back()->empty()) { | ||||
| 			rtlil_frontend_yywarning( | ||||
| 				"case rule assign statements after switch statements may cause unexpected behaviour. " | ||||
| 				"The assign statement is reordered to come before all switch statements." | ||||
| 			); | ||||
| 		} | ||||
| 
 | ||||
| 		case_stack.back()->actions.push_back(RTLIL::SigSig(*$2, *$3)); | ||||
| 		delete $2; | ||||
| 		delete $3; | ||||
|  |  | |||
|  | @ -2186,12 +2186,6 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma | |||
| 				log("    assert condition %s.\n", log_signal(cond)); | ||||
| 
 | ||||
| 			Cell *cell = module->addAssert(new_verific_id(inst), cond, State::S1); | ||||
| 			// Initialize FF feeding condition  to 1, in case it is not
 | ||||
| 			// used by rest of design logic, to prevent failing on
 | ||||
| 			// initial uninitialized state
 | ||||
| 			if (cond.is_wire() && !cond.wire->name.isPublic()) | ||||
| 				cond.wire->attributes[ID::init] = Const(1,1); | ||||
| 
 | ||||
| 			import_attributes(cell->attributes, inst); | ||||
| 			continue; | ||||
| 		} | ||||
|  | @ -3566,6 +3560,7 @@ struct VerificPass : public Pass { | |||
| 			RuntimeFlags::SetVar("veri_preserve_assignments", 1); | ||||
| 			RuntimeFlags::SetVar("veri_preserve_comments", 1); | ||||
| 			RuntimeFlags::SetVar("veri_preserve_drivers", 1); | ||||
| 			RuntimeFlags::SetVar("veri_create_empty_box", 1); | ||||
| 
 | ||||
| 			// Workaround for VIPER #13851
 | ||||
| 			RuntimeFlags::SetVar("veri_create_name_for_unnamed_gen_block", 1); | ||||
|  |  | |||
|  | @ -364,7 +364,7 @@ public: | |||
| 
 | ||||
| 	unsigned int hash() const | ||||
| 	{ | ||||
| 		unsigned int inner; | ||||
| 		unsigned int inner = 0; | ||||
| 		switch (type_) | ||||
| 		{ | ||||
| 			case DriveType::NONE: | ||||
|  | @ -385,6 +385,9 @@ public: | |||
| 			case DriveType::MULTIPLE: | ||||
| 				inner = multiple_.hash(); | ||||
| 				break; | ||||
| 			default: | ||||
| 				log_abort(); | ||||
| 				break; | ||||
| 		} | ||||
| 		return mkhash((unsigned int)type_, inner); | ||||
| 	} | ||||
|  | @ -912,7 +915,7 @@ public: | |||
| 
 | ||||
| 	unsigned int hash() const | ||||
| 	{ | ||||
| 		unsigned int inner; | ||||
| 		unsigned int inner = 0; | ||||
| 		switch (type_) | ||||
| 		{ | ||||
| 			case DriveType::NONE: | ||||
|  | @ -933,6 +936,9 @@ public: | |||
| 			case DriveType::MULTIPLE: | ||||
| 				inner = multiple_.hash(); | ||||
| 				break; | ||||
| 			default: | ||||
| 				log_abort(); | ||||
| 				break; | ||||
| 		} | ||||
| 		return mkhash((unsigned int)type_, inner); | ||||
| 	} | ||||
|  |  | |||
|  | @ -814,6 +814,7 @@ struct RTLIL::AttrObject | |||
| 	void set_bool_attribute(const RTLIL::IdString &id, bool value=true); | ||||
| 	bool get_bool_attribute(const RTLIL::IdString &id) const; | ||||
| 
 | ||||
| 	[[deprecated("Use Module::get_blackbox_attribute() instead.")]] | ||||
| 	bool get_blackbox_attribute(bool ignore_wb=false) const { | ||||
| 		return get_bool_attribute(ID::blackbox) || (!ignore_wb && get_bool_attribute(ID::whitebox)); | ||||
| 	} | ||||
|  | @ -1291,6 +1292,10 @@ public: | |||
| 	virtual void optimize(); | ||||
| 	virtual void makeblackbox(); | ||||
| 
 | ||||
| 	bool get_blackbox_attribute(bool ignore_wb=false) const { | ||||
| 		return get_bool_attribute(ID::blackbox) || (!ignore_wb && get_bool_attribute(ID::whitebox)); | ||||
| 	} | ||||
| 
 | ||||
| 	void connect(const RTLIL::SigSig &conn); | ||||
| 	void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); | ||||
| 	void new_connections(const std::vector<RTLIL::SigSig> &new_conn); | ||||
|  |  | |||
|  | @ -1019,8 +1019,10 @@ struct HierarchyPass : public Pass { | |||
| 
 | ||||
| 		if (top_mod == nullptr) | ||||
| 			for (auto mod : design->modules()) | ||||
| 				if (mod->get_bool_attribute(ID::top)) | ||||
| 				if (mod->get_bool_attribute(ID::top)) { | ||||
| 					log("Attribute `top' found on module `%s'. Setting top module to %s.\n", log_id(mod), log_id(mod)); | ||||
| 					top_mod = mod; | ||||
| 				} | ||||
| 
 | ||||
| 		if (top_mod == nullptr) | ||||
| 		{ | ||||
|  |  | |||
|  | @ -36,3 +36,4 @@ $(eval $(call add_share_file,share,techlibs/common/abc9_unmap.v)) | |||
| $(eval $(call add_share_file,share,techlibs/common/cmp2lcu.v)) | ||||
| $(eval $(call add_share_file,share,techlibs/common/cmp2softlogic.v)) | ||||
| $(eval $(call add_share_file,share/choices,techlibs/common/choices/kogge-stone.v)) | ||||
| $(eval $(call add_share_file,share/choices,techlibs/common/choices/han-carlson.v)) | ||||
|  |  | |||
							
								
								
									
										57
									
								
								techlibs/common/choices/han-carlson.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								techlibs/common/choices/han-carlson.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,57 @@ | |||
| (* techmap_celltype = "$lcu" *) | ||||
| module _80_lcu_han_carlson (P, G, CI, CO); | ||||
| 	parameter WIDTH = 2; | ||||
| 
 | ||||
| 	(* force_downto *) | ||||
| 	input [WIDTH-1:0] P, G; | ||||
| 	input CI; | ||||
| 
 | ||||
| 	(* force_downto *) | ||||
| 	output [WIDTH-1:0] CO; | ||||
| 
 | ||||
| 	integer i, j; | ||||
| 	(* force_downto *) | ||||
| 	reg [WIDTH-1:0] p, g; | ||||
| 
 | ||||
| 	always @* begin | ||||
| 		i = 0; | ||||
| 		p = P; | ||||
| 		g = G; | ||||
| 
 | ||||
| 		// in almost all cases CI will be constant zero
 | ||||
| 		g[0] = g[0] | (p[0] & CI); | ||||
| 		if (i < $clog2(WIDTH)) begin | ||||
| 
 | ||||
| 			// First layer: BK
 | ||||
| 			for (j = WIDTH - 1; j >= 0; j = j - 1) begin | ||||
| 				if (j % 2 == 1) begin | ||||
| 					g[j] = g[j] | p[j] & g[j - 1]; | ||||
| 					p[j] = p[j] & p[j - 1]; | ||||
| 				end | ||||
| 			end | ||||
| 
 | ||||
| 			// Inner (log(WIDTH) - 1) layers: KS
 | ||||
| 			for (i = 1; i < $clog2(WIDTH); i = i + 1) begin | ||||
| 				for (j = WIDTH - 1; j >= 2**i; j = j - 1) begin | ||||
| 					if (j % 2 == 1) begin | ||||
| 						g[j] = g[j] | p[j] & g[j - 2**i]; | ||||
| 						p[j] = p[j] & p[j - 2**i]; | ||||
| 					end | ||||
| 				end | ||||
| 			end | ||||
| 
 | ||||
| 			// Last layer: BK
 | ||||
| 			if (i < ($clog2(WIDTH) + 1)) begin | ||||
| 				for (j = WIDTH - 1; j >= 0; j = j - 1) begin | ||||
| 					if ((j % 2 == 0) && (j > 0)) begin | ||||
| 						g[j] = g[j] | p[j] & g[j - 1]; | ||||
| 						p[j] = p[j] & p[j - 1]; | ||||
| 					end | ||||
| 				end | ||||
| 			end | ||||
| 
 | ||||
| 		end | ||||
| 	end | ||||
| 
 | ||||
| 	assign CO = g; | ||||
| endmodule | ||||
|  | @ -20,6 +20,13 @@ generate_ys_test() { | |||
| 	generate_target "$ys_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${ys_file%.*}.log $yosys_args_ $ys_file" | ||||
| } | ||||
| 
 | ||||
| # $ generate_tcl_test tcl_file [yosys_args] | ||||
| generate_tcl_test() { | ||||
| 	tcl_file=$1 | ||||
| 	yosys_args_=${2:-} | ||||
| 	generate_target "$tcl_file" "\"$YOSYS_BASEDIR/yosys\" -ql ${tcl_file%.*}.log $yosys_args_ $tcl_file" | ||||
| } | ||||
| 
 | ||||
| # $ generate_bash_test bash_file | ||||
| generate_bash_test() { | ||||
| 	bash_file=$1 | ||||
|  | @ -29,6 +36,7 @@ generate_bash_test() { | |||
| # $ generate_tests [-y|--yosys-scripts] [-s|--prove-sv] [-b|--bash] [-a|--yosys-args yosys_args] | ||||
| generate_tests() { | ||||
| 	do_ys=false | ||||
| 	do_tcl=false | ||||
| 	do_sv=false | ||||
| 	do_sh=false | ||||
| 	yosys_args="" | ||||
|  | @ -40,6 +48,10 @@ generate_tests() { | |||
| 				do_ys=true | ||||
| 				shift | ||||
| 				;; | ||||
| 			-t|--tcl-scripts) | ||||
| 				do_tcl=true | ||||
| 				shift | ||||
| 				;; | ||||
| 			-s|--prove-sv) | ||||
| 				do_sv=true | ||||
| 				shift | ||||
|  | @ -59,7 +71,7 @@ generate_tests() { | |||
| 		esac | ||||
| 	done | ||||
| 
 | ||||
| 	if [[ ! ( $do_ys = true || $do_sv = true || $do_sh = true ) ]]; then | ||||
| 	if [[ ! ( $do_ys = true || $do_tcl = true || $do_sv = true || $do_sh = true ) ]]; then | ||||
| 		echo >&2 "Error: No file types selected" | ||||
| 		exit 1 | ||||
| 	fi | ||||
|  | @ -72,6 +84,11 @@ generate_tests() { | |||
| 			generate_ys_test "$x" "$yosys_args" | ||||
| 		done | ||||
| 	fi; | ||||
| 	if [[ $do_tcl = true ]]; then | ||||
| 		for x in *.tcl; do | ||||
| 			generate_tcl_test "$x" "$yosys_args" | ||||
| 		done | ||||
| 	fi; | ||||
| 	if [[ $do_sv = true ]]; then | ||||
| 		for x in *.sv; do | ||||
| 			if [ ! -f "${x%.sv}.ys"  ]; then | ||||
|  |  | |||
							
								
								
									
										15
									
								
								tests/techmap/han-carlson.tcl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/techmap/han-carlson.tcl
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| yosys -import | ||||
| 
 | ||||
| read_verilog +/choices/han-carlson.v | ||||
| read_verilog -icells lcu_refined.v | ||||
| design -save init | ||||
| 
 | ||||
| for {set i 1} {$i <= 16} {incr i} { | ||||
|     design -load init | ||||
|     chparam -set WIDTH $i | ||||
|     yosys proc | ||||
|     opt_clean | ||||
|     equiv_make lcu _80_lcu_han_carlson equiv | ||||
|     equiv_simple equiv | ||||
|     equiv_status -assert equiv | ||||
| } | ||||
							
								
								
									
										15
									
								
								tests/techmap/kogge-stone.tcl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								tests/techmap/kogge-stone.tcl
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| yosys -import | ||||
| 
 | ||||
| read_verilog +/choices/kogge-stone.v | ||||
| read_verilog -icells lcu_refined.v | ||||
| design -save init | ||||
| 
 | ||||
| for {set i 1} {$i <= 16} {incr i} { | ||||
|     design -load init | ||||
|     chparam -set WIDTH $i | ||||
|     yosys proc | ||||
|     opt_clean | ||||
|     equiv_make lcu _80_lcu_kogge_stone equiv | ||||
|     equiv_simple equiv | ||||
|     equiv_status -assert equiv | ||||
| } | ||||
|  | @ -1 +0,0 @@ | |||
| test_cell -s 1711533949 -n 10 -map +/techmap.v -map +/choices/kogge-stone.v $lcu | ||||
							
								
								
									
										13
									
								
								tests/techmap/lcu_refined.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tests/techmap/lcu_refined.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| module lcu (P, G, CI, CO); | ||||
| 	parameter WIDTH = 2; | ||||
| 
 | ||||
| 	input [WIDTH-1:0] P, G; | ||||
| 	input CI; | ||||
| 
 | ||||
| 	output [WIDTH-1:0] CO; | ||||
| 
 | ||||
| 	reg [WIDTH-1:0] p, g; | ||||
| 
 | ||||
| 	\$lcu #(.WIDTH(WIDTH)) impl (.P(P), .G(G), .CI(CI), .CO(CO)); | ||||
| 
 | ||||
| endmodule | ||||
|  | @ -1,4 +1,4 @@ | |||
| #!/usr/bin/env bash | ||||
| set -eu | ||||
| source ../gen-tests-makefile.sh | ||||
| run_tests --yosys-scripts --bash --yosys-args "-e 'select out of bounds'" | ||||
| run_tests --yosys-scripts --tcl-scripts --bash --yosys-args "-e 'select out of bounds'" | ||||
|  |  | |||
							
								
								
									
										24
									
								
								tests/verific/blackbox.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								tests/verific/blackbox.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| verific -sv -lib <<EOF | ||||
| module TEST_CELL(input clk, input a, input b, output reg c); | ||||
| parameter PATH = "DEFAULT"; | ||||
| always @(posedge clk) begin | ||||
|     if (PATH=="DEFAULT") | ||||
| 		c <= a; | ||||
| 	else  | ||||
| 		c <= b; | ||||
| end | ||||
| 
 | ||||
| endmodule | ||||
| EOF | ||||
| 
 | ||||
| verific -sv <<EOF | ||||
| module top(input clk, input a, input b, output c, output d); | ||||
| 	TEST_CELL  #(.PATH("TEST")) test1(.clk(clk),.a(a),.b(1'b1),.c(c)); | ||||
| 	TEST_CELL  #(.PATH("DEFAULT")) test2(.clk(clk),.a(a),.b(1'bx),.c(d)); | ||||
| endmodule | ||||
| EOF | ||||
| 
 | ||||
| verific -import top | ||||
| hierarchy -top top | ||||
| stat | ||||
| select -assert-count 2 t:TEST_CELL | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue