mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +00:00 
			
		
		
		
	More progress in FIRRTL back-end
This commit is contained in:
		
							parent
							
								
									c051115e03
								
							
						
					
					
						commit
						e01382739d
					
				
					 3 changed files with 121 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -190,6 +190,102 @@ struct FirrtlWorker
 | 
			
		|||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in("$mux"))
 | 
			
		||||
			{
 | 
			
		||||
				string y_id = make_id(cell->name);
 | 
			
		||||
				int width = cell->parameters.at("\\WIDTH").as_int();
 | 
			
		||||
				string a_expr = make_expr(cell->getPort("\\A"));
 | 
			
		||||
				string b_expr = make_expr(cell->getPort("\\B"));
 | 
			
		||||
				string s_expr = make_expr(cell->getPort("\\S"));
 | 
			
		||||
				wire_decls.push_back(stringf("    wire %s: UInt<%d>\n", y_id.c_str(), width));
 | 
			
		||||
 | 
			
		||||
				string expr = stringf("mux(%s, %s, %s)", s_expr.c_str(), b_expr.c_str(), a_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("$mem"))
 | 
			
		||||
			{
 | 
			
		||||
				string mem_id = make_id(cell->name);
 | 
			
		||||
				int abits = cell->parameters.at("\\ABITS").as_int();
 | 
			
		||||
				int width = cell->parameters.at("\\WIDTH").as_int();
 | 
			
		||||
				int size = cell->parameters.at("\\SIZE").as_int();
 | 
			
		||||
				int rd_ports = cell->parameters.at("\\RD_PORTS").as_int();
 | 
			
		||||
				int wr_ports = cell->parameters.at("\\WR_PORTS").as_int();
 | 
			
		||||
 | 
			
		||||
				Const initdata = cell->parameters.at("\\INIT");
 | 
			
		||||
				for (State bit : initdata.bits)
 | 
			
		||||
					if (bit != State::Sx)
 | 
			
		||||
						log_error("Memory with initialization data: %s.%s\n", log_id(module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
				Const rd_clk_enable = cell->parameters.at("\\RD_CLK_ENABLE");
 | 
			
		||||
				Const wr_clk_enable = cell->parameters.at("\\WR_CLK_ENABLE");
 | 
			
		||||
				Const wr_clk_polarity = cell->parameters.at("\\WR_CLK_POLARITY");
 | 
			
		||||
 | 
			
		||||
				int offset = cell->parameters.at("\\OFFSET").as_int();
 | 
			
		||||
				if (offset != 0)
 | 
			
		||||
					log_error("Memory with nonzero offset: %s.%s\n", log_id(module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
				cell_exprs.push_back(stringf("    mem %s:\n", mem_id.c_str()));
 | 
			
		||||
				cell_exprs.push_back(stringf("      data-type => UInt<%d>\n", width));
 | 
			
		||||
				cell_exprs.push_back(stringf("      depth => %d\n", size));
 | 
			
		||||
 | 
			
		||||
				for (int i = 0; i < rd_ports; i++)
 | 
			
		||||
					cell_exprs.push_back(stringf("      reader => r%d\n", i));
 | 
			
		||||
 | 
			
		||||
				for (int i = 0; i < wr_ports; i++)
 | 
			
		||||
					cell_exprs.push_back(stringf("      writer => w%d\n", i));
 | 
			
		||||
 | 
			
		||||
				cell_exprs.push_back(stringf("      read-latency => 0\n"));
 | 
			
		||||
				cell_exprs.push_back(stringf("      write-latency => 1\n"));
 | 
			
		||||
				cell_exprs.push_back(stringf("      read-under-write => undefined\n"));
 | 
			
		||||
 | 
			
		||||
				for (int i = 0; i < rd_ports; i++)
 | 
			
		||||
				{
 | 
			
		||||
					if (rd_clk_enable[i] != State::S0)
 | 
			
		||||
						log_error("Clocked read port %d on memory %s.%s.\n", i, log_id(module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
					SigSpec data_sig = cell->getPort("\\RD_DATA").extract(i*width, width);
 | 
			
		||||
					string addr_expr = make_expr(cell->getPort("\\RD_ADDR").extract(i*abits, abits));
 | 
			
		||||
 | 
			
		||||
					cell_exprs.push_back(stringf("    %s.r%d.addr <= %s\n", mem_id.c_str(), i, addr_expr.c_str()));
 | 
			
		||||
					cell_exprs.push_back(stringf("    %s.r%d.en <= UInt<1>(1)\n", mem_id.c_str(), i));
 | 
			
		||||
					cell_exprs.push_back(stringf("    %s.r%d.clk <= asClock(UInt<1>(0))\n", mem_id.c_str(), i));
 | 
			
		||||
 | 
			
		||||
					register_reverse_wire_map(stringf("%s.r%d.data", mem_id.c_str(), i), data_sig);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				for (int i = 0; i < wr_ports; i++)
 | 
			
		||||
				{
 | 
			
		||||
					if (wr_clk_enable[i] != State::S1)
 | 
			
		||||
						log_error("Unclocked write port %d on memory %s.%s.\n", i, log_id(module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
					if (wr_clk_polarity[i] != State::S1)
 | 
			
		||||
						log_error("Negedge write port %d on memory %s.%s.\n", i, log_id(module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
					string addr_expr = make_expr(cell->getPort("\\WR_ADDR").extract(i*abits, abits));
 | 
			
		||||
					string data_expr = make_expr(cell->getPort("\\WR_DATA").extract(i*width, width));
 | 
			
		||||
					string clk_expr = make_expr(cell->getPort("\\WR_CLK").extract(i));
 | 
			
		||||
 | 
			
		||||
					SigSpec wen_sig = cell->getPort("\\WR_EN").extract(i*width, width);
 | 
			
		||||
					string wen_expr = make_expr(wen_sig[0]);
 | 
			
		||||
 | 
			
		||||
					for (int i = 1; i < GetSize(wen_sig); i++)
 | 
			
		||||
						if (wen_sig[0] != wen_sig[i])
 | 
			
		||||
							log_error("Complex write enable on port %d on memory %s.%s.\n", i, log_id(module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
					cell_exprs.push_back(stringf("    %s.w%d.addr <= %s\n", mem_id.c_str(), i, addr_expr.c_str()));
 | 
			
		||||
					cell_exprs.push_back(stringf("    %s.w%d.data <= %s\n", mem_id.c_str(), i, data_expr.c_str()));
 | 
			
		||||
					cell_exprs.push_back(stringf("    %s.w%d.en <= %s\n", mem_id.c_str(), i, wen_expr.c_str()));
 | 
			
		||||
					cell_exprs.push_back(stringf("    %s.w%d.clk <= asClock(%s)\n", mem_id.c_str(), i, clk_expr.c_str()));
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in("$dff"))
 | 
			
		||||
			{
 | 
			
		||||
				bool clkpol = cell->parameters.at("\\CLK_POLARITY").as_bool();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
#!/bin/bash
 | 
			
		||||
set -ex
 | 
			
		||||
 | 
			
		||||
../../yosys -p 'prep; write_firrtl test.fir' test.v
 | 
			
		||||
../../yosys -p 'prep -nordff; write_firrtl test.fir' test.v
 | 
			
		||||
 | 
			
		||||
firrtl -i test.fir -o test_out.v
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +13,7 @@ firrtl -i test.fir -o test_out.v
 | 
			
		|||
	rename test gate
 | 
			
		||||
 | 
			
		||||
	prep
 | 
			
		||||
	memory_map
 | 
			
		||||
	miter -equiv -flatten gold gate miter
 | 
			
		||||
	hierarchy -top miter
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,24 @@
 | 
			
		|||
module test(input clk, signed input [7:0] a, b, x, output [15:0] s, d, y, z, u, q);
 | 
			
		||||
  assign s = a+{b[6:2], 2'b1}, d = a-b, y = x, z[7:0] = s+d, z[15:8] = s-d;
 | 
			
		||||
  always @(posedge clk) q <= s ^ d ^ x;
 | 
			
		||||
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
 | 
			
		||||
);
 | 
			
		||||
	reg [31:0] memory [0:31];
 | 
			
		||||
 | 
			
		||||
	always @(posedge clk) begin
 | 
			
		||||
		rdata <= memory[raddr];
 | 
			
		||||
		if (wen) memory[waddr] <= wdata;
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
	always @(posedge clk)
 | 
			
		||||
		q <= s ^ d ^ x;
 | 
			
		||||
endmodule
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue