aboutsummaryrefslogtreecommitdiffstats
path: root/backends/verilog
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2018-12-16 18:46:32 +0000
committerwhitequark <whitequark@whitequark.org>2018-12-16 18:46:32 +0000
commitca866d384e666f27e2cd7bb80950d0a1dd7c0ebd (patch)
tree0977ea610066ce1ac20fee43df07bdb73edda37d /backends/verilog
parentddff75b60ab6b29bbc8425c7f5ac2e6ebbbf32a6 (diff)
downloadyosys-ca866d384e666f27e2cd7bb80950d0a1dd7c0ebd.tar.gz
yosys-ca866d384e666f27e2cd7bb80950d0a1dd7c0ebd.tar.bz2
yosys-ca866d384e666f27e2cd7bb80950d0a1dd7c0ebd.zip
write_verilog: handle the $shift cell.
The implementation corresponds to the following Verilog, which is lifted straight from simlib.v: module \\$shift (A, B, Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; parameter A_WIDTH = 0; parameter B_WIDTH = 0; parameter Y_WIDTH = 0; input [A_WIDTH-1:0] A; input [B_WIDTH-1:0] B; output [Y_WIDTH-1:0] Y; generate if (B_SIGNED) begin:BLOCK1 assign Y = $signed(B) < 0 ? A << -B : A >> B; end else begin:BLOCK2 assign Y = A >> B; end endgenerate endmodule
Diffstat (limited to 'backends/verilog')
-rw-r--r--backends/verilog/verilog_backend.cc29
1 files changed, 29 insertions, 0 deletions
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc
index 3a47b478f..71db25f98 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -678,6 +678,35 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell)
#undef HANDLE_UNIOP
#undef HANDLE_BINOP
+ if (cell->type == "$shift")
+ {
+ f << stringf("%s" "assign ", indent.c_str());
+ dump_sigspec(f, cell->getPort("\\Y"));
+ f << stringf(" = ");
+ if (cell->getParam("\\B_SIGNED").as_bool())
+ {
+ f << stringf("$signed(");
+ dump_sigspec(f, cell->getPort("\\B"));
+ f << stringf(")");
+ f << stringf(" < 0 ? ");
+ dump_sigspec(f, cell->getPort("\\A"));
+ f << stringf(" << - ");
+ dump_sigspec(f, cell->getPort("\\B"));
+ f << stringf(" : ");
+ dump_sigspec(f, cell->getPort("\\A"));
+ f << stringf(" >> ");
+ dump_sigspec(f, cell->getPort("\\B"));
+ }
+ else
+ {
+ dump_sigspec(f, cell->getPort("\\A"));
+ f << stringf(" >> ");
+ dump_sigspec(f, cell->getPort("\\B"));
+ }
+ f << stringf(";\n");
+ return true;
+ }
+
if (cell->type == "$shiftx")
{
f << stringf("%s" "assign ", indent.c_str());