aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-08-06 19:05:35 +0100
committerGitHub <noreply@github.com>2019-08-06 19:05:35 +0100
commit8110fb9266e685aaea48359a5aebc4e5ac865240 (patch)
tree51aec1019478938e35ea0df0aeaec77b26c99017
parenta4b59de5d48a89ba5e1b46eb44877a91ceb6fa44 (diff)
parent3a3da678ad0902ad0b16fe48cbb10053cd7dcb28 (diff)
downloadyosys-8110fb9266e685aaea48359a5aebc4e5ac865240.tar.gz
yosys-8110fb9266e685aaea48359a5aebc4e5ac865240.tar.bz2
yosys-8110fb9266e685aaea48359a5aebc4e5ac865240.zip
Merge pull request #1232 from YosysHQ/dave/write_gzip
Add support for writing gzip-compressed files
-rw-r--r--CHANGELOG1
-rw-r--r--kernel/register.cc67
-rw-r--r--tests/various/.gitignore2
-rw-r--r--tests/various/write_gzip.ys16
4 files changed, 79 insertions, 7 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 9e9bda6e9..661581433 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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
--------------------------
diff --git a/kernel/register.cc b/kernel/register.cc
index 4c6e3591f..4f60338e9 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -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)
diff --git a/tests/various/.gitignore b/tests/various/.gitignore
index 7b3e8c68e..31078b298 100644
--- a/tests/various/.gitignore
+++ b/tests/various/.gitignore
@@ -1,2 +1,4 @@
/*.log
/*.out
+/write_gzip.v
+/write_gzip.v.gz
diff --git a/tests/various/write_gzip.ys b/tests/various/write_gzip.ys
new file mode 100644
index 000000000..030ec318e
--- /dev/null
+++ b/tests/various/write_gzip.ys
@@ -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