Skip to content

Commit 446f5be

Browse files
committed
[Odin]: add -S/--tcl option to run Yosys in Odin-II
Signed-off-by: Seyed Alireza Damghani <[email protected]>
1 parent 34b994f commit 446f5be

File tree

6 files changed

+92
-63
lines changed

6 files changed

+92
-63
lines changed

ODIN_II/SRC/YYosys.cpp

Lines changed: 56 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ YYosys::YYosys() {
7575
/* create Yosys child process */
7676
if ((this->yosys_pid = fork()) < 0)
7777
error_message(UTIL, unknown_location, "%s", YOSYS_FORK_ERROR);
78+
else {
79+
/* set up VTR_ROOT path environment variable */
80+
set_env("VTR_ROOT", std::string(global_args.program_root + "/..").c_str(), 1);
81+
}
82+
7883
#endif
7984
}
8085

@@ -205,52 +210,57 @@ void YYosys::execute() {
205210
/* must only be performed in the Yosys child process */
206211
oassert(this->yosys_pid == 0);
207212

208-
// Read the hardware decription Verilog circuits
209-
// FOR loop enables include feature for Yosys+Odin (multiple Verilog input files)
210-
for (auto verilog_circuit : this->verilog_circuits)
211-
run_pass(std::string("read_verilog -nomem2reg -nolatches " + verilog_circuit));
212-
213-
// Check whether cells match libraries and find top module
214-
run_pass(std::string("hierarchy -check -auto-top"));
215-
216-
// Use a readable name convention
217-
run_pass(std::string("autoname"));
218-
// Translate processes to netlist components such as MUXs, FFs and latches
219-
run_pass(std::string("proc; opt;"));
220-
// Extraction and optimization of finite state machines
221-
run_pass(std::string("fsm; opt;"));
222-
// Collects memories, their port and create multiport memory cells
223-
run_pass(std::string("memory_collect; memory_dff; opt;"));
224-
225-
// Looking for combinatorial loops, wires with multiple drivers and used wires without any driver.
226-
run_pass(std::string("check"));
227-
// Transform asynchronous dffs to synchronous dffs using techlib files provided by Yosys
228-
run_pass(std::string("techmap -map " + this->odin_techlib + "/adff2dff.v"));
229-
run_pass(std::string("techmap -map " + this->odin_techlib + "/adffe2dff.v"));
230-
231-
/**
232-
* convert yosys mem blocks to BRAMs / ROMs
233-
*
234-
* [NOTE] : Yosys complains about expression width more than 24 bits.
235-
* E.g.[63 : 0] memory[18 : 0] == > ERROR : Expression width 33554432 exceeds implementation limit of 16777216 !
236-
* Therfore, Yosys internal memory cells will be handled inside Odin-II as YMEM cell type.
237-
*
238-
* The following commands transform Yosys internal memories into BRAMs/ROMs defined in the Odin-II techlib
239-
* However, due to the above-mentioned reason they are commented.
240-
* Yosys::run_pass(std::string("memory_bram -rules ", this->odin_techlib, "/mem_rules.txt"))
241-
* Yosys::run_pass(std::string("techmap -map ", this->odin_techlib, "/mem_map.v"));
242-
*/
243-
244-
// Transform the design into a new one with single top module
245-
run_pass(std::string("flatten"));
246-
// Transforms PMUXes into trees of regular multiplexers
247-
run_pass(std::string("pmuxtree"));
248-
// "-undirven" to ensure there is no wire without drive
249-
run_pass(std::string("opt -undriven -full")); // -noff #potential option to remove all sdffXX and etc. Only dff will remain
250-
// Use a readable name convention
251-
run_pass(std::string("autoname"));
252-
// Print statistics
253-
run_pass(std::string("stat"));
213+
if (configuration.tcl_file != "") {
214+
// run the tcl file by yosys
215+
run_pass(std::string("tcl " + configuration.tcl_file));
216+
} else {
217+
// Read the hardware decription Verilog circuits
218+
// FOR loop enables include feature for Yosys+Odin (multiple Verilog input files)
219+
for (auto verilog_circuit : this->verilog_circuits)
220+
run_pass(std::string("read_verilog -nomem2reg -nolatches " + verilog_circuit));
221+
222+
// Check whether cells match libraries and find top module
223+
run_pass(std::string("hierarchy -check -auto-top"));
224+
225+
// Use a readable name convention
226+
run_pass(std::string("autoname"));
227+
// Translate processes to netlist components such as MUXs, FFs and latches
228+
run_pass(std::string("proc; opt;"));
229+
// Extraction and optimization of finite state machines
230+
run_pass(std::string("fsm; opt;"));
231+
// Collects memories, their port and create multiport memory cells
232+
run_pass(std::string("memory_collect; memory_dff; opt;"));
233+
234+
// Looking for combinatorial loops, wires with multiple drivers and used wires without any driver.
235+
run_pass(std::string("check"));
236+
// Transform asynchronous dffs to synchronous dffs using techlib files provided by Yosys
237+
run_pass(std::string("techmap -map " + this->odin_techlib + "/adff2dff.v"));
238+
run_pass(std::string("techmap -map " + this->odin_techlib + "/adffe2dff.v"));
239+
240+
/**
241+
* convert yosys mem blocks to BRAMs / ROMs
242+
*
243+
* [NOTE] : Yosys complains about expression width more than 24 bits.
244+
* E.g.[63 : 0] memory[18 : 0] == > ERROR : Expression width 33554432 exceeds implementation limit of 16777216 !
245+
* Therfore, Yosys internal memory cells will be handled inside Odin-II as YMEM cell type.
246+
*
247+
* The following commands transform Yosys internal memories into BRAMs/ROMs defined in the Odin-II techlib
248+
* However, due to the above-mentioned reason they are commented.
249+
* Yosys::run_pass(std::string("memory_bram -rules ", this->odin_techlib, "/mem_rules.txt"))
250+
* Yosys::run_pass(std::string("techmap -map ", this->odin_techlib, "/mem_map.v"));
251+
*/
252+
253+
// Transform the design into a new one with single top module
254+
run_pass(std::string("flatten"));
255+
// Transforms PMUXes into trees of regular multiplexers
256+
run_pass(std::string("pmuxtree"));
257+
// "-undirven" to ensure there is no wire without drive
258+
run_pass(std::string("opt -undriven -full")); // -noff #potential option to remove all sdffXX and etc. Only dff will remain
259+
// Use a readable name convention
260+
run_pass(std::string("autoname"));
261+
// Print statistics
262+
run_pass(std::string("stat"));
263+
}
254264

255265
#endif
256266
}

