|
degate 0.1.1
|
A code template generator for Verilog. More...
#include <VerilogCodeTemplateGenerator.h>

Public Types | |
| typedef std::map< std::string, std::string > | port_map_type |
Public Member Functions | |
| VerilogCodeTemplateGenerator (std::string const &entity_name, std::string const &description, std::string const &logic_class="") | |
| virtual | ~VerilogCodeTemplateGenerator () |
| virtual std::string | generate () const |
Protected Member Functions | |
| virtual std::string | generate_header () const |
| virtual std::string | generate_common () const |
| virtual std::string | generate_port_list () const |
| virtual std::string | generate_port_definition () const |
| virtual std::string | generate_module (std::string const &entity_name, std::string const &port_description="") const |
| virtual std::string | generate_impl (std::string const &logic_class="") const |
| virtual std::string | generate_identifier (std::string const &name, std::string const &prefix="") const |
| Generate a Verilog complient identifier from a string. | |
A code template generator for Verilog.
Definition at line 39 of file VerilogCodeTemplateGenerator.h.
| typedef std::map<std::string, std::string> degate::VerilogCodeTemplateGenerator::port_map_type |
Definition at line 50 of file VerilogCodeTemplateGenerator.h.
| VerilogCodeTemplateGenerator::VerilogCodeTemplateGenerator | ( | std::string const & | entity_name, |
| std::string const & | description, | ||
| std::string const & | logic_class = "" |
||
| ) |
Definition at line 31 of file VerilogCodeTemplateGenerator.cc.
| VerilogCodeTemplateGenerator::~VerilogCodeTemplateGenerator | ( | ) | [virtual] |
Definition at line 38 of file VerilogCodeTemplateGenerator.cc.
{
}
| std::string VerilogCodeTemplateGenerator::generate | ( | ) | const [virtual] |
Implements degate::CodeTemplateGenerator.
Reimplemented in degate::VerilogTBCodeTemplateGenerator.
Definition at line 41 of file VerilogCodeTemplateGenerator.cc.
References degate::CodeTemplateGenerator::entity_name, generate_common(), generate_header(), generate_impl(), generate_module(), generate_port_definition(), generate_port_list(), and degate::CodeTemplateGenerator::logic_class.
Referenced by degate::VerilogModuleGenerator::generate_common_code_for_gates().
{
return
generate_common() +
generate_header() +
generate_module(entity_name, generate_port_list()) +
generate_port_definition() +
generate_impl(logic_class) +
"\n\n"
"endmodule\n\n";
}


| std::string VerilogCodeTemplateGenerator::generate_common | ( | ) | const [protected, virtual] |
Reimplemented in degate::VerilogModuleGenerator.
Definition at line 52 of file VerilogCodeTemplateGenerator.cc.
Referenced by generate().
{
return "";
}

| std::string VerilogCodeTemplateGenerator::generate_header | ( | ) | const [protected, virtual] |
Reimplemented in degate::VerilogTBCodeTemplateGenerator.
Definition at line 56 of file VerilogCodeTemplateGenerator.cc.
References degate::CodeTemplateGenerator::entity_name.
Referenced by generate().
{
boost::format f("/** \n"
" * This is a Verilog implementation for a gate of type %1%.\n"
" */\n\n"
"// Please customize this code template according to your needs.\n"
"\n\n");
f % entity_name;
return f.str();
}

| std::string VerilogCodeTemplateGenerator::generate_identifier | ( | std::string const & | name, |
| std::string const & | prefix = "" |
||
| ) | const [protected, virtual] |
Generate a Verilog complient identifier from a string.
Verilog identifier:
Implements degate::CodeTemplateGenerator.
Definition at line 378 of file VerilogCodeTemplateGenerator.cc.
Referenced by degate::VerilogModuleGenerator::generate_impl(), generate_impl(), degate::VerilogTBCodeTemplateGenerator::generate_module(), generate_module(), generate_port_definition(), and generate_port_list().
{
std::string identifier = prefix;
bool first_char = prefix == "" ? true : false;
BOOST_FOREACH(char c, name) {
if(c == '/' || c == '!' || c == '~') identifier.append("not");
else if(first_char && !isalpha(c)) {
identifier.push_back('_');
identifier.push_back(c);
}
else if(isalnum(c)) identifier.push_back(c);
else identifier.push_back('_');
first_char = false;
}
return identifier;
}

