From 161cdd349c591c24ee8be069f3015b14163bd5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Ji=C5=99=C3=AD=20Tywoniak?= Date: Wed, 24 Sep 2025 11:30:29 +0200 Subject: [PATCH 01/35] io: add append_globbed to resolve globs in regular pass arguments --- kernel/io.cc | 7 +++++++ kernel/io.h | 1 + 2 files changed, 8 insertions(+) diff --git a/kernel/io.cc b/kernel/io.cc index 4c593501c..9e9eb9fb0 100644 --- a/kernel/io.cc +++ b/kernel/io.cc @@ -384,6 +384,13 @@ std::string escape_filename_spaces(const std::string& filename) return out; } +void append_globbed(std::vector& paths, std::string pattern) +{ + rewrite_filename(pattern); + std::vector globbed = glob_filename(pattern); + copy(globbed.begin(), globbed.end(), back_inserter(paths)); +} + void format_emit_unescaped(std::string &result, std::string_view fmt) { result.reserve(result.size() + fmt.size()); diff --git a/kernel/io.h b/kernel/io.h index 2ad0a6466..b3922bef0 100644 --- a/kernel/io.h +++ b/kernel/io.h @@ -469,6 +469,7 @@ bool is_absolute_path(std::string filename); void remove_directory(std::string dirname); bool create_directory(const std::string& dirname); std::string escape_filename_spaces(const std::string& filename); +void append_globbed(std::vector& paths, std::string pattern); YOSYS_NAMESPACE_END From a28c0c632b399f239ad3d0aa3d4a1197bfde9fc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Ji=C5=99=C3=AD=20Tywoniak?= Date: Wed, 24 Sep 2025 11:30:49 +0200 Subject: [PATCH 02/35] clockgate: support liberty filename globbing --- passes/techmap/clockgate.cc | 4 +--- tests/techmap/clockgate.ys | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/passes/techmap/clockgate.cc b/passes/techmap/clockgate.cc index 7c6ca5551..b68e5d93d 100644 --- a/passes/techmap/clockgate.cc +++ b/passes/techmap/clockgate.cc @@ -290,9 +290,7 @@ struct ClockgatePass : public Pass { continue; } if (args[argidx] == "-liberty" && argidx+1 < args.size()) { - std::string liberty_file = args[++argidx]; - rewrite_filename(liberty_file); - liberty_files.push_back(liberty_file); + append_globbed(liberty_files, args[++argidx]); continue; } if (args[argidx] == "-dont_use" && argidx+1 < args.size()) { diff --git a/tests/techmap/clockgate.ys b/tests/techmap/clockgate.ys index da0f9dc42..c28852ef8 100644 --- a/tests/techmap/clockgate.ys +++ b/tests/techmap/clockgate.ys @@ -194,7 +194,7 @@ select -assert-count 1 t:\\pdk_icg #------------------------------------------------------------------------------ design -load before -clockgate -liberty clockgate.lib +clockgate -liberty c*ckgate.lib # rising edge ICGs select -module dffe_00 -assert-count 0 t:\\pos_small From 856a387aad0377a85c1bf24427c37149d2d0acaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Ji=C5=99=C3=AD=20Tywoniak?= Date: Wed, 24 Sep 2025 11:30:57 +0200 Subject: [PATCH 03/35] dfflibmap: support liberty filename globbing --- passes/techmap/dfflibmap.cc | 4 +--- tests/techmap/dfflibmap.ys | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index f3b96aeec..f2bd16082 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -609,9 +609,7 @@ struct DfflibmapPass : public Pass { { std::string arg = args[argidx]; if (arg == "-liberty" && argidx+1 < args.size()) { - std::string liberty_file = args[++argidx]; - rewrite_filename(liberty_file); - liberty_files.push_back(liberty_file); + append_globbed(liberty_files, args[++argidx]); continue; } if (arg == "-prepare") { diff --git a/tests/techmap/dfflibmap.ys b/tests/techmap/dfflibmap.ys index 822d87a36..303daee48 100644 --- a/tests/techmap/dfflibmap.ys +++ b/tests/techmap/dfflibmap.ys @@ -23,7 +23,7 @@ read_liberty -lib dfflibmap.lib equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -liberty dfflibmap.lib equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -prepare -liberty dfflibmap.lib -dfflibmap -prepare -liberty dfflibmap.lib +dfflibmap -prepare -liberty dffl*bmap.lib equiv_opt -map dfflibmap-sim.v -assert -multiclock dfflibmap -map-only -liberty dfflibmap.lib design -load orig From 4508676e678af683991a7c3a37a997dca309dad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emil=20Ji=C5=99=C3=AD=20Tywoniak?= Date: Wed, 24 Sep 2025 11:31:06 +0200 Subject: [PATCH 04/35] libcache: support liberty filename globbing --- passes/techmap/libcache.cc | 4 +--- tests/liberty/libcache.ys | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/passes/techmap/libcache.cc b/passes/techmap/libcache.cc index c833a6046..e4326c49f 100644 --- a/passes/techmap/libcache.cc +++ b/passes/techmap/libcache.cc @@ -96,9 +96,7 @@ quiet = true; continue; } - std::string fname = args[argidx]; - rewrite_filename(fname); - paths.push_back(fname); + append_globbed(paths, args[argidx]); break; } int modes = enable + disable + purge + list + verbose + quiet; diff --git a/tests/liberty/libcache.ys b/tests/liberty/libcache.ys index 04257aa92..8132b3f11 100644 --- a/tests/liberty/libcache.ys +++ b/tests/liberty/libcache.ys @@ -1,5 +1,5 @@ libcache -verbose -libcache -enable busdef.lib +libcache -enable bus*f.lib logger -expect log "Caching is disabled by default." 1 logger -expect log "Caching is enabled for `busdef.lib'." 1 From 1a0b5d8ea70391100e5d3b7b08bc8b228f4627ee Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 24 May 2024 03:42:12 +1200 Subject: [PATCH 05/35] write_btor: Include `$assert` and `$assume` cells in -ywmap output --- backends/btor/btor.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index bba7249c7..ca7cf8a7f 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -98,6 +98,8 @@ struct BtorWorker vector ywmap_states; dict ywmap_clock_bits; dict ywmap_clock_inputs; + vector ywmap_asserts; + vector ywmap_assumes; PrettyJson ywmap_json; @@ -1280,6 +1282,8 @@ struct BtorWorker btorf("%d or %d %d %d\n", nid_a_or_not_en, sid, nid_a, nid_not_en); btorf("%d constraint %d\n", nid, nid_a_or_not_en); + if (ywmap_json.active()) ywmap_assumes.emplace_back(cell); + btorf_pop(log_id(cell)); } @@ -1304,6 +1308,8 @@ struct BtorWorker } else { int nid = next_nid++; btorf("%d bad %d%s\n", nid, nid_en_and_not_a, getinfo(cell, true)); + + if (ywmap_json.active()) ywmap_asserts.emplace_back(cell); } } @@ -1461,6 +1467,7 @@ struct BtorWorker log_assert(cursor == 0); log_assert(GetSize(todo) == 1); btorf("%d bad %d\n", nid, todo[cursor]); + // What do we do with ywmap_asserts when using single_bad? } } @@ -1526,6 +1533,18 @@ struct BtorWorker emit_ywmap_btor_sig(entry); ywmap_json.end_array(); + ywmap_json.name("asserts"); + ywmap_json.begin_array(); + for (Cell *cell : ywmap_asserts) + ywmap_json.value(witness_path(cell)); + ywmap_json.end_array(); + + ywmap_json.name("assumes"); + ywmap_json.begin_array(); + for (Cell *cell : ywmap_assumes) + ywmap_json.value(witness_path(cell)); + ywmap_json.end_array(); + ywmap_json.end_object(); } } From 02e40e811823b3165e4fbae15a3bb17554cb8ae2 Mon Sep 17 00:00:00 2001 From: YRabbit Date: Sat, 11 Oct 2025 21:12:35 +1000 Subject: [PATCH 06/35] Gowin. Reduce the range of flip-flop types. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UG303-1.0E_Arora Ⅴ Configurable Function Unit (CFU) User Guide.pdf specifies that the only flip-flop types supported in GW5 are DFFSE, DFFRE, DFFPE, and DFFCE. However, the bit streams generated by the vendor IDE also contain DFF flip-flops, which are probably the result of optimisation, so we leave them in the list of permitted items, but add a flag that will allow the generation of completely correct output files, acceptable for further P& R using vendor tools (they will not allow the use of flip-flops other than the four specified in the netlist). In the GW5 SemiDual Port BSRAM series, the primitive does not have RESETA and RESETB ports—they are replaced by the RESET port, so we separate the files for BSRAM generation, especially since in the future we may have to take into account other, as yet unexplored, differences in BSRAM. Signed-off-by: YRabbit --- techlibs/gowin/Makefile.inc | 1 + techlibs/gowin/brams_map_gw5a.v | 399 ++++++++++++++++++++++++++++++++ techlibs/gowin/synth_gowin.cc | 28 ++- 3 files changed, 422 insertions(+), 6 deletions(-) create mode 100644 techlibs/gowin/brams_map_gw5a.v diff --git a/techlibs/gowin/Makefile.inc b/techlibs/gowin/Makefile.inc index 9ec7dce4d..df1b79317 100644 --- a/techlibs/gowin/Makefile.inc +++ b/techlibs/gowin/Makefile.inc @@ -8,6 +8,7 @@ $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_xtra_gw2a.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_xtra_gw5a.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/arith_map.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_map.v)) +$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_map_gw5a.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/brams.txt)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams_map.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/lutrams.txt)) diff --git a/techlibs/gowin/brams_map_gw5a.v b/techlibs/gowin/brams_map_gw5a.v new file mode 100644 index 000000000..246146ee5 --- /dev/null +++ b/techlibs/gowin/brams_map_gw5a.v @@ -0,0 +1,399 @@ +`define DEF_FUNCS \ + function [255:0] init_slice_x8; \ + input integer idx; \ + integer i; \ + for (i = 0; i < 32; i = i + 1) begin \ + init_slice_x8[i*8+:8] = INIT[(idx * 32 + i) * 9+:8]; \ + end \ + endfunction \ + function [287:0] init_slice_x9; \ + input integer idx; \ + init_slice_x9 = INIT[idx * 288+:288]; \ + endfunction \ + +`define x8_width(width) (width / 9 * 8 + width % 9) +`define x8_rd_data(data) {1'bx, data[31:24], 1'bx, data[23:16], 1'bx, data[15:8], 1'bx, data[7:0]} +`define x8_wr_data(data) {data[34:27], data[25:18], data[16:9], data[7:0]} +`define addrbe_always(width, addr) (width < 18 ? addr : width == 18 ? {addr[13:4], 4'b0011} : {addr[13:5], 5'b01111}) + + +`define INIT(func) \ + .INIT_RAM_00(func('h00)), \ + .INIT_RAM_01(func('h01)), \ + .INIT_RAM_02(func('h02)), \ + .INIT_RAM_03(func('h03)), \ + .INIT_RAM_04(func('h04)), \ + .INIT_RAM_05(func('h05)), \ + .INIT_RAM_06(func('h06)), \ + .INIT_RAM_07(func('h07)), \ + .INIT_RAM_08(func('h08)), \ + .INIT_RAM_09(func('h09)), \ + .INIT_RAM_0A(func('h0a)), \ + .INIT_RAM_0B(func('h0b)), \ + .INIT_RAM_0C(func('h0c)), \ + .INIT_RAM_0D(func('h0d)), \ + .INIT_RAM_0E(func('h0e)), \ + .INIT_RAM_0F(func('h0f)), \ + .INIT_RAM_10(func('h10)), \ + .INIT_RAM_11(func('h11)), \ + .INIT_RAM_12(func('h12)), \ + .INIT_RAM_13(func('h13)), \ + .INIT_RAM_14(func('h14)), \ + .INIT_RAM_15(func('h15)), \ + .INIT_RAM_16(func('h16)), \ + .INIT_RAM_17(func('h17)), \ + .INIT_RAM_18(func('h18)), \ + .INIT_RAM_19(func('h19)), \ + .INIT_RAM_1A(func('h1a)), \ + .INIT_RAM_1B(func('h1b)), \ + .INIT_RAM_1C(func('h1c)), \ + .INIT_RAM_1D(func('h1d)), \ + .INIT_RAM_1E(func('h1e)), \ + .INIT_RAM_1F(func('h1f)), \ + .INIT_RAM_20(func('h20)), \ + .INIT_RAM_21(func('h21)), \ + .INIT_RAM_22(func('h22)), \ + .INIT_RAM_23(func('h23)), \ + .INIT_RAM_24(func('h24)), \ + .INIT_RAM_25(func('h25)), \ + .INIT_RAM_26(func('h26)), \ + .INIT_RAM_27(func('h27)), \ + .INIT_RAM_28(func('h28)), \ + .INIT_RAM_29(func('h29)), \ + .INIT_RAM_2A(func('h2a)), \ + .INIT_RAM_2B(func('h2b)), \ + .INIT_RAM_2C(func('h2c)), \ + .INIT_RAM_2D(func('h2d)), \ + .INIT_RAM_2E(func('h2e)), \ + .INIT_RAM_2F(func('h2f)), \ + .INIT_RAM_30(func('h30)), \ + .INIT_RAM_31(func('h31)), \ + .INIT_RAM_32(func('h32)), \ + .INIT_RAM_33(func('h33)), \ + .INIT_RAM_34(func('h34)), \ + .INIT_RAM_35(func('h35)), \ + .INIT_RAM_36(func('h36)), \ + .INIT_RAM_37(func('h37)), \ + .INIT_RAM_38(func('h38)), \ + .INIT_RAM_39(func('h39)), \ + .INIT_RAM_3A(func('h3a)), \ + .INIT_RAM_3B(func('h3b)), \ + .INIT_RAM_3C(func('h3c)), \ + .INIT_RAM_3D(func('h3d)), \ + .INIT_RAM_3E(func('h3e)), \ + .INIT_RAM_3F(func('h3f)), + +module $__GOWIN_SP_ (...); + +parameter INIT = 0; +parameter OPTION_RESET_MODE = "SYNC"; + +parameter PORT_A_WIDTH = 36; +parameter PORT_A_OPTION_WRITE_MODE = 0; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [13:0] PORT_A_ADDR; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +`DEF_FUNCS + +wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST; +wire [13:0] AD = `addrbe_always(PORT_A_WIDTH, PORT_A_ADDR); + +generate + +if (PORT_A_WIDTH < 9) begin + + wire [31:0] DI = `x8_wr_data(PORT_A_WR_DATA); + wire [31:0] DO; + + assign PORT_A_RD_DATA = `x8_rd_data(DO); + + SP #( + `INIT(init_slice_x8) + .READ_MODE(1'b0), + .WRITE_MODE(PORT_A_OPTION_WRITE_MODE), + .BIT_WIDTH(`x8_width(PORT_A_WIDTH)), + .BLK_SEL(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSEL(3'b000), + .CLK(PORT_A_CLK), + .CE(PORT_A_CLK_EN), + .WRE(PORT_A_WR_EN), + .RESET(RST), + .OCE(1'b1), + .AD(AD), + .DI(DI), + .DO(DO), + ); + +end else begin + + wire [35:0] DI = PORT_A_WR_DATA; + wire [35:0] DO; + + assign PORT_A_RD_DATA = DO; + + SPX9 #( + `INIT(init_slice_x9) + .READ_MODE(1'b0), + .WRITE_MODE(PORT_A_OPTION_WRITE_MODE), + .BIT_WIDTH(PORT_A_WIDTH), + .BLK_SEL(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSEL(3'b000), + .CLK(PORT_A_CLK), + .CE(PORT_A_CLK_EN), + .WRE(PORT_A_WR_EN), + .RESET(RST), + .OCE(1'b1), + .AD(AD), + .DI(DI), + .DO(DO), + ); + +end + +endgenerate + +endmodule + + +module $__GOWIN_DP_ (...); + +parameter INIT = 0; +parameter OPTION_RESET_MODE = "SYNC"; + +parameter PORT_A_WIDTH = 18; +parameter PORT_A_OPTION_WRITE_MODE = 0; + +parameter PORT_B_WIDTH = 18; +parameter PORT_B_OPTION_WRITE_MODE = 0; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [13:0] PORT_A_ADDR; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input PORT_B_WR_EN; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; +input [13:0] PORT_B_ADDR; +input [PORT_A_WIDTH-1:0] PORT_B_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_B_RD_DATA; + +`DEF_FUNCS + +wire RSTA = OPTION_RESET_MODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST; +wire RSTB = OPTION_RESET_MODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST; +wire [13:0] ADA = `addrbe_always(PORT_A_WIDTH, PORT_A_ADDR); +wire [13:0] ADB = `addrbe_always(PORT_B_WIDTH, PORT_B_ADDR); + +generate + +if (PORT_A_WIDTH < 9 || PORT_B_WIDTH < 9) begin + + wire [15:0] DIA = `x8_wr_data(PORT_A_WR_DATA); + wire [15:0] DIB = `x8_wr_data(PORT_B_WR_DATA); + wire [15:0] DOA; + wire [15:0] DOB; + + assign PORT_A_RD_DATA = `x8_rd_data(DOA); + assign PORT_B_RD_DATA = `x8_rd_data(DOB); + + DPB #( + `INIT(init_slice_x8) + .READ_MODE0(1'b0), + .READ_MODE1(1'b0), + .WRITE_MODE0(PORT_A_OPTION_WRITE_MODE), + .WRITE_MODE1(PORT_B_OPTION_WRITE_MODE), + .BIT_WIDTH_0(`x8_width(PORT_A_WIDTH)), + .BIT_WIDTH_1(`x8_width(PORT_B_WIDTH)), + .BLK_SEL_0(3'b000), + .BLK_SEL_1(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSELA(3'b000), + .BLKSELB(3'b000), + + .CLKA(PORT_A_CLK), + .CEA(PORT_A_CLK_EN), + .WREA(PORT_A_WR_EN), + .RESETA(RSTA), + .OCEA(1'b1), + .ADA(ADA), + .DIA(DIA), + .DOA(DOA), + + .CLKB(PORT_B_CLK), + .CEB(PORT_B_CLK_EN), + .WREB(PORT_B_WR_EN), + .RESETB(RSTB), + .OCEB(1'b1), + .ADB(ADB), + .DIB(DIB), + .DOB(DOB), + ); + +end else begin + + wire [17:0] DIA = PORT_A_WR_DATA; + wire [17:0] DIB = PORT_B_WR_DATA; + wire [17:0] DOA; + wire [17:0] DOB; + + assign PORT_A_RD_DATA = DOA; + assign PORT_B_RD_DATA = DOB; + + DPX9B #( + `INIT(init_slice_x9) + .READ_MODE0(1'b0), + .READ_MODE1(1'b0), + .WRITE_MODE0(PORT_A_OPTION_WRITE_MODE), + .WRITE_MODE1(PORT_B_OPTION_WRITE_MODE), + .BIT_WIDTH_0(PORT_A_WIDTH), + .BIT_WIDTH_1(PORT_B_WIDTH), + .BLK_SEL_0(3'b000), + .BLK_SEL_1(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSELA(3'b000), + .BLKSELB(3'b000), + + .CLKA(PORT_A_CLK), + .CEA(PORT_A_CLK_EN), + .WREA(PORT_A_WR_EN), + .RESETA(RSTA), + .OCEA(1'b1), + .ADA(ADA), + .DIA(DIA), + .DOA(DOA), + + .CLKB(PORT_B_CLK), + .CEB(PORT_B_CLK_EN), + .WREB(PORT_B_WR_EN), + .RESETB(RSTB), + .OCEB(1'b1), + .ADB(ADB), + .DIB(DIB), + .DOB(DOB), + ); + +end + +endgenerate + +endmodule + + +module $__GOWIN_SDP_ (...); + +parameter INIT = 0; +parameter OPTION_RESET_MODE = "SYNC"; + +parameter PORT_R_WIDTH = 18; +parameter PORT_W_WIDTH = 18; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input PORT_R_RD_SRST; +input PORT_R_RD_ARST; +input [13:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input PORT_W_WR_EN; +input [13:0] PORT_W_ADDR; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; + +`DEF_FUNCS + +wire RST = OPTION_RESET_MODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST; +wire [13:0] ADW = `addrbe_always(PORT_W_WIDTH, PORT_W_ADDR); +wire WRE = PORT_W_CLK_EN & PORT_W_WR_EN; + +generate + +if (PORT_W_WIDTH < 9 || PORT_R_WIDTH < 9) begin + + wire [31:0] DI = `x8_wr_data(PORT_W_WR_DATA); + wire [31:0] DO; + + assign PORT_R_RD_DATA = `x8_rd_data(DO); + + SDPB #( + `INIT(init_slice_x8) + .READ_MODE(1'b0), + .BIT_WIDTH_0(`x8_width(PORT_W_WIDTH)), + .BIT_WIDTH_1(`x8_width(PORT_R_WIDTH)), + .BLK_SEL_0(3'b000), + .BLK_SEL_1(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSELA(3'b000), + .BLKSELB(3'b000), + + .CLKA(PORT_W_CLK), + .CEA(WRE), + .ADA(ADW), + .DI(DI), + + .CLKB(PORT_R_CLK), + .CEB(PORT_R_CLK_EN), + .RESET(RST), + .OCE(1'b1), + .ADB(PORT_R_ADDR), + .DO(DO), + ); + +end else begin + + wire [35:0] DI = PORT_W_WR_DATA; + wire [35:0] DO; + + assign PORT_R_RD_DATA = DO; + + SDPX9B #( + `INIT(init_slice_x9) + .READ_MODE(1'b0), + .BIT_WIDTH_0(PORT_W_WIDTH), + .BIT_WIDTH_1(PORT_R_WIDTH), + .BLK_SEL_0(3'b000), + .BLK_SEL_1(3'b000), + .RESET_MODE(OPTION_RESET_MODE), + ) _TECHMAP_REPLACE_ ( + .BLKSELA(3'b000), + .BLKSELB(3'b000), + + .CLKA(PORT_W_CLK), + .CEA(WRE), + .ADA(ADW), + .DI(DI), + + .CLKB(PORT_R_CLK), + .CEB(PORT_R_CLK_EN), + .RESET(RST), + .OCE(1'b1), + .ADB(PORT_R_ADDR), + .DO(DO), + ); + +end + +endgenerate + +endmodule diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 8f3553df6..03766ed36 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -57,6 +57,9 @@ struct SynthGowinPass : public ScriptPass log(" -nodffe\n"); log(" do not use flipflops with CE in output netlist\n"); log("\n"); + log(" -strict-gw5a-dffs\n"); + log(" use only DFFSE/DFFRE/DFFPE/DFFCE flipflops for the GW5A family\n"); + log("\n"); log(" -nobram\n"); log(" do not use BRAM cells in output netlist\n"); log("\n"); @@ -97,7 +100,7 @@ struct SynthGowinPass : public ScriptPass } string top_opt, vout_file, json_file, family; - bool retime, nobram, nolutram, flatten, nodffe, nowidelut, abc9, noiopads, noalu, no_rw_check; + bool retime, nobram, nolutram, flatten, nodffe, strict_gw5a_dffs, nowidelut, abc9, noiopads, noalu, no_rw_check; void clear_flags() override { @@ -109,6 +112,7 @@ struct SynthGowinPass : public ScriptPass flatten = true; nobram = false; nodffe = false; + strict_gw5a_dffs = false; nolutram = false; nowidelut = false; abc9 = true; @@ -165,6 +169,10 @@ struct SynthGowinPass : public ScriptPass nodffe = true; continue; } + if (args[argidx] == "-strict-gw5a-dffs") { + strict_gw5a_dffs = true; + continue; + } if (args[argidx] == "-noflatten") { flatten = false; continue; @@ -248,7 +256,7 @@ struct SynthGowinPass : public ScriptPass args += " -no-auto-distributed"; } run("memory_libmap -lib +/gowin/lutrams.txt -lib +/gowin/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); - run("techmap -map +/gowin/lutrams_map.v -map +/gowin/brams_map.v"); + run(stringf("techmap -map +/gowin/lutrams_map.v -map +/gowin/brams_map%s.v", family == "gw5a" ? "_gw5a" : "")); } if (check_label("map_ffram")) @@ -276,10 +284,18 @@ struct SynthGowinPass : public ScriptPass if (check_label("map_ffs")) { run("opt_clean"); - if (nodffe) - run("dfflegalize -cell $_DFF_?_ 0 -cell $_SDFF_?P?_ r -cell $_DFF_?P?_ r"); - else - run("dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_SDFF_?P?_ r -cell $_SDFFE_?P?P_ r -cell $_DFF_?P?_ r -cell $_DFFE_?P?P_ r"); + if (family == "gw5a") { + if (strict_gw5a_dffs) { + run("dfflegalize -cell $_SDFFE_PP?P_ r -cell $_DFFE_PP?P_ r"); + } else { + run("dfflegalize -cell $_DFF_?_ 0 -cell $_SDFFE_PP?P_ r -cell $_DFFE_PP?P_ r"); + } + } else { + if (nodffe) + run("dfflegalize -cell $_DFF_?_ 0 -cell $_SDFF_?P?_ r -cell $_DFF_?P?_ r"); + else + run("dfflegalize -cell $_DFF_?_ 0 -cell $_DFFE_?P_ 0 -cell $_SDFF_?P?_ r -cell $_SDFFE_?P?P_ r -cell $_DFF_?P?_ r -cell $_DFFE_?P?P_ r"); + } run("techmap -map +/gowin/cells_map.v"); run("opt_expr -mux_undef"); run("simplemap"); From 2f8f421dee5d71a3c2c6ca0dbf09610b2b4d0e84 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 13 Oct 2025 09:47:18 +0200 Subject: [PATCH 07/35] verifix: fix bits() deprecation warnings --- frontends/verific/verific.cc | 21 ++++++++++----------- frontends/verific/verificsva.cc | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 408542131..e56fd9e50 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1663,7 +1663,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma if (*ascii_initdata == 0) break; if (*ascii_initdata == '0' || *ascii_initdata == '1') { - initval.bits()[bit_idx] = (*ascii_initdata == '0') ? State::S0 : State::S1; + initval.set(bit_idx, (*ascii_initdata == '0') ? State::S0 : State::S1); initval_valid = true; } ascii_initdata++; @@ -1787,9 +1787,9 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma if (init_nets.count(net)) { if (init_nets.at(net) == '0') - initval.bits().at(bitidx) = State::S0; + initval.set(bitidx, State::S0); if (init_nets.at(net) == '1') - initval.bits().at(bitidx) = State::S1; + initval.set(bitidx, State::S1); initval_valid = true; init_nets.erase(net); } @@ -1862,13 +1862,12 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma if (bit.wire->attributes.count(ID::init)) initval = bit.wire->attributes.at(ID::init); - while (GetSize(initval) < GetSize(bit.wire)) - initval.bits().push_back(State::Sx); + initval.resize(GetSize(bit.wire), State::Sx); if (it.second == '0') - initval.bits().at(bit.offset) = State::S0; + initval.set(bit.offset, State::S0); if (it.second == '1') - initval.bits().at(bit.offset) = State::S1; + initval.set(bit.offset, State::S1); bit.wire->attributes[ID::init] = initval; } @@ -2055,7 +2054,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma } Const qx_init = Const(State::S1, width); - qx_init.bits().resize(2 * width, State::S0); + qx_init.resize(2 * width, State::S0); clocking.addDff(new_verific_id(inst), sig_dx, sig_qx, qx_init); module->addXnor(new_verific_id(inst), sig_dx, sig_qx, sig_ox); @@ -2320,7 +2319,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma continue; if (non_ff_bits.count(SigBit(wire, i))) - initval.bits()[i] = State::Sx; + initval.set(i, State::Sx); } if (wire->port_input) { @@ -2513,7 +2512,7 @@ Cell *VerificClocking::addDff(IdString name, SigSpec sig_d, SigSpec sig_q, Const if (c.wire && c.wire->attributes.count(ID::init)) { Const val = c.wire->attributes.at(ID::init); for (int i = 0; i < GetSize(c); i++) - initval.bits()[offset+i] = val[c.offset+i]; + initval.set(offset+i, val[c.offset+i]); } offset += GetSize(c); } @@ -2584,7 +2583,7 @@ Cell *VerificClocking::addAldff(IdString name, RTLIL::SigSpec sig_aload, RTLIL:: if (c.wire && c.wire->attributes.count(ID::init)) { Const val = c.wire->attributes.at(ID::init); for (int i = 0; i < GetSize(c); i++) - initval.bits()[offset+i] = val[c.offset+i]; + initval.set(offset+i, val[c.offset+i]); } offset += GetSize(c); } diff --git a/frontends/verific/verificsva.cc b/frontends/verific/verificsva.cc index 50e0049ae..dffe6e8e0 100644 --- a/frontends/verific/verificsva.cc +++ b/frontends/verific/verificsva.cc @@ -577,7 +577,7 @@ struct SvaFsm if (delta_pos >= 0 && i_within_j && j_within_i) { did_something = true; - values[i].bits()[delta_pos] = State::Sa; + values[i].set(delta_pos, State::Sa); values[j] = values.back(); values.pop_back(); goto next_pair; From 9570b395193691967491a23be8af3efd79d01866 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 13 Oct 2025 09:57:22 +0200 Subject: [PATCH 08/35] verifix: fix bits() deprecation warnings --- frontends/verific/verific.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index e56fd9e50..937789842 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1862,7 +1862,8 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma if (bit.wire->attributes.count(ID::init)) initval = bit.wire->attributes.at(ID::init); - initval.resize(GetSize(bit.wire), State::Sx); + if (GetSize(initval) < GetSize(bit.wire)) + initval.resize(GetSize(bit.wire), State::Sx); if (it.second == '0') initval.set(bit.offset, State::S0); From dc959cdf4abdcc696585cc8fa9d587042132018a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 13 Oct 2025 09:11:46 +0200 Subject: [PATCH 09/35] verific: Fix error compiling without VERIFIC_LINEFILE_INCLUDES_COLUMNS --- frontends/verific/verific.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 937789842..2d0e6959e 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -168,12 +168,12 @@ string get_full_netlist_name(Netlist *nl) std::string format_src_location(DesignObj *obj) { - if (obj == nullptr || obj->Linefile() == nullptr) + if (obj == nullptr || !obj->Linefile()) return std::string(); #ifdef VERIFIC_LINEFILE_INCLUDES_COLUMNS - return stringf("%s:%d.%d-%d.%d", LineFile::GetFileName(obj->Linefile()), obj->Linefile()->GetLeftLine(), obj->Linefile()->GetLeftCol(), obj->Linefile()->GetRightLine(), obj->Linefile()->GetRightCol()); + return stringf("%s:%d.%d-%d.%d", LineFile::GetFileName(obj->Linefile()), obj->Linefile()->GetLeftLine(), obj->Linefile()->GetLeftCol(), obj->Linefile()->GetRightLine(), obj->Linefile()->GetRightCol()); #else - return stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile())); + return stringf("%s:%d", LineFile::GetFileName(obj->Linefile()), LineFile::GetLineNo(obj->Linefile())); #endif } From 1f11b2c5299781c1e935ee60e06a3a1fdbe8c376 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 13 Oct 2025 15:16:10 +0200 Subject: [PATCH 10/35] verific: Add src to message missed in #5406 --- frontends/verific/verific.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 2d0e6959e..ff8932dac 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1995,7 +1995,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma if (import_netlist_instance_cells(inst, inst_name)) continue; if (inst->IsOperator() && !verific_sva_prims.count(inst->Type())) - log_warning("Unsupported Verific operator: %s (fallback to gate level implementation provided by verific)\n", inst->View()->Owner()->Name()); + log_warning("%sUnsupported Verific operator: %s (fallback to gate level implementation provided by verific)\n", announce_src_location(inst), inst->View()->Owner()->Name()); } else { if (import_netlist_instance_gates(inst, inst_name)) continue; From 7d8f92e198e623b693c03d3c5cd9714004bfca65 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Wed, 25 Jun 2025 12:43:01 +0200 Subject: [PATCH 11/35] publish: add pass for renaming private cell types to public --- passes/cmds/Makefile.inc | 1 + passes/cmds/publish.cc | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 passes/cmds/publish.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 9bf615a7e..f4c4db2f8 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -57,3 +57,4 @@ OBJS += passes/cmds/abstract.o OBJS += passes/cmds/test_select.o OBJS += passes/cmds/timeest.o OBJS += passes/cmds/linecoverage.o +OBJS += passes/cmds/publish.o diff --git a/passes/cmds/publish.cc b/passes/cmds/publish.cc new file mode 100644 index 000000000..45a3ef5de --- /dev/null +++ b/passes/cmds/publish.cc @@ -0,0 +1,43 @@ +#include "kernel/register.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct PublishPass : public Pass { +private: + static void publish(RTLIL::IdString& id) { + if (id.begins_with("$")) { + log_debug("publishing %s\n", id.c_str()); + id = "\\" + id.str(); + log_debug("published %s\n", id.c_str()); + } + } +public: + PublishPass() : Pass("publish", "publish private cell types") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" publish\n"); + log("Makes all module names and cell types public by prefixing\n"); + log("%% with \\.\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + log_header(design, "Executing PUBLISH pass. (make cell types public)\n"); + extra_args(args, 1, design); + auto saved_modules = design->modules_; + design->modules_.clear(); + for (auto& [name, mod] : saved_modules) { + publish(mod->name); + design->modules_[mod->name] = mod; + for (auto* cell : mod->cells()) { + publish(cell->type); + } + } + } +} PublishPass; + +PRIVATE_NAMESPACE_END From d7cea2c35c61661c7f6c6fbc3e90c137e5c98251 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Wed, 25 Jun 2025 12:43:15 +0200 Subject: [PATCH 12/35] box_derive: add -apply --- passes/cmds/box_derive.cc | 37 ++++++++++++++++++++++------------ tests/various/box_derive.ys | 40 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/passes/cmds/box_derive.cc b/passes/cmds/box_derive.cc index a0faacc9a..c193e91ae 100644 --- a/passes/cmds/box_derive.cc +++ b/passes/cmds/box_derive.cc @@ -51,6 +51,9 @@ struct BoxDerivePass : Pass { log(" replaces the internal Yosys naming scheme in which the names of derived\n"); log(" modules start with '$paramod$')\n"); log("\n"); + log(" -apply\n"); + log(" use the derived modules\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *d) override { @@ -59,11 +62,14 @@ struct BoxDerivePass : Pass { size_t argidx; IdString naming_attr; IdString base_name; + bool apply_mode = false; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-naming_attr" && argidx + 1 < args.size()) naming_attr = RTLIL::escape_id(args[++argidx]); else if (args[argidx] == "-base" && argidx + 1 < args.size()) base_name = RTLIL::escape_id(args[++argidx]); + else if (args[argidx] == "-apply") + apply_mode = true; else break; } @@ -90,24 +96,29 @@ struct BoxDerivePass : Pass { auto index = std::make_pair(base->name, cell->parameters); - if (cell->parameters.empty() || done.count(index)) + if (cell->parameters.empty()) continue; - IdString derived_type = base->derive(d, cell->parameters); - Module *derived = d->module(derived_type); - log_assert(derived && "Failed to derive module\n"); - log_debug("derived %s\n", derived_type); + if (!done.count(index)) { + IdString derived_type = base->derive(d, cell->parameters); + Module *derived = d->module(derived_type); + log_assert(derived && "Failed to derive module\n"); + log("derived %s\n", derived_type); - if (!naming_attr.empty() && derived->has_attribute(naming_attr)) { - IdString new_name = RTLIL::escape_id(derived->get_string_attribute(naming_attr)); - if (!new_name.isPublic()) - log_error("Derived module %s cannot be renamed to private name %s.\n", - log_id(derived), log_id(new_name)); - derived->attributes.erase(naming_attr); - d->rename(derived, new_name); + if (!naming_attr.empty() && derived->has_attribute(naming_attr)) { + IdString new_name = RTLIL::escape_id(derived->get_string_attribute(naming_attr)); + if (!new_name.isPublic()) + log_error("Derived module %s cannot be renamed to private name %s.\n", + log_id(derived), log_id(new_name)); + derived->attributes.erase(naming_attr); + d->rename(derived, new_name); + } + + done[index] = derived; } - done[index] = derived; + if (apply_mode) + cell->type = done[index]->name; } } } diff --git a/tests/various/box_derive.ys b/tests/various/box_derive.ys index f02e13360..ef6c87193 100644 --- a/tests/various/box_derive.ys +++ b/tests/various/box_derive.ys @@ -34,6 +34,7 @@ module top; endmodule EOF +design -save before box_derive -naming_attr final_name top select -assert-mod-count 1 =aa1 @@ -48,6 +49,45 @@ select -assert-mod-count 1 =cc1 select -assert-mod-count 0 =cc2 select -assert-mod-count 0 =cc3 +# no instances of the new derived modules +# you could use wildcards like t:aa* here - if that wasn't just broken +select -assert-count 0 t:aa1 t:aa2 t:aa3 +select -assert-count 0 t:bb1 t:bb2 t:bb3 +select -assert-count 0 t:cc1 t:cc2 t:cc3 + +design -load before + +# same command but with -apply +box_derive -apply -naming_attr final_name top + +# same derived modules created as without -apply +select -assert-mod-count 1 =aa1 +select -assert-mod-count 1 =aa2 +select -assert-mod-count 0 =aa3 + +select -assert-mod-count 1 =bb1 +select -assert-mod-count 0 =bb2 +select -assert-mod-count 1 =bb3 + +select -assert-mod-count 1 =cc1 +select -assert-mod-count 0 =cc2 +select -assert-mod-count 0 =cc3 + +# but we have instances of the new derived modules +select -assert-count 1 t:aa1 +select -assert-count 1 t:aa2 +select -assert-count 0 t:aa3 + +select -assert-count 1 t:bb1 +select -assert-count 0 t:bb2 +select -assert-count 1 t:bb3 + +select -assert-count 2 t:cc1 +select -assert-count 0 t:cc2 +select -assert-count 0 t:cc3 + + + # we are expecting the original aa, bb, cc modules # and 5 specializations generated by box_derive select -assert-mod-count 8 =A:whitebox From c46df9ffdc4ad9975ee8258425cebd2ce8d51f1b Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Thu, 9 Oct 2025 01:44:13 +0200 Subject: [PATCH 13/35] box_derive: rename -apply to -apply_derived_type --- passes/cmds/box_derive.cc | 4 ++-- tests/various/box_derive.ys | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/passes/cmds/box_derive.cc b/passes/cmds/box_derive.cc index c193e91ae..2590baa93 100644 --- a/passes/cmds/box_derive.cc +++ b/passes/cmds/box_derive.cc @@ -51,7 +51,7 @@ struct BoxDerivePass : Pass { log(" replaces the internal Yosys naming scheme in which the names of derived\n"); log(" modules start with '$paramod$')\n"); log("\n"); - log(" -apply\n"); + log(" -apply_derived_type\n"); log(" use the derived modules\n"); log("\n"); } @@ -68,7 +68,7 @@ struct BoxDerivePass : Pass { naming_attr = RTLIL::escape_id(args[++argidx]); else if (args[argidx] == "-base" && argidx + 1 < args.size()) base_name = RTLIL::escape_id(args[++argidx]); - else if (args[argidx] == "-apply") + else if (args[argidx] == "-apply_derived_type") apply_mode = true; else break; diff --git a/tests/various/box_derive.ys b/tests/various/box_derive.ys index ef6c87193..465eab284 100644 --- a/tests/various/box_derive.ys +++ b/tests/various/box_derive.ys @@ -57,10 +57,10 @@ select -assert-count 0 t:cc1 t:cc2 t:cc3 design -load before -# same command but with -apply -box_derive -apply -naming_attr final_name top +# same command but with -apply_derived_type +box_derive -apply_derived_type -naming_attr final_name top -# same derived modules created as without -apply +# same derived modules created as without -apply_derived_type select -assert-mod-count 1 =aa1 select -assert-mod-count 1 =aa2 select -assert-mod-count 0 =aa3 From e5edd2acdb1e3e8d753702a8424b0bf6b09166aa Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Mon, 13 Oct 2025 17:32:26 +0200 Subject: [PATCH 14/35] sort: init --- passes/cmds/Makefile.inc | 1 + passes/cmds/sort.cc | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 passes/cmds/sort.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 9bf615a7e..2dbeadac2 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -57,3 +57,4 @@ OBJS += passes/cmds/abstract.o OBJS += passes/cmds/test_select.o OBJS += passes/cmds/timeest.o OBJS += passes/cmds/linecoverage.o +OBJS += passes/cmds/sort.o diff --git a/passes/cmds/sort.cc b/passes/cmds/sort.cc new file mode 100644 index 000000000..ab058880e --- /dev/null +++ b/passes/cmds/sort.cc @@ -0,0 +1,26 @@ +#include "kernel/yosys.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct SortPass : Pass { + SortPass() : Pass("sort", "sort the design objects") {} + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" sort\n"); + log("\n"); + log("Sorts the design objects.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *d) override + { + log_header(d, "Executing SORT pass.\n"); + if (args.size() != 1) + log_cmd_error("This pass takes no arguments.\n"); + d->sort(); + } +} SortPass; + +PRIVATE_NAMESPACE_END From 25f2a887701f91dc2fd0aa02f5a19033e48887eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 00:22:29 +0000 Subject: [PATCH 15/35] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b744763c8..8cf3fcef1 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.58+35 +YOSYS_VER := 0.58+47 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From d3d3a9f1ea3549ee250a25b7b722aee12110adbc Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 14 Oct 2025 14:47:17 +0200 Subject: [PATCH 16/35] Update ABC --- abc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abc b/abc index 8827bafb7..fa186342b 160000 --- a/abc +++ b/abc @@ -1 +1 @@ -Subproject commit 8827bafb7f288de6749dc6e30fa452f2040949c0 +Subproject commit fa186342baefea06e7c2aa13fe51f338ffc84912 From d92cf2f5b0428b6f1c5a0abebdd0bea572262c20 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 14 Oct 2025 14:54:56 +0200 Subject: [PATCH 17/35] Compile abc when submodule updates --- .gitignore | 1 + Makefile | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 47f758a9b..2367bccb3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /Brewfile.lock.json ## build artifacts +/.git-abc-submodule-hash # compiler intermediate files *.o *.d diff --git a/Makefile b/Makefile index 8cf3fcef1..976f709d1 100644 --- a/Makefile +++ b/Makefile @@ -845,7 +845,17 @@ check-git-abc: exit 1; \ fi -abc/abc$(EXE) abc/libabc.a: | check-git-abc +.git-abc-submodule-hash: FORCE + @new=$$(cd abc 2>/dev/null && git rev-parse HEAD 2>/dev/null || echo none); \ + old=$$(cat .git-abc-submodule-hash 2>/dev/null || echo none); \ + if [ "$$new" != "$$old" ]; then \ + echo "$$new" > .git-abc-submodule-hash; \ + fi + +abc/abc$(EXE) abc/libabc.a: .git-abc-submodule-hash | check-git-abc + @if [ "$$(cd abc 2>/dev/null && git rev-parse HEAD 2>/dev/null)" != "$$(cat ../.git-abc-submodule-hash 2>/dev/null || echo none)" ]; then \ + rm -f abc/abc$(EXE); \ + fi $(P) $(Q) mkdir -p abc && $(MAKE) -C $(PROGRAM_PREFIX)abc -f "$(realpath $(YOSYS_SRC)/abc/Makefile)" ABCSRC="$(realpath $(YOSYS_SRC)/abc/)" $(S) $(ABCMKARGS) $(if $(filter %.a,$@),PROG="abc",PROG="abc$(EXE)") MSG_PREFIX="$(eval P_OFFSET = 5)$(call P_SHOW)$(eval P_OFFSET = 10) ABC: " $(if $(filter %.a,$@),libabc.a) @@ -1147,7 +1157,7 @@ clean-py: clean-abc: $(MAKE) -C abc DEP= clean - rm -f $(PROGRAM_PREFIX)yosys-abc$(EXE) $(PROGRAM_PREFIX)yosys-libabc.a abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a + rm -f $(PROGRAM_PREFIX)yosys-abc$(EXE) $(PROGRAM_PREFIX)yosys-libabc.a abc/abc-[0-9a-f]* abc/libabc-[0-9a-f]*.a .git-abc-submodule-hash mrproper: clean git clean -xdf From e9aedf505c5f4260c14b699ba3ab584d43bd72f0 Mon Sep 17 00:00:00 2001 From: "Emil J. Tywoniak" Date: Thu, 9 Oct 2025 02:08:20 +0200 Subject: [PATCH 18/35] chtype: replace publish pass with chtype -publish_icells --- passes/cmds/Makefile.inc | 1 - passes/cmds/chtype.cc | 32 ++++++++++++++++++++++++ passes/cmds/publish.cc | 43 --------------------------------- tests/techmap/techmap_chtype.ys | 16 ++++++++++++ 4 files changed, 48 insertions(+), 44 deletions(-) delete mode 100644 passes/cmds/publish.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index f4c4db2f8..9bf615a7e 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -57,4 +57,3 @@ OBJS += passes/cmds/abstract.o OBJS += passes/cmds/test_select.o OBJS += passes/cmds/timeest.o OBJS += passes/cmds/linecoverage.o -OBJS += passes/cmds/publish.o diff --git a/passes/cmds/chtype.cc b/passes/cmds/chtype.cc index 6f9ca9a45..eb194f3e3 100644 --- a/passes/cmds/chtype.cc +++ b/passes/cmds/chtype.cc @@ -22,6 +22,27 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +static void publish(RTLIL::IdString& id) { + if (id.begins_with("$")) { + log_debug("publishing %s\n", id.c_str()); + id = "\\" + id.str(); + log_debug("published %s\n", id.c_str()); + } +} + +static void publish_design(RTLIL::Design* design) { + auto saved_modules = design->modules_; + design->modules_.clear(); + for (auto& [name, mod] : saved_modules) { + publish(mod->name); + design->modules_[mod->name] = mod; + for (auto* cell : mod->cells()) { + publish(cell->type); + } + } +} + + struct ChtypePass : public Pass { ChtypePass() : Pass("chtype", "change type of cells in the design") { } void help() override @@ -38,12 +59,16 @@ struct ChtypePass : public Pass { log(" -map \n"); log(" change cells types that match to \n"); log("\n"); + log(" -publish_icells\n"); + log(" change internal cells types to public types\n"); + log("\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override { IdString set_type; dict map_types; + bool publish_mode = false; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -58,10 +83,17 @@ struct ChtypePass : public Pass { map_types[old_type] = new_type; continue; } + if (args[argidx] == "-publish_icells") { + publish_mode = true; + continue; + } break; } extra_args(args, argidx, design); + if (publish_mode) + publish_design(design); + for (auto module : design->selected_modules()) { for (auto cell : module->selected_cells()) diff --git a/passes/cmds/publish.cc b/passes/cmds/publish.cc deleted file mode 100644 index 45a3ef5de..000000000 --- a/passes/cmds/publish.cc +++ /dev/null @@ -1,43 +0,0 @@ -#include "kernel/register.h" -#include "kernel/rtlil.h" -#include "kernel/log.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct PublishPass : public Pass { -private: - static void publish(RTLIL::IdString& id) { - if (id.begins_with("$")) { - log_debug("publishing %s\n", id.c_str()); - id = "\\" + id.str(); - log_debug("published %s\n", id.c_str()); - } - } -public: - PublishPass() : Pass("publish", "publish private cell types") { } - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" publish\n"); - log("Makes all module names and cell types public by prefixing\n"); - log("%% with \\.\n"); - } - void execute(std::vector args, RTLIL::Design *design) override - { - log_header(design, "Executing PUBLISH pass. (make cell types public)\n"); - extra_args(args, 1, design); - auto saved_modules = design->modules_; - design->modules_.clear(); - for (auto& [name, mod] : saved_modules) { - publish(mod->name); - design->modules_[mod->name] = mod; - for (auto* cell : mod->cells()) { - publish(cell->type); - } - } - } -} PublishPass; - -PRIVATE_NAMESPACE_END diff --git a/tests/techmap/techmap_chtype.ys b/tests/techmap/techmap_chtype.ys index 7c3398420..0c759e448 100644 --- a/tests/techmap/techmap_chtype.ys +++ b/tests/techmap/techmap_chtype.ys @@ -31,3 +31,19 @@ opt techmap -map %techmap select -assert-count 1 t:LCU_8 + +design -reset +read_verilog < Date: Tue, 14 Oct 2025 15:48:16 +0200 Subject: [PATCH 19/35] add tests --- tests/verific/ext_ramnet_err.sv | 13 +++++++++++++ tests/verific/ext_ramnet_err.ys | 5 +++++ tests/verific/import_warning_operator.vhd | 15 +++++++++++++++ tests/verific/import_warning_operator.ys | 5 +++++ 4 files changed, 38 insertions(+) create mode 100644 tests/verific/ext_ramnet_err.sv create mode 100644 tests/verific/ext_ramnet_err.ys create mode 100644 tests/verific/import_warning_operator.vhd create mode 100644 tests/verific/import_warning_operator.ys diff --git a/tests/verific/ext_ramnet_err.sv b/tests/verific/ext_ramnet_err.sv new file mode 100644 index 000000000..ba8040004 --- /dev/null +++ b/tests/verific/ext_ramnet_err.sv @@ -0,0 +1,13 @@ +module sub_rom (input clk, input [3:0] addr, output reg [7:0] data); + reg [7:0] mem [0:15]; + + always @(posedge clk) + data <= mem[addr]; +endmodule + +module top (input clk, input [3:0] addr, output [7:0] data, input [3:0] f_addr, input [7:0] f_data); + sub_rom u_sub_rom (clk, addr, data); + + always @(posedge clk) + assume(u_sub_rom.mem[f_addr] == f_data); +endmodule diff --git a/tests/verific/ext_ramnet_err.ys b/tests/verific/ext_ramnet_err.ys new file mode 100644 index 000000000..f1d45bd47 --- /dev/null +++ b/tests/verific/ext_ramnet_err.ys @@ -0,0 +1,5 @@ +logger -expect error "ext_ramnet_err.sv:\d+.\d+-\d+.\d+: Memory net '\S+' missing, possibly no driver, use verific -flatten." 1 +verific -sv ext_ramnet_err.sv +verific -import top +logger -check-expected +design -reset diff --git a/tests/verific/import_warning_operator.vhd b/tests/verific/import_warning_operator.vhd new file mode 100644 index 000000000..0b7d51788 --- /dev/null +++ b/tests/verific/import_warning_operator.vhd @@ -0,0 +1,15 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; + +entity top is + Port ( + a : in STD_LOGIC_VECTOR(3 downto 0); + b : in STD_LOGIC_VECTOR(3 downto 0); + y : out STD_LOGIC_VECTOR(3 downto 0) + ); +end top; + +architecture Behavioral of top is +begin + y <= a nor b; +end Behavioral; diff --git a/tests/verific/import_warning_operator.ys b/tests/verific/import_warning_operator.ys new file mode 100644 index 000000000..9d16e3c18 --- /dev/null +++ b/tests/verific/import_warning_operator.ys @@ -0,0 +1,5 @@ +logger -expect warning "import_warning_operator.vhd:\d+.\d+-\d+.\d+: Unsupported Verific operator: nor_4 (fallback to gate level implementation provided by verific)" 1 +verific -vhdl import_warning_operator.vhd +verific -import top +logger -check-expected +design -reset From 7d2857b30fdbaa3713f080ceb9218529faf7c5b3 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 14 Oct 2025 16:04:56 +0200 Subject: [PATCH 20/35] Fix regex checks --- tests/verific/ext_ramnet_err.ys | 2 +- tests/verific/import_warning_operator.ys | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/verific/ext_ramnet_err.ys b/tests/verific/ext_ramnet_err.ys index f1d45bd47..7456af444 100644 --- a/tests/verific/ext_ramnet_err.ys +++ b/tests/verific/ext_ramnet_err.ys @@ -1,4 +1,4 @@ -logger -expect error "ext_ramnet_err.sv:\d+.\d+-\d+.\d+: Memory net '\S+' missing, possibly no driver, use verific -flatten." 1 +logger -expect error "ext_ramnet_err.sv:[0-9]+\.[0-9]+-[0-9]+\.[0-9]+: Memory net '[^']+' missing, possibly no driver, use verific -flatten." 1 verific -sv ext_ramnet_err.sv verific -import top logger -check-expected diff --git a/tests/verific/import_warning_operator.ys b/tests/verific/import_warning_operator.ys index 9d16e3c18..1ecd6d296 100644 --- a/tests/verific/import_warning_operator.ys +++ b/tests/verific/import_warning_operator.ys @@ -1,4 +1,4 @@ -logger -expect warning "import_warning_operator.vhd:\d+.\d+-\d+.\d+: Unsupported Verific operator: nor_4 (fallback to gate level implementation provided by verific)" 1 +logger -expect warning "import_warning_operator.vhd:[0-9]+.[0-9]+-[0-9]+.[0-9]+: Unsupported Verific operator: nor_4 \(fallback to gate level implementation provided by verific\)" 1 verific -vhdl import_warning_operator.vhd verific -import top logger -check-expected From e099a7d34a93397c4d41dad5ad8328c38bd37ec5 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Tue, 14 Oct 2025 21:18:58 +0000 Subject: [PATCH 21/35] Don't stop parsing sigspec after a {} group. Resolves #5424 --- frontends/rtlil/rtlil_frontend.cc | 30 ++++++++++++++---------------- tests/rtlil/bug5424.ys | 12 ++++++++++++ tests/rtlil/run-test.sh | 2 +- 3 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 tests/rtlil/bug5424.ys diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index b54cd8f14..04d01fc93 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -324,29 +324,27 @@ struct RTLILFrontendWorker { RTLIL::SigSpec parse_sigspec() { + RTLIL::SigSpec sig; + if (try_parse_char('{')) { std::vector parts; while (!try_parse_char('}')) parts.push_back(parse_sigspec()); - RTLIL::SigSpec sig; for (auto it = parts.rbegin(); it != parts.rend(); ++it) sig.append(std::move(*it)); - return sig; - } - - RTLIL::SigSpec sig; - - // We could add a special path for parsing IdStrings that must already exist, - // as here. - // We don't need to addref/release in this case. - std::optional id = try_parse_id(); - if (id.has_value()) { - RTLIL::Wire *wire = current_module->wire(*id); - if (wire == nullptr) - error("Wire `%s' not found.", *id); - sig = RTLIL::SigSpec(wire); } else { - sig = RTLIL::SigSpec(parse_const()); + // We could add a special path for parsing IdStrings that must already exist, + // as here. + // We don't need to addref/release in this case. + std::optional id = try_parse_id(); + if (id.has_value()) { + RTLIL::Wire *wire = current_module->wire(*id); + if (wire == nullptr) + error("Wire `%s' not found.", *id); + sig = RTLIL::SigSpec(wire); + } else { + sig = RTLIL::SigSpec(parse_const()); + } } while (try_parse_char('[')) { diff --git a/tests/rtlil/bug5424.ys b/tests/rtlil/bug5424.ys new file mode 100644 index 000000000..a0b0638e5 --- /dev/null +++ b/tests/rtlil/bug5424.ys @@ -0,0 +1,12 @@ +read_rtlil < Date: Wed, 15 Oct 2025 00:23:49 +0000 Subject: [PATCH 22/35] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 976f709d1..d62575f1a 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.58+47 +YOSYS_VER := 0.58+63 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From e86797f0297ef75826cebdd0e6f4cc51b7c77e0a Mon Sep 17 00:00:00 2001 From: Mohamed Gaber Date: Wed, 15 Oct 2025 14:13:25 +0300 Subject: [PATCH 23/35] plugins: add search path This uses the environment variable `YOSYS_PLUGIN_PATH` to provide multiple colon-delimited search paths for native plugins in a similar manner to `PATH` for executables and `PYTHONPATH` for Python modules. This addresses https://github.com/YosysHQ/yosys/issues/2545, allowing Yosys to be better packaged in non-FHS environments such as Nix. --- passes/cmds/plugin.cc | 61 +++++++++++++++++++++++++++------------- tests/various/.gitignore | 1 + tests/various/plugin.sh | 4 +++ 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index 191261a17..329aa4cee 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -22,6 +22,8 @@ #ifdef YOSYS_ENABLE_PLUGINS # include +# include +namespace fs = std::filesystem; #endif #ifdef YOSYS_ENABLE_PYTHON @@ -39,6 +41,23 @@ std::map loaded_python_plugins; std::map loaded_plugin_aliases; #ifdef YOSYS_ENABLE_PLUGINS +inline const std::vector get_plugin_search_paths() { + std::vector result; + const char *yosys_plugin_path = std::getenv("YOSYS_PLUGIN_PATH"); + if (yosys_plugin_path != nullptr && strlen(yosys_plugin_path)) { + // make mutable. std::string also manages allocation as a bonus + // guaranteed contiguous in c++>=11 + std::string copy{yosys_plugin_path}; + char *token = nullptr; + char *rest = ©[0]; + while ((token = strtok_r(rest, ":", &rest))) { + result.push_back(fs::path(token)); + } + } + result.push_back(fs::path(proc_share_dirname()) / "plugins"); // lowest priority + return result; +} + void load_plugin(std::string filename, std::vector aliases) { std::string orig_filename = filename; @@ -55,17 +74,17 @@ void load_plugin(std::string filename, std::vector aliases) const bool is_loaded = loaded_plugins.count(orig_filename); #endif + fs::path full_path = fs::absolute(filename); + if (!is_loaded) { // Check if we're loading a python script - if (filename.rfind(".py") != std::string::npos) { + if (full_path.extension() == ".py") { #ifdef YOSYS_ENABLE_PYTHON - py::object Path = py::module_::import("pathlib").attr("Path"); - py::object full_path = Path(py::cast(filename)); - py::object plugin_python_path = full_path.attr("parent"); - auto basename = py::cast(full_path.attr("stem")); + fs::path plugin_python_path = full_path.parent_path(); + fs::path basename = full_path.stem(); py::object sys = py::module_::import("sys"); - sys.attr("path").attr("insert")(0, py::str(plugin_python_path)); + sys.attr("path").attr("insert")(0, py::str(plugin_python_path.c_str())); try { auto module_container = py::module_::import(basename.c_str()); @@ -83,23 +102,25 @@ void load_plugin(std::string filename, std::vector aliases) #endif } else { // Otherwise we assume it's a native plugin - void *hdl = dlopen(filename.c_str(), RTLD_LAZY|RTLD_LOCAL); - // We were unable to open the file, try to do so from the plugin directory - if (hdl == NULL && orig_filename.find('/') == std::string::npos) { - hdl = dlopen([orig_filename]() { - std::string new_path = proc_share_dirname() + "plugins/" + orig_filename; - - // Check if we need to append .so - if (new_path.find(".so") == std::string::npos) - new_path.append(".so"); - - return new_path; - }().c_str(), RTLD_LAZY|RTLD_LOCAL); + // We were unable to open the file, try to do so from plugin search + // paths + if (hdl == nullptr && orig_filename.find('/') == std::string::npos) { + const std::vector search_paths = get_plugin_search_paths(); + for (const auto &search_path: search_paths) { + fs::path potential_path = search_path / orig_filename; + if (potential_path.extension() != ".so") { + potential_path = search_path / (orig_filename + ".so"); + } + hdl = dlopen(potential_path.c_str(), RTLD_LAZY | RTLD_LOCAL); + if (hdl != nullptr) { + break; + } + } } - if (hdl == NULL) + if (hdl == nullptr) log_cmd_error("Can't load module `%s': %s\n", filename, dlerror()); loaded_plugins[orig_filename] = hdl; @@ -116,7 +137,7 @@ void load_plugin(std::string, std::vector) log_error( "\n This version of Yosys cannot load plugins at runtime.\n" " Some plugins may have been included at build time.\n" - " Use option `-H' to see the available built-in and plugin commands.\n" + " Use `yosys -H' to see the available built-in and plugin commands.\n" ); } #endif diff --git a/tests/various/.gitignore b/tests/various/.gitignore index 879645f66..e116179ae 100644 --- a/tests/various/.gitignore +++ b/tests/various/.gitignore @@ -2,6 +2,7 @@ /write_gzip.v /write_gzip.v.gz /plugin.so +/plugin_search /plugin.so.dSYM /temp /smtlib2_module.smt2 diff --git a/tests/various/plugin.sh b/tests/various/plugin.sh index 2880c8c06..75b4c9e56 100644 --- a/tests/various/plugin.sh +++ b/tests/various/plugin.sh @@ -1,8 +1,12 @@ set -e rm -f plugin.so +rm -rf plugin_search CXXFLAGS=$(../../yosys-config --cxxflags) DATDIR=$(../../yosys-config --datdir) DATDIR=${DATDIR//\//\\\/} CXXFLAGS=${CXXFLAGS//$DATDIR/..\/..\/share} ../../yosys-config --exec --cxx ${CXXFLAGS} --ldflags -shared -o plugin.so plugin.cc ../../yosys -m ./plugin.so -p "test" | grep -q "Plugin test passed!" +mkdir -p plugin_search +mv plugin.so plugin_search/plugin.so +YOSYS_PLUGIN_PATH=$PWD/plugin_search ../../yosys -m plugin.so -p "test" | grep -q "Plugin test passed!" From dce70abd94caaa81eeb4c9bf97548db8517fb193 Mon Sep 17 00:00:00 2001 From: Mohamed Gaber Date: Wed, 15 Oct 2025 15:53:44 +0300 Subject: [PATCH 24/35] plugins: support Windows path delimiters --- passes/cmds/plugin.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index 329aa4cee..4ccd8e5d4 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -41,6 +41,9 @@ std::map loaded_python_plugins; std::map loaded_plugin_aliases; #ifdef YOSYS_ENABLE_PLUGINS + +static constexpr const char *path_delimiters = fs::path::preferred_separator == '\\' ? ";" : ":" ; + inline const std::vector get_plugin_search_paths() { std::vector result; const char *yosys_plugin_path = std::getenv("YOSYS_PLUGIN_PATH"); @@ -50,7 +53,7 @@ inline const std::vector get_plugin_search_paths() { std::string copy{yosys_plugin_path}; char *token = nullptr; char *rest = ©[0]; - while ((token = strtok_r(rest, ":", &rest))) { + while ((token = strtok_r(rest, path_delimiters, &rest))) { result.push_back(fs::path(token)); } } From 061b6ce2adbce47cb1db4eef55169fd64977bbbb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 16 Oct 2025 00:23:57 +0000 Subject: [PATCH 25/35] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d62575f1a..934bd6586 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.58+63 +YOSYS_VER := 0.58+69 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From db8c1878a0df1eaafaef698469bb91ac4118f285 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 16 Oct 2025 08:30:43 +0200 Subject: [PATCH 26/35] fix dlopen using fs:path with mingw --- passes/cmds/plugin.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index 4ccd8e5d4..dec53cf37 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -116,7 +116,7 @@ void load_plugin(std::string filename, std::vector aliases) if (potential_path.extension() != ".so") { potential_path = search_path / (orig_filename + ".so"); } - hdl = dlopen(potential_path.c_str(), RTLD_LAZY | RTLD_LOCAL); + hdl = dlopen(potential_path.string().c_str(), RTLD_LAZY | RTLD_LOCAL); if (hdl != nullptr) { break; } From f11a61b32b669248dc8e8535135672ccb8249532 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 16 Oct 2025 11:37:44 +0200 Subject: [PATCH 27/35] sim: Make cycle width small as possible and configurable --- passes/sat/sim.cc | 56 ++++++++++++++++++++++++----------------- tests/sim/sim_cycles.ys | 14 +++++------ 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index fac7bd744..8f0886a4e 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -1392,7 +1392,7 @@ struct SimWorker : SimShared } } - void run(Module *topmod, int numcycles) + void run(Module *topmod, int cycle_width, int numcycles) { log_assert(top == nullptr); top = new SimInstance(this, scope, topmod); @@ -1418,20 +1418,20 @@ struct SimWorker : SimShared for (int cycle = 0; cycle < numcycles; cycle++) { if (debug) - log("\n===== %d =====\n", 10*cycle + 5); + log("\n===== %d =====\n", int(cycle_width*cycle + cycle_width/2)); else if (verbose) log("Simulating cycle %d.\n", (cycle*2)+1); set_inports(clock, State::S0); set_inports(clockn, State::S1); update(true); - register_output_step(10*cycle + 5); + register_output_step(cycle_width*cycle + cycle_width/2); if (cycle == 0) top->set_initstate_outputs(State::S0); if (debug) - log("\n===== %d =====\n", 10*cycle + 10); + log("\n===== %d =====\n", int(cycle_width*cycle + cycle_width)); else if (verbose) log("Simulating cycle %d.\n", (cycle*2)+2); @@ -1444,10 +1444,10 @@ struct SimWorker : SimShared } update(true); - register_output_step(10*cycle + 10); + register_output_step(cycle_width*cycle + cycle_width); } - register_output_step(10*numcycles + 2); + register_output_step(cycle_width*numcycles + 2); write_output_files(); } @@ -1582,7 +1582,7 @@ struct SimWorker : SimShared return atoi(name.substr(pos+1).c_str()); } - void run_cosim_aiger_witness(Module *topmod) + void run_cosim_aiger_witness(Module *topmod, int cycle_width) { log_assert(top == nullptr); if (!multiclock && (clock.size()+clockn.size())==0) @@ -1691,18 +1691,18 @@ struct SimWorker : SimShared set_inports(clockn, State::S1); } update(true); - register_output_step(10*cycle); + register_output_step(cycle_width*cycle); if (!multiclock && cycle) { set_inports(clock, State::S0); set_inports(clockn, State::S1); update(true); - register_output_step(10*cycle + 5); + register_output_step(cycle_width*cycle + cycle_width/2); } cycle++; break; } } - register_output_step(10*cycle); + register_output_step(cycle_width*cycle); write_output_files(); } @@ -1730,7 +1730,7 @@ struct SimWorker : SimShared return name.substr(0, pos); } - void run_cosim_btor2_witness(Module *topmod) + void run_cosim_btor2_witness(Module *topmod, int cycle_width) { log_assert(top == nullptr); if (!multiclock && (clock.size()+clockn.size())==0) @@ -1768,12 +1768,12 @@ struct SimWorker : SimShared set_inports(clock, State::S1); set_inports(clockn, State::S0); update(true); - register_output_step(10*cycle+0); + register_output_step(cycle_width*cycle + 0); if (!multiclock) { set_inports(clock, State::S0); set_inports(clockn, State::S1); update(true); - register_output_step(10*cycle+5); + register_output_step(cycle_width*cycle + cycle_width/2); } cycle++; prev_cycle = curr_cycle; @@ -1832,7 +1832,7 @@ struct SimWorker : SimShared break; } } - register_output_step(10*cycle); + register_output_step(cycle_width*cycle); write_output_files(); } @@ -1983,7 +1983,7 @@ struct SimWorker : SimShared } } - void run_cosim_yw_witness(Module *topmod, int append) + void run_cosim_yw_witness(Module *topmod, int cycle_width, int append) { if (!clock.empty()) log_cmd_error("The -clock option is not required nor supported when reading a Yosys witness file.\n"); @@ -2013,7 +2013,7 @@ struct SimWorker : SimShared log("Simulating non-active clock edge.\n"); set_yw_clocks(yw, hierarchy, false); update(false); - register_output_step(5); + register_output_step(cycle_width/2); } top->set_initstate_outputs(State::S0); } @@ -2026,18 +2026,18 @@ struct SimWorker : SimShared set_yw_state(yw, hierarchy, cycle); set_yw_clocks(yw, hierarchy, true); update(true); - register_output_step(10 * cycle); + register_output_step(cycle_width*cycle); if (!yw.clocks.empty()) { if (debug) log("Simulating non-active clock edge.\n"); set_yw_clocks(yw, hierarchy, false); update(false); - register_output_step(5 + 10 * cycle); + register_output_step(cycle_width*cycle + cycle_width/2); } } - register_output_step(10 * (GetSize(yw.steps) + append)); + register_output_step(cycle_width * (GetSize(yw.steps) + append)); write_output_files(); } @@ -2630,6 +2630,9 @@ struct SimPass : public Pass { log(" File formats supported: FST, VCD, AIW, WIT and .yw\n"); log(" VCD support requires vcd2fst external tool to be present\n"); log("\n"); + log(" -width \n"); + log(" cycle width in generated simulation output (must be divisible by 2).\n"); + log("\n"); log(" -append \n"); log(" number of extra clock cycles to simulate for a Yosys witness input\n"); log("\n"); @@ -2689,6 +2692,7 @@ struct SimPass : public Pass { { SimWorker worker; int numcycles = 20; + int cycle_width = 2; int append = 0; bool start_set = false, stop_set = false, at_set = false; @@ -2781,6 +2785,12 @@ struct SimPass : public Pass { append = atoi(args[++argidx].c_str()); continue; } + if (args[argidx] == "-width" && argidx+1 < args.size()) { + cycle_width = atoi(args[++argidx].c_str()); + if (cycle_width <= 0 || (cycle_width % 2)) + log_cmd_error("Cycle width must be positive even number.\n"); + continue; + } if (args[argidx] == "-map" && argidx+1 < args.size()) { std::string map_filename = args[++argidx]; rewrite_filename(map_filename); @@ -2872,7 +2882,7 @@ struct SimPass : public Pass { } if (worker.sim_filename.empty()) - worker.run(top_mod, numcycles); + worker.run(top_mod, cycle_width, numcycles); else { std::string filename_trim = file_base_name(worker.sim_filename); if (filename_trim.size() > 4 && ((filename_trim.compare(filename_trim.size()-4, std::string::npos, ".fst") == 0) || @@ -2881,11 +2891,11 @@ struct SimPass : public Pass { } else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".aiw") == 0) { if (worker.map_filename.empty()) log_cmd_error("For AIGER witness file map parameter is mandatory.\n"); - worker.run_cosim_aiger_witness(top_mod); + worker.run_cosim_aiger_witness(top_mod, cycle_width); } else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".wit") == 0) { - worker.run_cosim_btor2_witness(top_mod); + worker.run_cosim_btor2_witness(top_mod, cycle_width); } else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".yw") == 0) { - worker.run_cosim_yw_witness(top_mod, append); + worker.run_cosim_yw_witness(top_mod, cycle_width, append); } else { log_cmd_error("Unhandled extension for simulation input file `%s`.\n", worker.sim_filename); } diff --git a/tests/sim/sim_cycles.ys b/tests/sim/sim_cycles.ys index 7c6c943d9..0a13d9301 100644 --- a/tests/sim/sim_cycles.ys +++ b/tests/sim/sim_cycles.ys @@ -10,7 +10,7 @@ logger -expect-no-warnings logger -expect log "Co-simulating cycle 41" 2 logger -warn "Co-simulating cycle 42" sim -clock clk -r sim_cycles.fst -scope dff -n 21 -sim-cmp -sim -clock clk -r sim_cycles.fst -scope dff -stop 202 -sim-cmp +sim -clock clk -r sim_cycles.fst -scope dff -stop 41 -sim-cmp logger -check-expected # over limit stops at final step @@ -18,29 +18,29 @@ logger -expect log "Co-simulating cycle 41" 2 sim -clock clk -r sim_cycles.fst -scope dff -n 30 -sim-cmp # -stop warns for over limit logger -nowarn "Stop time is after simulation file end time" -sim -clock clk -r sim_cycles.fst -scope dff -stop 300 -sim-cmp +sim -clock clk -r sim_cycles.fst -scope dff -stop 50 -sim-cmp logger -check-expected # don't auto step last logger -expect log "Co-simulating cycle 40" 2 logger -warn "Co-simulating cycle 41" sim -clock clk -r sim_cycles.fst -scope dff -n 20 -sim-cmp -sim -clock clk -r sim_cycles.fst -scope dff -stop 200 -sim-cmp +sim -clock clk -r sim_cycles.fst -scope dff -stop 40 -sim-cmp logger -check-expected -# -n 10 == -stop 100 +# -n 10 == -stop 20 # should simulate up to 20 and not more logger -expect log "Co-simulating cycle 20" 2 logger -warn "Co-simulating cycle 21" sim -clock clk -r sim_cycles.fst -scope dff -n 10 -sim-cmp -sim -clock clk -r sim_cycles.fst -scope dff -stop 100 -sim-cmp +sim -clock clk -r sim_cycles.fst -scope dff -stop 20 -sim-cmp logger -check-expected -# -n 1 == -stop 10 +# -n 1 == -stop 2 logger -expect log "Co-simulating cycle 2" 2 logger -warn "Co-simulating cycle 3" sim -clock clk -r sim_cycles.fst -scope dff -n 1 -sim-cmp -sim -clock clk -r sim_cycles.fst -scope dff -stop 10 -sim-cmp +sim -clock clk -r sim_cycles.fst -scope dff -stop 2 -sim-cmp logger -check-expected # -n 0 == -stop 0 From 8f6d63c0823cd8b64fd30f7892735f00e12f7467 Mon Sep 17 00:00:00 2001 From: Maxim Kudinov Date: Thu, 16 Oct 2025 10:32:39 +0300 Subject: [PATCH 28/35] synth_gowin: make setundef an off by default option --- techlibs/gowin/synth_gowin.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 03766ed36..f1669d8f8 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -94,13 +94,16 @@ struct SynthGowinPass : public ScriptPass log(" The following families are supported:\n"); log(" 'gw1n', 'gw2a', 'gw5a'.\n"); log("\n"); + log(" -setundef\n"); + log(" run 'setundef' with '-undriven -params -zero' options\n"); + log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); log("\n"); } string top_opt, vout_file, json_file, family; - bool retime, nobram, nolutram, flatten, nodffe, strict_gw5a_dffs, nowidelut, abc9, noiopads, noalu, no_rw_check; + bool retime, nobram, nolutram, flatten, nodffe, strict_gw5a_dffs, nowidelut, abc9, noiopads, noalu, no_rw_check, setundef; void clear_flags() override { @@ -119,6 +122,7 @@ struct SynthGowinPass : public ScriptPass noiopads = false; noalu = false; no_rw_check = false; + setundef = false; } void execute(std::vector args, RTLIL::Design *design) override @@ -201,6 +205,10 @@ struct SynthGowinPass : public ScriptPass no_rw_check = true; continue; } + if (args[argidx] == "-setundef") { + setundef = true; + continue; + } break; } extra_args(args, argidx, design); @@ -321,7 +329,8 @@ struct SynthGowinPass : public ScriptPass { run("techmap -map +/gowin/cells_map.v"); run("opt_lut_ins -tech gowin"); - run("setundef -undriven -params -zero"); + if (setundef || help_mode) + run("setundef -undriven -params -zero", "(only if -setundef used)"); run("hilomap -singleton -hicell VCC V -locell GND G"); if (!vout_file.empty() || help_mode) // vendor output requires 1-bit wires run("splitnets -ports", "(only if -vout used)"); From 8c347826f68586187c426d059ae4ce4a335ad037 Mon Sep 17 00:00:00 2001 From: Maxim Kudinov Date: Thu, 16 Oct 2025 11:06:02 +0300 Subject: [PATCH 29/35] synth_gowin: make help description more clear --- techlibs/gowin/synth_gowin.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index f1669d8f8..5585c0ddb 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -95,7 +95,7 @@ struct SynthGowinPass : public ScriptPass log(" 'gw1n', 'gw2a', 'gw5a'.\n"); log("\n"); log(" -setundef\n"); - log(" run 'setundef' with '-undriven -params -zero' options\n"); + log(" set undriven wires and parameters to zero\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); From 653599500532fb7285bb0ce6d63369f7eb4dc079 Mon Sep 17 00:00:00 2001 From: Maxim Kudinov Date: Thu, 16 Oct 2025 11:08:27 +0300 Subject: [PATCH 30/35] synth_gowin: fix help hint style --- techlibs/gowin/synth_gowin.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 5585c0ddb..1a55f9f37 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -330,10 +330,10 @@ struct SynthGowinPass : public ScriptPass run("techmap -map +/gowin/cells_map.v"); run("opt_lut_ins -tech gowin"); if (setundef || help_mode) - run("setundef -undriven -params -zero", "(only if -setundef used)"); + run("setundef -undriven -params -zero", "(only if -setundef)"); run("hilomap -singleton -hicell VCC V -locell GND G"); if (!vout_file.empty() || help_mode) // vendor output requires 1-bit wires - run("splitnets -ports", "(only if -vout used)"); + run("splitnets -ports", "(only if -vout)"); run("clean"); run("autoname"); } From 272aa9cde2cbb943e44a6e5c195b7bc231d51f92 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 17 Oct 2025 00:23:40 +0000 Subject: [PATCH 31/35] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 934bd6586..f2784bfd8 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.58+69 +YOSYS_VER := 0.58+74 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From b510c361621d80c63f3016d4af424a8a800393a6 Mon Sep 17 00:00:00 2001 From: Mohamed Gaber Date: Sat, 18 Oct 2025 15:59:17 +0300 Subject: [PATCH 32/35] hotfix: headers mistakenly added to clean target - fix `make clean` deleting a number of headers when ENABLE_PYOSYS is set to 1 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f2784bfd8..9252e1e7a 100644 --- a/Makefile +++ b/Makefile @@ -1131,7 +1131,7 @@ docs: docs/prep clean: clean-py rm -rf share - rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) $(PY_WRAP_INCLUDES) + rm -f $(OBJS) $(GENFILES) $(TARGETS) $(EXTRA_TARGETS) $(EXTRA_OBJS) rm -f kernel/version_*.o kernel/version_*.cc rm -f libs/*/*.d frontends/*/*.d passes/*/*.d backends/*/*.d kernel/*.d techlibs/*/*.d rm -rf tests/asicworld/*.out tests/asicworld/*.log From 1598771a370d5636624c7bf0029c484880c361b0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 19 Oct 2025 00:26:17 +0000 Subject: [PATCH 33/35] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9252e1e7a..ed0428ef4 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.58+74 +YOSYS_VER := 0.58+76 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2) From 6a0ee6e4fb740840326d163599b6cad38933d26e Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Mon, 20 Oct 2025 14:40:05 +0200 Subject: [PATCH 34/35] Revert sim's cycle_width default back to 10, but keep -width option --- passes/sat/sim.cc | 2 +- tests/sim/sim_cycles.ys | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 8f0886a4e..a29651653 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -2692,7 +2692,7 @@ struct SimPass : public Pass { { SimWorker worker; int numcycles = 20; - int cycle_width = 2; + int cycle_width = 10; int append = 0; bool start_set = false, stop_set = false, at_set = false; diff --git a/tests/sim/sim_cycles.ys b/tests/sim/sim_cycles.ys index 0a13d9301..732b1fb81 100644 --- a/tests/sim/sim_cycles.ys +++ b/tests/sim/sim_cycles.ys @@ -2,7 +2,7 @@ read_verilog dff.v prep # create fst with 20 clock cycles (41 samples, 202ns) -sim -clock clk -fst sim_cycles.fst -n 20 +sim -clock clk -fst sim_cycles.fst -width 2 -n 20 logger -expect-no-warnings From 37875fdedfeb6a72d2fe830618346e5c695cfe74 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 Oct 2025 00:23:46 +0000 Subject: [PATCH 35/35] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ed0428ef4..d17fe3a9a 100644 --- a/Makefile +++ b/Makefile @@ -160,7 +160,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.58+76 +YOSYS_VER := 0.58+80 YOSYS_MAJOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f1) YOSYS_MINOR := $(shell echo $(YOSYS_VER) | cut -d'.' -f2 | cut -d'+' -f1) YOSYS_COMMIT := $(shell echo $(YOSYS_VER) | cut -d'+' -f2)