mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	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
					
				
					 3 changed files with 181 additions and 27 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue