Merge pull request #1232 from YosysHQ/dave/write_gzip

Add support for writing gzip-compressed files
This commit is contained in:
David Shah 2019-08-06 19:05:35 +01:00 committed by GitHub
commit 8110fb9266
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 7 deletions

View File

@ -16,6 +16,7 @@ Yosys 0.9 .. Yosys 0.9-dev
- "synth_xilinx" to now infer wide multiplexers (-widemux <min> to enable)
- Added automatic gzip decompression for frontends
- Added $_NMUX_ cell type
- Added automatic gzip compression (based on filename extension) for backends
Yosys 0.8 .. Yosys 0.8-dev
--------------------------

View File

@ -41,6 +41,45 @@ void decompress_gzip(const std::string &filename, std::stringstream &out)
}
gzclose(gzf);
}
/*
An output stream that uses a stringbuf to buffer data internally,
using zlib to write gzip-compressed data every time the stream is flushed.
*/
class gzip_ostream : public std::ostream {
public:
gzip_ostream()
{
rdbuf(&outbuf);
}
bool open(const std::string &filename)
{
return outbuf.open(filename);
}
private:
class gzip_streambuf : public std::stringbuf {
public:
gzip_streambuf() { };
bool open(const std::string &filename)
{
gzf = gzopen(filename.c_str(), "wb");
return gzf != nullptr;
}
virtual int sync() override
{
gzwrite(gzf, reinterpret_cast<const void *>(str().c_str()), unsigned(str().size()));
str("");
return 0;
}
~gzip_streambuf()
{
sync();
gzclose(gzf);
}
private:
gzFile gzf = nullptr;
} outbuf;
};
PRIVATE_NAMESPACE_END
#endif
@ -588,14 +627,28 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st
filename = arg;
rewrite_filename(filename);
std::ofstream *ff = new std::ofstream;
ff->open(filename.c_str(), std::ofstream::trunc);
yosys_output_files.insert(filename);
if (ff->fail()) {
delete ff;
log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
if (filename.size() > 3 && filename.substr(filename.size()-3) == ".gz") {
#ifdef YOSYS_ENABLE_ZLIB
gzip_ostream *gf = new gzip_ostream;
if (!gf->open(filename)) {
delete gf;
log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
}
yosys_output_files.insert(filename);
f = gf;
#else
log_cmd_error("Yosys is compiled without zlib support, unable to write gzip output.\n");
#endif
} else {
std::ofstream *ff = new std::ofstream;
ff->open(filename.c_str(), std::ofstream::trunc);
yosys_output_files.insert(filename);
if (ff->fail()) {
delete ff;
log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
}
f = ff;
}
f = ff;
}
if (called_with_fp)

View File

@ -1,2 +1,4 @@
/*.log
/*.out
/write_gzip.v
/write_gzip.v.gz

View File

@ -0,0 +1,16 @@
read -vlog2k <<EOT
module top(input a, output y);
assign y = !a;
endmodule
EOT
prep -top top
write_verilog write_gzip.v.gz
design -reset
! rm -f write_gzip.v
! gunzip write_gzip.v.gz
read -vlog2k write_gzip.v
! rm -f write_gzip.v
hierarchy -top top
select -assert-any top