|
degate 0.1.1
|
00001 /* -*-c++-*- 00002 00003 This file is part of the IC reverse engineering tool degate. 00004 00005 Copyright 2008, 2009, 2010 by Martin Schobert 00006 00007 Degate is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 any later version. 00011 00012 Degate is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with degate. If not, see <http://www.gnu.org/licenses/>. 00019 00020 */ 00021 00022 00023 #include <VHDLTBCodeTemplateGenerator.h> 00024 #include <boost/format.hpp> 00025 #include <boost/foreach.hpp> 00026 #include <boost/algorithm/string/join.hpp> 00027 00028 using namespace boost; 00029 using namespace degate; 00030 00031 VHDLTBCodeTemplateGenerator::VHDLTBCodeTemplateGenerator(std::string const& entity_name, 00032 std::string const& description, 00033 std::string const& logic_class) : 00034 VHDLCodeTemplateGenerator(entity_name, description, logic_class) { 00035 } 00036 00037 VHDLTBCodeTemplateGenerator::~VHDLTBCodeTemplateGenerator() { 00038 } 00039 00040 std::string VHDLTBCodeTemplateGenerator::generate() const { 00041 00042 std::string tb_entity_name("testbench_"); 00043 tb_entity_name += entity_name; 00044 00045 port_map_type port_map; 00046 BOOST_FOREACH(std::string const& port_name, get_inports()) port_map[port_name] = port_name; 00047 BOOST_FOREACH(std::string const& port_name, get_outports()) port_map[port_name] = port_name; 00048 00049 00050 std::string clock_process_impl; 00051 std::string clock_signal_name = get_port_name_by_type(CLOCK); 00052 std::cout << "clock signal is : " << clock_signal_name << std::endl; 00053 if(!clock_signal_name.empty()) clock_process_impl += generate_clock_process(clock_signal_name); 00054 00055 return 00056 generate_header() + 00057 generate_entity(tb_entity_name) + 00058 generate_architecture(tb_entity_name, 00059 00060 generate_component(entity_name, 00061 generate_port_description()) + 00062 generate_signals(), 00063 00064 generate_instance("uut", entity_name, port_map) + 00065 clock_process_impl + 00066 generate_impl(logic_class)); 00067 } 00068 00069 std::string VHDLTBCodeTemplateGenerator::generate_header() const { 00070 boost::format f("--\n" 00071 "-- This is VHDL testbench for a gate of type %1%\n" 00072 "--\n" 00073 "-- Please customize this code template according to your needs.\n\n" 00074 "library ieee;\n" 00075 "use ieee.std_logic_1164.all;\n\n"); 00076 f % entity_name; 00077 return f.str(); 00078 } 00079 00080 std::string VHDLTBCodeTemplateGenerator::generate_impl(std::string const& logic_class) const { 00081 00082 boost::format f(" tb_proc : PROCESS is \n" 00083 " BEGIN\n\n" 00084 00085 " -- \n" 00086 " -- Please implement test.\n" 00087 " -- \n\n" 00088 00089 " -- signal_name_a << '0';\n" 00090 " -- signal_name_b << '0';\n" 00091 " -- wait for clock_duration; \n" 00092 " -- assert (signal_name_y == '0') report \"Got unexpected output.\" severity note;\n\n" 00093 " END PROCESS tb_proc;\n\n\n"); 00094 00095 return f.str(); 00096 } 00097 00098 std::string VHDLTBCodeTemplateGenerator::generate_signals() const { 00099 00100 boost::format f(" signal %1% : in std_logic;\n" 00101 " signal %2% : out std_logic;\n"); 00102 f % boost::algorithm::join(CodeTemplateGenerator::generate_identifier<std::vector<std::string> >(get_inports()), ", ") 00103 % boost::algorithm::join(CodeTemplateGenerator::generate_identifier<std::vector<std::string> >(get_outports()), ", "); 00104 return f.str(); 00105 } 00106 00107 std::string VHDLTBCodeTemplateGenerator::generate_clock_process(std::string const& clock_signal_name) const { 00108 boost::format f(" constant clock_duration : time := 10 ns;\n\n" 00109 " clk_proc : PROCESS (%1%)\n" 00110 " BEGIN\n" 00111 " IF rising_edge(%2%) then\n" 00112 " %3% <= '0' AFTER clock_duration;\n" 00113 " ELSE\n" 00114 " %4% <= '1' AFTER clock_duration;\n" 00115 " END IF;\n" 00116 " END PROCESS clk_proc;\n\n\n"); 00117 f % clock_signal_name 00118 % clock_signal_name 00119 % clock_signal_name 00120 % clock_signal_name; 00121 00122 return f.str(); 00123 }
1.7.4