More support code for $sr cells
authorClifford Wolf <clifford@clifford.at>
Thu, 14 Mar 2013 10:15:00 +0000 (11:15 +0100)
committerClifford Wolf <clifford@clifford.at>
Thu, 14 Mar 2013 10:15:00 +0000 (11:15 +0100)
backends/verilog/verilog_backend.cc
techlibs/simlib.v

index 7d6c75150bd019663ceeacff63582588b5b2936a..613324b1638e55695e53c958c12cf464d1a4f23c 100644 (file)
@@ -143,7 +143,7 @@ bool is_reg_wire(RTLIL::SigSpec sig, std::string &reg_name)
                if (sig.width == 1)
                        reg_name += stringf("[%d]", sig.chunks[0].wire->start_offset +  sig.chunks[0].offset);
                else
-                       reg_name += stringf("[%d]", sig.chunks[0].wire->start_offset +  sig.chunks[0].offset + sig.chunks[0].width - 1,
+                       reg_name += stringf("[%d:%d]", sig.chunks[0].wire->start_offset +  sig.chunks[0].offset + sig.chunks[0].width - 1,
                                        sig.chunks[0].wire->start_offset +  sig.chunks[0].offset);
        }
        return true;
@@ -556,6 +556,33 @@ bool dump_cell_expr(FILE *f, std::string indent, RTLIL::Cell *cell)
                return true;
        }
 
+       if (cell->type == "$sr")
+       {
+               RTLIL::SigSpec sig_set, sig_reset;
+
+               std::string reg_name = cellname(cell);
+               bool out_is_reg_wire = is_reg_wire(cell->connections["\\Q"], reg_name);
+
+               if (!out_is_reg_wire)
+                       fprintf(f, "%s" "reg [%d:0] %s;\n", indent.c_str(), cell->parameters["\\WIDTH"].as_int()-1, reg_name.c_str());
+
+               fprintf(f, "%s" "always @*\n", indent.c_str());
+
+               fprintf(f, "%s" "    %s <= (%s | ", indent.c_str(), reg_name.c_str(), reg_name.c_str());
+               dump_cell_expr_port(f, cell, "S", false);
+               fprintf(f, ") & ~");
+               dump_cell_expr_port(f, cell, "R", false);
+               fprintf(f, ";\n");
+
+               if (!out_is_reg_wire) {
+                       fprintf(f, "%s" "assign ", indent.c_str());
+                       dump_sigspec(f, cell->connections["\\Q"]);
+                       fprintf(f, " = %s;\n", reg_name.c_str());
+               }
+
+               return true;
+       }
+
        // FIXME: $memrd, $memwr, $mem, $fsm
 
        return false;
@@ -891,6 +918,7 @@ struct VerilogBackend : public Backend {
 
                reg_ct.clear();
                reg_ct.setup_stdcells_mem();
+               reg_ct.cell_types.insert("$sr");
                reg_ct.cell_types.insert("$dff");
                reg_ct.cell_types.insert("$adff");
 
index 1792425415d1a9be5447000ac4bc268e72bf65bd..29c13503b5abeec336f70d48e84578656b215cf6 100644 (file)
@@ -642,6 +642,27 @@ endmodule
 
 // --------------------------------------------------------
 
+module \$sr (S, R, Q);
+
+parameter WIDTH = 0;
+
+input CLK;
+input [WIDTH-1:0] S, R;
+output reg [WIDTH-1:0] Q;
+
+integer i;
+always @(S, R)
+       for (i = 0; i < WIDTH; i = i+1) begin
+               if (R[i])
+                       Q[i] <= 0;
+               else if (S[i])
+                       Q[i] <= 1;
+       end
+
+endmodule
+
+// --------------------------------------------------------
+
 module \$dff (CLK, D, Q);
 
 parameter WIDTH = 0;