ODIN_II/SRC/include/YYosys.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@
4444

4545
#include "odin_globals.h" // global_args
4646

47+
/* to set local environment variable */
48+
#ifdef WIN32
49+
# define set_env _setenv
50+
#else
51+
# define set_env setenv
52+
#endif
53+
4754
/**
4855
* @brief A class to provide the general object of Yosys synthezier
4956
*/

ODIN_II/SRC/include/config_t.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct config_t {
5252
int soft_logic_memory_width_threshold;
5353

5454
std::string arch_file; // Name of the FPGA architecture file
55+
std::string tcl_file; // TCL file to be run by yosys
5556
};
5657

5758
extern config_t configuration;

ODIN_II/SRC/include/odin_types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ struct global_args_t {
9696
argparse::ArgValue<std::string> blif_file;
9797
argparse::ArgValue<std::string> output_file;
9898
argparse::ArgValue<std::string> arch_file; // Name of the FPGA architecture file
99+
argparse::ArgValue<std::string> tcl_file; // TCL file to be run by yosys elaborator
99100
argparse::ArgValue<std::string> elaborator; // Name of the external elaborator tool, currently Yosys is supported, default is Odin
100-
argparse::ArgValue<bool> permissive; //turn possible_errors into warnings
101+
argparse::ArgValue<bool> permissive; // turn possible_errors into warnings
101102
argparse::ArgValue<bool> print_parse_tokens; // print the tokens as they are parsed byt the parser
102103

103104
argparse::ArgValue<std::string> high_level_block; //Legacy option, no longer used

ODIN_II/SRC/odin_ii.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ netlist_t* start_odin_ii(int argc, char** argv) {
344344
printf("Using Lut input width of: %d\n", physical_lut_size);
345345

346346
/* do High level Synthesis */
347-
if (!configuration.list_of_file_names.empty()) {
347+
if (!configuration.list_of_file_names.empty() || !configuration.tcl_file.empty()) {
348348
ODIN_ERROR_CODE error_code;
349349

350350
print_input_files_info();
@@ -481,7 +481,7 @@ void get_options(int argc, char** argv) {
481481
get_current_path();
482482
// get Odin-II program name
483483
global_args.program_name = parser.prog();
484-
// getting Odin-II path and program name
484+
// getting Odin-II path
485485
global_args.program_root = get_directory(std::string(argv[0]));
486486

487487
auto& input_grp = parser.add_argument_group("input files");
@@ -525,6 +525,14 @@ void get_options(int argc, char** argv) {
525525
.action(argparse::Action::STORE_TRUE)
526526
.metavar("INPUT_BLIF_FLATNESS");
527527

528+
ext_elaborator_group.add_argument(global_args.tcl_file, "-S")
529+
.help("TCL file")
530+
.metavar("TCL_FILE");
531+
532+
ext_elaborator_group.add_argument(global_args.tcl_file, "--tcl")
533+
.help("TCL file")
534+
.metavar("TCL_FILE");
535+
528536
auto& other_grp = parser.add_argument_group("other options");
529537

530538
other_grp.add_argument(global_args.show_help, "-h")
@@ -699,10 +707,11 @@ void get_options(int argc, char** argv) {
699707
if (!only_one_is_true({
700708
global_args.config_file.provenance() == argparse::Provenance::SPECIFIED, //have a config file
701709
global_args.blif_file.provenance() == argparse::Provenance::SPECIFIED, //have a BLIF file
710+
global_args.tcl_file.provenance() == argparse::Provenance::SPECIFIED, //have a TCL file that includes HDL designs
702711
global_args.verilog_files.value().size() > 0 //have a Verilog input list
703712
})) {
704713
parser.print_usage();
705-
warning_message(PARSE_ARGS, unknown_location, "%s", "Must include only one of either:\n\ta config file(-c)\n\ta BLIF file(-b)\n\ta Verilog file(-V)\nUnless is used for infrastructure directly\n");
714+
warning_message(PARSE_ARGS, unknown_location, "%s", "Must include only one of either:\n\ta config file(-c)\n\ta BLIF file(-b)\n\ta Verilog file(-V)\n\ta TCL file including HDL designs(-S)\nUnless is used for infrastructure directly\n");
706715
}
707716

708717
//adjust thread count
@@ -735,6 +744,14 @@ void get_options(int argc, char** argv) {
735744
configuration.show_yosys_log = global_args.show_yosys_log;
736745
}
737746

747+
if (global_args.tcl_file.provenance() == argparse::Provenance::SPECIFIED) {
748+
configuration.tcl_file = global_args.tcl_file;
749+
750+
coarsen_cleanup = true;
751+
configuration.coarsen = true;
752+
configuration.elaborator_type = elaborator_e::_YOSYS;
753+
}
754+
738755
if (global_args.write_netlist_as_dot.provenance() == argparse::Provenance::SPECIFIED) {
739756
configuration.output_netlist_graphs = global_args.write_netlist_as_dot;
740757
}
@@ -792,6 +809,7 @@ void set_default_config() {
792809
configuration.coarsen = false;
793810
configuration.fflegalize = false;
794811
configuration.show_yosys_log = false;
812+
configuration.tcl_file = "";
795813
configuration.output_file_type = file_type_e::_BLIF;
796814
configuration.elaborator_type = elaborator_e::_ODIN;
797815
configuration.output_ast_graphs = 0;

ODIN_II/regression_test/tools/synth.tcl

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
yosys -import
22

3-
# Read VTR baseline library first
4-
read_verilog -nomem2reg $env(PRIMITIVES);
5-
setattr -mod -set keep_hierarchy 1 single_port_ram;
6-
setattr -mod -set keep_hierarchy 1 dual_port_ram;
3+
# the environment variable VTR_ROOT is set by Odin-II.
4+
# Feel free to specify file paths using "$env(VTR_ROOT)/ ..."
75

86
# Read the hardware decription Verilog
9-
read_verilog -nomem2reg -nolatches $env(TCL_CIRCUIT);
7+
read_verilog -nomem2reg -nolatches $env(VTR_ROOT)/ODIN_II/regression_test/benchmark/verilog/common/mux.v;
108
# Check that cells match libraries and find top module
119
hierarchy -check -auto-top;
1210

@@ -22,8 +20,8 @@ memory_collect; memory_dff; opt;
2220
# Looking for combinatorial loops, wires with multiple drivers and used wires without any driver.
2321
check;
2422
# resolve asynchronous dffs
25-
techmap -map $env(ODIN_TECHLIB)/adff2dff.v;
26-
techmap -map $env(ODIN_TECHLIB)/adffe2dff.v;
23+
techmap -map $env(VTR_ROOT)/ODIN_II/techlib/adff2dff.v;
24+
techmap -map $env(VTR_ROOT)/ODIN_II/techlib/adffe2dff.v;
2725
# convert mem block to bram/rom
2826

2927
# [NOTE]: Yosys complains about expression width more than 24 bits.
@@ -42,9 +40,3 @@ opt -undriven -full; # -noff #potential option to remove all sdff and etc. Only
4240
autoname;
4341
# Print statistics
4442
stat;
45-
46-
# param is to print non-standard cells attributes
47-
# impltf is also used not to show the definition of primary netlist ports, i.e. VCC, GND and PAD, in the output.
48-
write_blif -param -impltf $env(TCL_BLIF);
49-
50-
exit;

0 commit comments

Comments
 (0)