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
This commit is contained in:
whitequark 2018-12-16 18:46:32 +00:00
parent ddff75b60a
commit ca866d384e
1 changed files with 29 additions and 0 deletions

View File

@ -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());