aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2013-03-14 11:15:00 +0100
committerClifford Wolf <clifford@clifford.at>2013-03-14 11:15:00 +0100
commit11789db206276edf50f45f8d82e094a87643630c (patch)
tree273617ebcc76baca97a426345aeb0ae835073f6a
parentde823ce964b93c0746b81867b29228cdbe00aae6 (diff)
downloadyosys-11789db206276edf50f45f8d82e094a87643630c.tar.gz
yosys-11789db206276edf50f45f8d82e094a87643630c.tar.bz2
yosys-11789db206276edf50f45f8d82e094a87643630c.zip
More support code for $sr cells
-rw-r--r--backends/verilog/verilog_backend.cc30
-rw-r--r--techlibs/simlib.v21
2 files changed, 50 insertions, 1 deletions
diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc
index 7d6c75150..613324b16 100644
--- a/backends/verilog/verilog_backend.cc
+++ b/backends/verilog/verilog_backend.cc
@@ -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");
diff --git a/techlibs/simlib.v b/techlibs/simlib.v
index 179242541..29c13503b 100644
--- a/techlibs/simlib.v
+++ b/techlibs/simlib.v
@@ -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;