| std::string VerilogCodeTemplateGenerator::generate_impl | ( | std::string const & | logic_class = "" | ) | const [protected, virtual] |
Reimplemented in degate::VerilogModuleGenerator.
Definition at line 114 of file VerilogCodeTemplateGenerator.cc.
References degate::CodeTemplateGenerator::CLOCK, degate::CodeTemplateGenerator::D, degate::CodeTemplateGenerator::ENABLE, generate_identifier(), degate::CodeTemplateGenerator::get_first_port_name_not_in(), degate::CodeTemplateGenerator::get_inports(), degate::CodeTemplateGenerator::get_outports(), degate::CodeTemplateGenerator::get_port_name_by_type(), degate::CodeTemplateGenerator::NOT_Q, degate::CodeTemplateGenerator::Q, and degate::CodeTemplateGenerator::RESET.
Referenced by generate().
{
std::vector<std::string> in = get_inports();
std::vector<std::string> out = get_outports();
if(in.size() == 0 || out.size() == 0)
throw DegateRuntimeException("The standard cell has either no input port or no ouput port.");
std::string clock_name = get_port_name_by_type(CLOCK);
if(clock_name.empty()) clock_name = "clock";
std::string reset_name = get_port_name_by_type(RESET);
if(reset_name.empty()) reset_name = "reset";
std::string enable_name = get_port_name_by_type(ENABLE);
if(reset_name.empty()) reset_name = "enable";
if(logic_class == "inverter" &&
in.size() == 1 && out.size() == 1) {
boost::format f(" assign %1% = ~%2%;");
f % generate_identifier(out[0]) % generate_identifier(in[0]);
return f.str();
}
else if(logic_class == "tristate-inverter" ||
logic_class == "tristate-inverter-lo-actiSve" ||
logic_class == "tristate-inverter-hi-active") {
bool low_active = logic_class == "tristate-inverter-lo-active";
boost::format f(" tri %1%; // ???\n\n"
" assign %2% = %3%%4% ? ~%5% : 1'bz;");
f % generate_identifier(out[0])
% generate_identifier(out[0])
% (low_active ? "~" : "")
% generate_identifier(enable_name)
% generate_identifier(get_first_port_name_not_in(in, enable_name));
return f.str();
}
else if((logic_class == "xor" ||
logic_class == "or" ||
logic_class == "and" ||
logic_class == "nor" ||
logic_class == "nand" ||
logic_class == "xnor") &&
in.size() >= 2 && out.size() == 1) {
std::string inner_op, outer_op = "~";
if(logic_class == "nand") inner_op = "&";
else if(logic_class == "nor") inner_op = "|";
else if(logic_class == "xnor") inner_op = "^";
else {
outer_op = "";
if(logic_class == "and") inner_op = "&";
else if(logic_class == "or") inner_op = "|";
else if(logic_class == "xor") inner_op = "^";
}
boost::format f(" assign %1% = %2%%3%%4%%5%;");
f % generate_identifier(out[0])
% outer_op
% (outer_op.empty() ? "" : "(")
% boost::algorithm::join(generate_identifier<std::vector<std::string> >(in),
std::string(" ") + inner_op + std::string(" "))
% (outer_op.empty() ? "" : ")");
return f.str();
}
else if(logic_class == "buffer" && in.size() > 0 && out.size() > 0) {
boost::format f(" assign %1% = %2%; // ???");
f % generate_identifier(out[0]) % generate_identifier(in[0]);
return f.str();
}
else if(logic_class == "buffer-tristate-hi-active" ||
logic_class == "buffer-tristate-lo-active") {
boost::format f(" tri %1%; // ???\n\n"
" bufif%2%(%3%, %4%, %45);");
f % generate_identifier(out[0])
% (logic_class == "buffer-tristate-lo-active" ? "0" : "1")
% generate_identifier(out[0])
% generate_identifier(get_first_port_name_not_in(in, enable_name))
% generate_identifier(enable_name);
return f.str();
}
else if(logic_class == "latch-generic" ||
logic_class == "latch-async-enable") {
boost::format f(" reg %1%;\n\n"
" always @(*)\n"
" if (%2%) %3% = %4%;\n");
f % generate_identifier(out[0])
% generate_identifier(enable_name)
% generate_identifier(out[0])
% generate_identifier(get_first_port_name_not_in(in, enable_name));
return f.str();
}
else if(logic_class == "latch-sync-enable") {
return " // stub not implemented, yet";
}
else if(logic_class == "flipflop") {
boost::format f(" reg %1%;\n"
"\n"
" always @(posedge %2%)\n"
" %3% <= %4%;\n");
f % generate_identifier(get_port_name_by_type(Q))
% generate_identifier(get_port_name_by_type(CLOCK))
% generate_identifier(get_port_name_by_type(Q))
% generate_identifier(get_port_name_by_type(D));
if(get_port_name_by_type(NOT_Q).empty())
return f.str();
else {
boost::format f2("\n"
" reg %1%;\n"
"\n"
" always @*\n"
" %2% <= ~%3%;\n");
f2 % generate_identifier(get_port_name_by_type(NOT_Q))
% generate_identifier(get_port_name_by_type(NOT_Q))
% generate_identifier(get_port_name_by_type(Q));
return f.str() + f2.str();
}
}
else if(logic_class == "flipflop-sync-rst") {
boost::format f(" reg %1%;\n"
"\n"
" always @(posedge %2%)\n"
" if(%3%) // synchronous reset\n"
" %4% <= 1'b0;\n"
" else\n"
" %5% <= %6%;\n");
f % generate_identifier(get_port_name_by_type(Q)) // reg
% generate_identifier(get_port_name_by_type(CLOCK)) // always
% generate_identifier(get_port_name_by_type(RESET)) // if
% generate_identifier(get_port_name_by_type(Q))
% generate_identifier(get_port_name_by_type(Q))
% generate_identifier(get_port_name_by_type(D));
if(get_port_name_by_type(NOT_Q).empty())
return f.str();
else {
boost::format f2("\n"
" reg %1%;\n"
"\n"
" always @*\n"
" %2% <= ~%3%;\n");
f2 % generate_identifier(get_port_name_by_type(NOT_Q))
% generate_identifier(get_port_name_by_type(NOT_Q))
% generate_identifier(get_port_name_by_type(Q));
return f.str() + f2.str();
}
}
else if(logic_class == "flipflop-async-rst") {
boost::format f(" reg %1%;\n"
"\n"
" always @(posedge %2% or posedge %3%)\n"
" if(%4%) // asynchronous reset\n"
" %5% <= 1'b0;\n"
" else\n"
" %6% <= %7%;\n");
f % generate_identifier(get_port_name_by_type(Q)) // reg
% generate_identifier(get_port_name_by_type(CLOCK)) // always
% generate_identifier(get_port_name_by_type(RESET)) // always
% generate_identifier(get_port_name_by_type(RESET)) // if
% generate_identifier(get_port_name_by_type(Q))
% generate_identifier(get_port_name_by_type(Q))
% generate_identifier(get_port_name_by_type(D));
if(get_port_name_by_type(NOT_Q).empty())
return f.str();
else {
boost::format f2("\n"
" reg %1%;\n"
"\n"
" always @*\n"
" %2% <= ~%3%;\n");
f2 % generate_identifier(get_port_name_by_type(NOT_Q))
% generate_identifier(get_port_name_by_type(NOT_Q))
% generate_identifier(get_port_name_by_type(Q));
return f.str() + f2.str();
}
}
else if(logic_class == "generic-combinational-logic" ||
logic_class == "ao" ||
logic_class == "aoi" ||
logic_class == "oa" ||
logic_class == "oai") {
std::string ret;
BOOST_FOREACH(std::string const& oport,
generate_identifier<std::vector<std::string> >(get_outports())) {
boost::format f(" assign %1% = ...;\n");
f % oport;
ret += f.str();
}
return ret;
}
else if(logic_class == "half-adder") {
return " // assign {cout,sum} = a + b + cin;\n";
}
else if(logic_class == "full-adder") {
return " // stub not implemented, yet";
}
else if(logic_class == "mux") {
boost::format f(" reg %1%;\n"
"\n"
" always @*\n"
" begin\n"
" %2% = 1'b0; // default\n"
" case({sel1, sel0}) // just an example\n"
" 2'b00 : %3% = a;\n"
" 2'b01 : %4% = b;\n"
" 2'b10 : %5% = c;\n"
" 2'b11 : %6% = d;\n"
" endcase\n"
" end\n");
f % generate_identifier(out[0])
% generate_identifier(out[0])
% generate_identifier(out[0])
% generate_identifier(out[0])
% generate_identifier(out[0])
% generate_identifier(out[0]);
return f.str();
}
else if(logic_class == "demux") {
boost::format f(" reg a, b, c, d;\n"
"\n"
" always @*\n"
" begin\n"
" %1% = 1'b0; // default\n"
" case({sel1, sel0}) // just an example\n"
" 2'b00 : a = %2%;\n"
" 2'b01 : b = %3%;\n"
" 2'b10 : c = %4%;\n"
" 2'b11 : d = %5%;\n"
" endcase\n"
" end\n");
f % generate_identifier(in[0])
% generate_identifier(in[0])
% generate_identifier(in[0])
% generate_identifier(in[0])
% generate_identifier(in[0]);
return f.str();
}
return
"/*\n"
" * Please implement behaviour.\n"
" */\n";
}


| std::string VerilogCodeTemplateGenerator::generate_module | ( | std::string const & | entity_name, |
| std::string const & | port_description = "" |
||
| ) | const [protected, virtual] |
Definition at line 66 of file VerilogCodeTemplateGenerator.cc.
References generate_identifier().
Referenced by generate().
{
boost::format f("module %1% (\n"
"%2%"
");\n\n");
f % generate_identifier(entity_name, "dg_")
% port_description;
return f.str();
}


| std::string VerilogCodeTemplateGenerator::generate_port_definition | ( | ) | const [protected, virtual] |
Definition at line 88 of file VerilogCodeTemplateGenerator.cc.
References generate_identifier(), degate::CodeTemplateGenerator::get_inports(), and degate::CodeTemplateGenerator::get_outports().
Referenced by generate().
{
std::string ret;
ret += " // input ports\n";
BOOST_FOREACH(std::string const& port_name,
generate_identifier<std::vector<std::string> >(get_inports())) {
boost::format f(" input %1%;\n");
f % port_name;
ret += f.str();
}
ret += "\n // output ports\n";
BOOST_FOREACH(std::string const& port_name,
generate_identifier<std::vector<std::string> >(get_outports())) {
boost::format f(" output %1%;\n");
f % port_name;
ret += f.str();
}
ret += "\n";
return ret;
}


| std::string VerilogCodeTemplateGenerator::generate_port_list | ( | ) | const [protected, virtual] |
Definition at line 77 of file VerilogCodeTemplateGenerator.cc.
References generate_identifier(), degate::CodeTemplateGenerator::get_inports(), and degate::CodeTemplateGenerator::get_outports().
Referenced by generate().
{
boost::format f(" %1%%2%\n"
" %3%\n");
f % boost::algorithm::join(generate_identifier<std::vector<std::string> >(get_inports()), ", ")
% (get_inports().size() > 0 ? ", " : "")
% boost::algorithm::join(generate_identifier<std::vector<std::string> >(get_outports()), ", ");
return f.str();
}


1.7.4