degate  0.1.2
VHDLTBCodeTemplateGenerator.cc
Go to the documentation of this file.
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 }