mirror of https://github.com/YosysHQ/yosys.git
More progress on Firrtl backend.
Chisel -> Firrtl -> Verilog -> Firrtl -> Verilog is successful for a simple rocket-chip design.
This commit is contained in:
parent
69468d5a16
commit
794cec0016
|
@ -157,7 +157,53 @@ struct FirrtlWorker
|
|||
|
||||
for (auto cell : module->cells())
|
||||
{
|
||||
if (cell->type.in("$add", "$sub", "$xor"))
|
||||
if (cell->type.in("$not", "$logic_not", "$neg", "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_bool", "$reduce_xnor"))
|
||||
{
|
||||
string y_id = make_id(cell->name);
|
||||
bool is_signed = cell->parameters.at("\\A_SIGNED").as_bool();
|
||||
int y_width = cell->parameters.at("\\Y_WIDTH").as_int();
|
||||
string a_expr = make_expr(cell->getPort("\\A"));
|
||||
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
|
||||
|
||||
if (cell->parameters.at("\\A_SIGNED").as_bool()) {
|
||||
a_expr = "asSInt(" + a_expr + ")";
|
||||
}
|
||||
|
||||
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
|
||||
|
||||
string primop;
|
||||
bool always_uint = false;
|
||||
if (cell->type == "$not") primop = "not";
|
||||
if (cell->type == "$neg") primop = "neg";
|
||||
if (cell->type == "$logic_not") {
|
||||
primop = "eq";
|
||||
a_expr = stringf("%s, UInt(0)", a_expr.c_str());
|
||||
}
|
||||
if (cell->type == "$reduce_and") primop = "andr";
|
||||
if (cell->type == "$reduce_or") primop = "orr";
|
||||
if (cell->type == "$reduce_xor") primop = "xorr";
|
||||
if (cell->type == "$reduce_xnor") {
|
||||
primop = "not";
|
||||
a_expr = stringf("xorr(%s)", a_expr.c_str());
|
||||
}
|
||||
if (cell->type == "$reduce_bool") {
|
||||
primop = "neq";
|
||||
a_expr = stringf("%s, UInt(0)", a_expr.c_str());
|
||||
}
|
||||
|
||||
string expr = stringf("%s(%s)", primop.c_str(), a_expr.c_str());
|
||||
|
||||
if ((is_signed && !always_uint))
|
||||
expr = stringf("asUInt(%s)", expr.c_str());
|
||||
|
||||
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
|
||||
register_reverse_wire_map(y_id, cell->getPort("\\Y"));
|
||||
|
||||
continue;
|
||||
}
|
||||
if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$xor", "$and", "$or", "$eq", "$eqx",
|
||||
"$gt", "$ge", "$lt", "$le", "$ne", "$nex", "$shr", "$sshr", "$sshl", "$shl",
|
||||
"$logic_and", "$logic_or"))
|
||||
{
|
||||
string y_id = make_id(cell->name);
|
||||
bool is_signed = cell->parameters.at("\\A_SIGNED").as_bool();
|
||||
|
@ -166,22 +212,88 @@ struct FirrtlWorker
|
|||
string b_expr = make_expr(cell->getPort("\\B"));
|
||||
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
|
||||
|
||||
if (is_signed) {
|
||||
if (cell->parameters.at("\\A_SIGNED").as_bool()) {
|
||||
a_expr = "asSInt(" + a_expr + ")";
|
||||
}
|
||||
if (cell->parameters.at("\\A_SIGNED").as_bool() & (cell->type != "$shr")) {
|
||||
b_expr = "asSInt(" + b_expr + ")";
|
||||
}
|
||||
|
||||
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
|
||||
b_expr = stringf("pad(%s, %d)", b_expr.c_str(), y_width);
|
||||
|
||||
if ((cell->type != "$shl") && (cell->type != "$sshl")) {
|
||||
b_expr = stringf("pad(%s, %d)", b_expr.c_str(), y_width);
|
||||
}
|
||||
|
||||
if (cell->parameters.at("\\A_SIGNED").as_bool() & (cell->type == "$shr")) {
|
||||
a_expr = "asUInt(" + a_expr + ")";
|
||||
}
|
||||
|
||||
string primop;
|
||||
bool always_uint = false;
|
||||
if (cell->type == "$add") primop = "add";
|
||||
if (cell->type == "$sub") primop = "sub";
|
||||
if (cell->type == "$xor") primop = "xor";
|
||||
if (cell->type == "$mul") primop = "mul";
|
||||
if (cell->type == "$div") primop = "div";
|
||||
if (cell->type == "$mod") primop = "rem";
|
||||
if (cell->type == "$and") {
|
||||
primop = "and";
|
||||
always_uint = true;
|
||||
}
|
||||
if (cell->type == "$or" ) {
|
||||
primop = "or";
|
||||
always_uint = true;
|
||||
}
|
||||
if (cell->type == "$xor") {
|
||||
primop = "xor";
|
||||
always_uint = true;
|
||||
}
|
||||
if ((cell->type == "$eq") | (cell->type == "$eqx")) {
|
||||
primop = "eq";
|
||||
always_uint = true;
|
||||
}
|
||||
if ((cell->type == "$ne") | (cell->type == "$nex")) {
|
||||
primop = "neq";
|
||||
always_uint = true;
|
||||
}
|
||||
if (cell->type == "$gt") {
|
||||
primop = "gt";
|
||||
always_uint = true;
|
||||
}
|
||||
if (cell->type == "$ge") {
|
||||
primop = "geq";
|
||||
always_uint = true;
|
||||
}
|
||||
if (cell->type == "$lt") {
|
||||
primop = "lt";
|
||||
always_uint = true;
|
||||
}
|
||||
if (cell->type == "$le") {
|
||||
primop = "leq";
|
||||
always_uint = true;
|
||||
}
|
||||
if ((cell->type == "$shl") | (cell->type == "$sshl")) primop = "dshl";
|
||||
if ((cell->type == "$shr") | (cell->type == "$sshr")) primop = "dshr";
|
||||
if ((cell->type == "$logic_and")) {
|
||||
primop = "and";
|
||||
a_expr = "neq(" + a_expr + ", UInt(0))";
|
||||
b_expr = "neq(" + b_expr + ", UInt(0))";
|
||||
always_uint = true;
|
||||
}
|
||||
if ((cell->type == "$logic_or")) {
|
||||
primop = "or";
|
||||
a_expr = "neq(" + a_expr + ", UInt(0))";
|
||||
b_expr = "neq(" + b_expr + ", UInt(0))";
|
||||
always_uint = true;
|
||||
}
|
||||
|
||||
if (!cell->parameters.at("\\B_SIGNED").as_bool()) {
|
||||
b_expr = "asUInt(" + b_expr + ")";
|
||||
}
|
||||
|
||||
string expr = stringf("%s(%s, %s)", primop.c_str(), a_expr.c_str(), b_expr.c_str());
|
||||
|
||||
if ((is_signed && !cell->type.in("$xor")) || cell->type.in("$sub"))
|
||||
if ((is_signed && !always_uint) || cell->type.in("$sub"))
|
||||
expr = stringf("asUInt(%s)", expr.c_str());
|
||||
|
||||
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
../../yosys -p 'prep -nordff; write_firrtl test.fir' test.v
|
||||
cd ../../
|
||||
make
|
||||
cd backends/firrtl
|
||||
|
||||
firrtl -i test.fir -o test_out.v
|
||||
../../yosys -q -p 'prep -nordff; write_firrtl test.fir' $1
|
||||
|
||||
../../yosys -p '
|
||||
read_verilog test.v
|
||||
rename test gold
|
||||
firrtl -i test.fir -o test_out.v -ll Info
|
||||
|
||||
../../yosys -p "
|
||||
read_verilog $1
|
||||
rename Top gold
|
||||
|
||||
read_verilog test_out.v
|
||||
rename test gate
|
||||
rename Top gate
|
||||
|
||||
prep
|
||||
memory_map
|
||||
|
@ -18,5 +22,4 @@ firrtl -i test.fir -o test_out.v
|
|||
hierarchy -top miter
|
||||
|
||||
sat -verify -prove trigger 0 -set-init-zero -seq 10 miter
|
||||
'
|
||||
|
||||
"
|
||||
|
|
|
@ -1,24 +1,63 @@
|
|||
module test(
|
||||
input clk, wen,
|
||||
input [4:0] waddr, raddr,
|
||||
input [31:0] wdata,
|
||||
output reg [31:0] rdata,
|
||||
signed input [7:0] a, b, x,
|
||||
output [15:0] s, d, y, z, u, q
|
||||
input [7:0] uns,
|
||||
input signed [7:0] a, b,
|
||||
input signed [23:0] c,
|
||||
input signed [2:0] sel,
|
||||
output [15:0] s, d, y, z, u, q, p, mul, div, mod, mux, And, Or, Xor, eq, neq, gt, lt, geq, leq, eqx, shr, sshr, shl, sshl, Land, Lor, Lnot, Not, Neg, pos, Andr, Orr, Xorr, Xnorr, Reduce_bool,
|
||||
output [7:0] PMux
|
||||
);
|
||||
reg [31:0] memory [0:31];
|
||||
|
||||
always @(posedge clk) begin
|
||||
rdata <= memory[raddr];
|
||||
if (wen) memory[waddr] <= wdata;
|
||||
end
|
||||
|
||||
//initial begin
|
||||
//$display("shr = %b", shr);
|
||||
//end
|
||||
assign s = a+{b[6:2], 2'b1};
|
||||
assign d = a-b;
|
||||
assign y = x;
|
||||
assign z[7:0] = s+d;
|
||||
assign z[15:8] = s-d;
|
||||
assign p = a & b | x;
|
||||
assign mul = a * b;
|
||||
assign div = a / b;
|
||||
assign mod = a % b;
|
||||
assign mux = x[0] ? a : b;
|
||||
assign And = a & b;
|
||||
assign Or = a | b;
|
||||
assign Xor = a ^ b;
|
||||
assign Not = ~a;
|
||||
assign Neg = -a;
|
||||
assign eq = a == b;
|
||||
assign neq = a != b;
|
||||
assign gt = a > b;
|
||||
assign lt = a < b;
|
||||
assign geq = a >= b;
|
||||
assign leq = a <= b;
|
||||
assign eqx = a === b;
|
||||
assign shr = a >> b; //0111111111000000
|
||||
assign sshr = a >>> b;
|
||||
assign shl = a << b;
|
||||
assign sshl = a <<< b;
|
||||
assign Land = a && b;
|
||||
assign Lor = a || b;
|
||||
assign Lnot = !a;
|
||||
assign pos = $signed(uns);
|
||||
assign Andr = &a;
|
||||
assign Orr = |a;
|
||||
assign Xorr = ^a;
|
||||
assign Xnorr = ~^a;
|
||||
always @*
|
||||
if(!a) begin
|
||||
Reduce_bool = a;
|
||||
end else begin
|
||||
Reduce_bool = b;
|
||||
end
|
||||
//always @(sel or c or a)
|
||||
// begin
|
||||
// case (sel)
|
||||
// 3'b000: PMux = a;
|
||||
// 3'b001: PMux = c[7:0];
|
||||
// 3'b010: PMux = c[15:8];
|
||||
// 3'b100: PMux = c[23:16];
|
||||
// endcase
|
||||
// end
|
||||
|
||||
always @(posedge clk)
|
||||
q <= s ^ d ^ x;
|
||||
endmodule
|
||||
|
|
Loading…
Reference in New Issue