PandA-2024.02
xilinx_taste_backend_flow.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2015-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
41 
42 #include "config_GRLIB_DIR.hpp"
43 
44 #include "DesignParameters.hpp"
45 #include "Parameter.hpp"
46 #include "SynthesisTool.hpp"
47 #include "XilinxWrapper.hpp"
48 #include "dbgPrintHelper.hpp"
49 #include "fileIO.hpp"
50 #include "generic_device.hpp"
51 #include "string_manipulation.hpp"
52 #include "structural_objects.hpp"
53 #include "technology_manager.hpp"
54 #include "xst_wrapper.hpp"
55 
56 XilinxTasteBackendFlow::XilinxTasteBackendFlow(const ParameterConstRef& _parameters, const std::string& _flow_name,
57  const generic_deviceRef _device)
58  : XilinxBackendFlow(_parameters, _flow_name, _device)
59 {
60  debug_level = _parameters->get_class_debug_level(GET_CLASS(*this));
61 }
62 
64  const std::list<std::string>& hdl_files,
65  const std::list<std::string>& aux_files)
66 {
67  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Generating synthesis scripts");
68  std::string synthesis_file_list;
69  for(const auto& hdl_file : hdl_files)
70  {
71  synthesis_file_list += hdl_file + ";";
72  }
74  actual_parameters->component_name = "TASTE_hardware_architecture";
75  if(!flow_name.empty())
76  {
78  }
79 
80  for(const auto& aux_file : aux_files)
81  {
82  synthesis_file_list += aux_file + ";";
83  }
84  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---List of synthesis files: " + synthesis_file_list);
85  actual_parameters->parameter_values[PARAM_HDL_files] = synthesis_file_list;
86  const technology_managerRef TM = device->get_technology_manager();
89  if(Param->isOption(OPT_clock_name))
90  {
91  actual_parameters->parameter_values[PARAM_clk_name] = Param->getOption<std::string>(OPT_clock_name);
92  }
93  else
94  {
96  }
97  bool connect_iob = false;
98  if(Param->isOption(OPT_connect_iob) && Param->getOption<bool>(OPT_connect_iob))
99  {
100  connect_iob = true;
101  }
103  if(Param->isOption(OPT_top_design_name))
104  {
105  actual_parameters->parameter_values[PARAM_top_id] = Param->getOption<std::string>(OPT_top_design_name);
106  }
107  else
108  {
110  }
111  if(Param->isOption(OPT_backend_script_extensions))
112  {
115  Param->getOption<std::string>(OPT_backend_script_extensions);
116  }
117  else
118  {
120  }
121  if(Param->isOption(OPT_VHDL_library))
122  {
124  actual_parameters->parameter_values[PARAM_VHDL_library] = Param->getOption<std::string>(OPT_VHDL_library);
125  }
126  else
127  {
129  }
130 
132 
133  const auto ret = CreateScripts(actual_parameters);
134 
136 
137  const auto cp_ret = PandaSystem(Param, "cp -r " + relocate_compiler_path(GRLIB_DIR) + " " + GetCurrentPath());
138  if(IsError(cp_ret))
139  {
140  THROW_ERROR("copy of GRLIB returns an error");
141  }
142 
145  {
146  const auto output_temporary_directory = Param->getOption<std::string>(OPT_output_temporary_directory);
147  std::ofstream temp_file(output_temporary_directory + "/temp_xst_prj_file0");
148  temp_file << "vhdl grlib GRLIB/grlib/stdlib/version.vhd" << std::endl;
149  temp_file << "vhdl grlib GRLIB/grlib/stdlib/stdlib.vhd" << std::endl;
150  temp_file << "vhdl grlib GRLIB/grlib/amba/amba.vhd" << std::endl;
151  temp_file << "vhdl techmap GRLIB/techmap/gencomp/gencomp.vhd" << std::endl;
152  temp_file << "vhdl grlib GRLIB/grlib/amba/devices.vhd" << std::endl;
153  temp_file << "vhdl techmap GRLIB/techmap/unisim/pads_unisim.vhd" << std::endl;
154  temp_file << "vhdl techmap GRLIB/techmap/maps/allpads.vhd" << std::endl;
155  temp_file << "vhdl gaisler GRLIB/gaisler/misc/misc.vhd" << std::endl;
156  temp_file << "vhdl techmap GRLIB/techmap/unisim/clkgen_unisim.vhd" << std::endl;
157  temp_file << "vhdl techmap GRLIB/techmap/maps/toutpad.vhd" << std::endl;
158  temp_file << "vhdl techmap GRLIB/techmap/maps/outpad.vhd" << std::endl;
159  temp_file << "vhdl techmap GRLIB/techmap/maps/odpad.vhd" << std::endl;
160  temp_file << "vhdl techmap GRLIB/techmap/maps/iopad.vhd" << std::endl;
161  temp_file << "vhdl techmap GRLIB/techmap/maps/iodpad.vhd" << std::endl;
162  temp_file << "vhdl techmap GRLIB/techmap/maps/inpad.vhd" << std::endl;
163  temp_file << "vhdl techmap GRLIB/techmap/maps/allclkgen.vhd" << std::endl;
164  temp_file << "vhdl gaisler GRLIB/gaisler/pci/pci.vhd" << std::endl;
165  temp_file << "vhdl gaisler GRLIB/gaisler/misc/ahbmst.vhd" << std::endl;
166  temp_file << "vhdl techmap GRLIB/techmap/maps/clkpad.vhd" << std::endl;
167  temp_file << "vhdl techmap GRLIB/techmap/maps/clkgen.vhd" << std::endl;
168  temp_file << "vhdl grlib GRLIB/grlib/amba/apbctrl.vhd" << std::endl;
169  temp_file << "vhdl grlib GRLIB/grlib/amba/ahbctrl.vhd" << std::endl;
170  temp_file << "vhdl gaisler GRLIB/gaisler/pci/pci_target.vhd" << std::endl;
171  temp_file << "vhdl gaisler GRLIB/gaisler/pci/pcipads.vhd" << std::endl;
172  temp_file << "vhdl gaisler GRLIB/gaisler/misc/rstgen.vhd" << std::endl;
173  temp_file.close();
174  const auto xst_prj_file = GetPath(actual_parameters->parameter_values.at(PARAM_xst_prj_file));
175  const auto cat_ret =
176  PandaSystem(Param, "cat " + output_temporary_directory + "/temp_xst_prj_file0 " + xst_prj_file, true,
177  output_temporary_directory + "/temp_xst_prj_file1");
178  if(IsError(cat_ret))
179  {
180  THROW_ERROR("cat of " + xst_prj_file + " failed");
181  }
182  const auto mv_ret =
183  PandaSystem(Param, "mv " + output_temporary_directory + "/temp_xst_prj_file1 " + xst_prj_file);
184  if(IsError(mv_ret))
185  {
186  THROW_ERROR("mv to " + xst_prj_file + " failed");
187  }
188  }
189 
190  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Generated synthesis scripts");
191  return ret;
192 }
193 
195 {
196  std::string ucf_filename = UCF_SUBDIR + dp->component_name + (xst ? ".xcf" : ".ucf");
197  std::ofstream UCF_file(ucf_filename);
198  UCF_file << "CONFIG STEPPING=\"0\";" << std::endl;
199  UCF_file << "" << std::endl;
200  UCF_file << "NET resetn TIG ;" << std::endl;
201  UCF_file << "" << std::endl;
202  UCF_file << "NET \"clk\" PERIOD = 20.000 ;" << std::endl;
203  UCF_file << "" << std::endl;
204  UCF_file << "NET \"pci_clk\" PERIOD = 30.000 ;" << std::endl;
205  UCF_file << "OFFSET = OUT : 11.000 : AFTER pci_clk ;" << std::endl;
206  UCF_file << "OFFSET = IN : 7.000 : BEFORE pci_clk ;" << std::endl;
207  UCF_file << "" << std::endl;
208  UCF_file << R"(NET "clk" LOC = "P20" | IOSTANDARD=LVTTL;)" << std::endl;
209  UCF_file << R"(NET "pci_clk" LOC = "AK19" | IOSTANDARD=LVTTL;)" << std::endl;
210  UCF_file << "" << std::endl;
211  UCF_file << R"(NET "pllref" LOC = "J19" | IOSTANDARD=LVTTL;)" << std::endl;
212  UCF_file << "" << std::endl;
213  UCF_file << R"(NET "resetn" LOC = "G38" | IOSTANDARD=LVTTL;)" << std::endl;
214  UCF_file << "" << std::endl;
215  UCF_file << R"(NET "pci_ad<0>" LOC = "AW16" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
216  UCF_file << R"(NET "pci_ad<1>" LOC = "AV17" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
217  UCF_file << R"(NET "pci_ad<2>" LOC = "AW15" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
218  UCF_file << R"(NET "pci_ad<3>" LOC = "AV15" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
219  UCF_file << R"(NET "pci_ad<4>" LOC = "AU18" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
220  UCF_file << R"(NET "pci_ad<5>" LOC = "AW17" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
221  UCF_file << R"(NET "pci_ad<6>" LOC = "AT18" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
222  UCF_file << R"(NET "pci_ad<7>" LOC = "AP16" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
223  UCF_file << R"(NET "pci_ad<8>" LOC = "AU17" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
224  UCF_file << R"(NET "pci_ad<9>" LOC = "AT16" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
225  UCF_file << R"(NET "pci_ad<10>" LOC = "AU16" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
226  UCF_file << R"(NET "pci_ad<11>" LOC = "AT15" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
227  UCF_file << R"(NET "pci_ad<12>" LOC = "AU15" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
228  UCF_file << R"(NET "pci_ad<13>" LOC = "AR14" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
229  UCF_file << R"(NET "pci_ad<14>" LOC = "AT14" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
230  UCF_file << R"(NET "pci_ad<15>" LOC = "AU13" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
231  UCF_file << R"(NET "pci_ad<16>" LOC = "AT8" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
232  UCF_file << R"(NET "pci_ad<17>" LOC = "AU8" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
233  UCF_file << R"(NET "pci_ad<18>" LOC = "AT9" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
234  UCF_file << R"(NET "pci_ad<19>" LOC = "AU6" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
235  UCF_file << R"(NET "pci_ad<20>" LOC = "AR8" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
236  UCF_file << R"(NET "pci_ad<21>" LOC = "AU7" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
237  UCF_file << R"(NET "pci_ad<22>" LOC = "AU5" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
238  UCF_file << R"(NET "pci_ad<23>" LOC = "AR7" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
239  UCF_file << R"(NET "pci_ad<24>" LOC = "AW7" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
240  UCF_file << R"(NET "pci_ad<25>" LOC = "AV7" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
241  UCF_file << R"(NET "pci_ad<26>" LOC = "AW6" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
242  UCF_file << R"(NET "pci_ad<27>" LOC = "AW5" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
243  UCF_file << R"(NET "pci_ad<28>" LOC = "AV5" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
244  UCF_file << R"(NET "pci_ad<29>" LOC = "AW4" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
245  UCF_file << R"(NET "pci_ad<30>" LOC = "AV4" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
246  UCF_file << R"(NET "pci_ad<31>" LOC = "AV3" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
247  UCF_file << R"(NET "pci_cbe<0>" LOC = "AT13" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
248  UCF_file << R"(NET "pci_cbe<1>" LOC = "AU12" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
249  UCF_file << R"(NET "pci_cbe<2>" LOC = "AR13" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
250  UCF_file << R"(NET "pci_cbe<3>" LOC = "AR12" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
251  UCF_file << "" << std::endl;
252  UCF_file << R"(NET "pci_66" LOC = "AW14" | IOSTANDARD=LVTTL;)" << std::endl;
253  UCF_file << R"(NET "pci_host" LOC = "AV14" | IOSTANDARD=LVTTL;)" << std::endl;
254  UCF_file << R"(NET "pci_devsel" LOC = "AV10" | IOSTANDARD=PCI33_3 | BYPASS; # the PCI spec calls this devseln)"
255  << std::endl;
256  UCF_file << R"(NET "pci_frame" LOC = "AR9" | IOSTANDARD=PCI33_3 | BYPASS; # the PCI spec calls this framen)"
257  << std::endl;
258  UCF_file << R"(NET "pci_gnt" LOC = "AV13" | IOSTANDARD=LVTTL; # the PCI spec calls this gntn)" << std::endl;
259  UCF_file << R"(NET "pci_req" LOC = "AW12" | IOSTANDARD=LVTTL; # the PCI spec calls this reqn)" << std::endl;
260  UCF_file << "" << std::endl;
261  UCF_file << R"(NET "pci_idsel" LOC = "AV9" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
262  UCF_file << R"(NET "pci_irdy" LOC = "AW9" | IOSTANDARD=PCI33_3 | BYPASS; # the PCI spec calls this" irdyn)"
263  << std::endl;
264  UCF_file << R"(NET "pci_lock" LOC = "AU11" | IOSTANDARD=PCI33_3 | BYPASS; # the PCI spec calls this" lockn)"
265  << std::endl;
266  UCF_file << R"(NET "pci_par" LOC = "AW11" | IOSTANDARD=PCI33_3 | BYPASS;)" << std::endl;
267  UCF_file << R"(NET "pci_perr" LOC = "AW10" | IOSTANDARD=PCI33_3 | BYPASS; # the PCI spec calls this perrn)"
268  << std::endl;
269  UCF_file << R"(NET "pci_rst" LOC = "AV8" | IOSTANDARD=LVTTL; # the PCI spec calls this rstn)" << std::endl;
270  UCF_file << R"(NET "pci_serr" LOC = "AT11" | IOSTANDARD=PCI33_3; # the PCI spec calls this serrn)" << std::endl;
271  UCF_file << R"(NET "pci_stop" LOC = "AV12" | IOSTANDARD=PCI33_3 | BYPASS; # the PCI spec calls this stopn)"
272  << std::endl;
273  UCF_file << R"(NET "pci_trdy" LOC = "AU10" | IOSTANDARD=PCI33_3 | BYPASS; # the PCI spec calls this trdyn)"
274  << std::endl;
275  UCF_file.close();
276  if(xst)
277  {
278  dp->parameter_values[PARAM_xcf_file] = ucf_filename;
279  }
280  else
281  {
282  dp->parameter_values[PARAM_ucf_file] = ucf_filename;
283  }
284 }
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
File containing functions and utilities to support the printing of debug messagges.
DesignParametersRef actual_parameters
set of design parameters with the actual values
#define GET_CLASS(obj)
Macro returning the actual type of an object.
#define PARAM_xcf_file
#define PARAM_backend_script_extensions
std::string flow_name
string-based identifier of the flow
Class specification of the manager of the technology library data structures.
#define PARAM_VHDL_library
const generic_deviceRef device
information about the target device
#define UCF_SUBDIR
int debug_level
debugging level of the class
Wrapper to synthesis tools by Xilinx.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
bool IsError(const int error_value)
Utility include.
Definition: exceptions.cpp:58
#define CLOCK_PORT_NAME
standard name for ports
std::string CreateScripts(const DesignParametersRef dp)
Creates the scripts for the specified tools in the right order, along with the overall configuration...
map_t parameter_values
Map between the name of the parameter and the corresponding string-based value.
std::string GenerateSynthesisScripts(const std::string &fu_name, const structural_managerRef SM, const std::list< std::string > &hdl_files, const std::list< std::string > &aux_files) override
Generates the synthesis scripts for the specified design.
This file contains the definition of the parameters for the synthesis tools.
Wrapper to XST by XILINX.
#define PARAM_has_script_extensions
utility function used to read files.
#define PARAM_time_constrained
const ParameterConstRef Param
class containing all the parameters
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
void InitDesignParameters() override
Initializes the parameters.
int PandaSystem(const ParameterConstRef Param, const std::string &system_command, bool host_exec, const std::string &output, const unsigned int type, const bool background, const size_t timeout)
System call forcing execution with bash.
Definition: fileIO.cpp:78
#define PARAM_top_id
This class describes all classes used to represent a structural object.
std::string GetPath(std::filesystem::path path)
Definition: fileIO.hpp:140
std::string component_name
Name of the component.
XilinxTasteBackendFlow(const ParameterConstRef &parameters, const std::string &flow_name, const generic_deviceRef _device)
Constructor.
void create_cf(const DesignParametersRef dp, bool xst) override
Creates the UCF file.
Wrapper to implement a synthesis tools by Xilinx targeting Taste architecture.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
#define PARAM_connect_iob
this class is used to manage the command-line or XML options.
std::string GetCurrentPath()
Definition: fileIO.hpp:123
Generic device description.
#define PARAM_ucf_file
#define PARAM_xst_prj_file
Definition: xst_wrapper.hpp:65
#define PARAM_has_VHDL_library
std::string relocate_compiler_path(const std::string &path, bool resolve_path=false)
Definition: fileIO.hpp:149
#define PARAM_clk_name
refcount< DesignParameters > DesignParametersRef
refcount definition of the class
#define PARAM_HDL_files
Abstract class for a generic synthesis tool.
std::string chain_name
Name of the flow.
#define PARAM_is_combinational

Generated on Mon Feb 12 2024 13:02:56 for PandA-2024.02 by doxygen 1.8.13