mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	efinix: Use memory_libmap pass.
				
					
				
			This commit is contained in:
		
							parent
							
								
									f4d1426229
								
							
						
					
					
						commit
						9d11575856
					
				
					 4 changed files with 164 additions and 102 deletions
				
			
		| 
						 | 
					@ -1,32 +1,19 @@
 | 
				
			||||||
bram $__EFINIX_5K
 | 
					ram block $__EFINIX_5K_ {
 | 
				
			||||||
  init 1
 | 
						abits 12;
 | 
				
			||||||
 | 
						widths 1 2 5 10 20 per_port;
 | 
				
			||||||
  abits 8  @a8d16
 | 
						cost 32;
 | 
				
			||||||
  dbits 16 @a8d16
 | 
						init no_undef;
 | 
				
			||||||
  abits 9  @a9d8
 | 
						port sr "R" {
 | 
				
			||||||
  dbits 8  @a9d8
 | 
							clock anyedge;
 | 
				
			||||||
  abits 10 @a10d4
 | 
							rden;
 | 
				
			||||||
  dbits 4  @a10d4
 | 
						}
 | 
				
			||||||
  abits 11 @a11d2
 | 
						port sw "W" {
 | 
				
			||||||
  dbits 2  @a11d2
 | 
							clock anyedge;
 | 
				
			||||||
  abits 12 @a12d1
 | 
							option "WRITE_MODE" "READ_FIRST" {
 | 
				
			||||||
  dbits 1  @a12d1
 | 
								wrtrans "R" old;
 | 
				
			||||||
  abits 8  @a8d20
 | 
							}
 | 
				
			||||||
  dbits 20 @a8d20
 | 
							option "WRITE_MODE" "WRITE_FIRST" {
 | 
				
			||||||
  abits 9  @a9d10
 | 
								wrtrans "R" new;
 | 
				
			||||||
  dbits 10 @a9d10
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
  groups 2
 | 
					}
 | 
				
			||||||
  ports 1 1
 | 
					 | 
				
			||||||
  wrmode 1 0
 | 
					 | 
				
			||||||
  enable 1 1
 | 
					 | 
				
			||||||
  transp 0 2
 | 
					 | 
				
			||||||
  clocks 2 3
 | 
					 | 
				
			||||||
  clkpol 2 3
 | 
					 | 
				
			||||||
endbram
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
match $__EFINIX_5K
 | 
					 | 
				
			||||||
  min bits 256
 | 
					 | 
				
			||||||
  min efficiency 5
 | 
					 | 
				
			||||||
  shuffle_enable B
 | 
					 | 
				
			||||||
endmatch
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,65 +1,149 @@
 | 
				
			||||||
module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
 | 
					module $__EFINIX_5K_ (...);
 | 
				
			||||||
	parameter CFG_ABITS = 8;
 | 
						parameter INIT = 0;
 | 
				
			||||||
	parameter CFG_DBITS = 20;
 | 
						parameter OPTION_WRITE_MODE = "READ_FIRST";
 | 
				
			||||||
	parameter CFG_ENABLE_A = 1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	parameter CLKPOL2 = 1;
 | 
						parameter PORT_R_WIDTH = 20;
 | 
				
			||||||
	parameter CLKPOL3 = 1;
 | 
						parameter PORT_R_CLK_POL = 1;
 | 
				
			||||||
	parameter [5119:0] INIT = 5119'bx;
 | 
						parameter PORT_W_WIDTH = 20;
 | 
				
			||||||
	parameter TRANSP2 = 0;
 | 
						parameter PORT_W_CLK_POL = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	input CLK2;
 | 
						input PORT_R_CLK;
 | 
				
			||||||
	input CLK3;
 | 
						input PORT_R_RD_EN;
 | 
				
			||||||
 | 
						input [11:0] PORT_R_ADDR;
 | 
				
			||||||
 | 
						output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	input [CFG_ABITS-1:0] A1ADDR;
 | 
						input PORT_W_CLK;
 | 
				
			||||||
	input [CFG_DBITS-1:0] A1DATA;
 | 
						input PORT_W_WR_EN;
 | 
				
			||||||
	input [CFG_ENABLE_A-1:0] A1EN;
 | 
						input [11:0] PORT_W_ADDR;
 | 
				
			||||||
 | 
						input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	input [CFG_ABITS-1:0] B1ADDR;
 | 
						localparam IS_5BIT = PORT_R_WIDTH >= 5 && PORT_W_WIDTH >= 5;
 | 
				
			||||||
	output [CFG_DBITS-1:0] B1DATA;
 | 
					 | 
				
			||||||
	input B1EN;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	localparam WRITEMODE_A = TRANSP2 ? "WRITE_FIRST" : "READ_FIRST";
 | 
						localparam RADDR_WIDTH =
 | 
				
			||||||
 | 
							PORT_R_WIDTH == 1 ? 12 :
 | 
				
			||||||
 | 
							PORT_R_WIDTH == 2 ? 11 :
 | 
				
			||||||
 | 
							PORT_R_WIDTH == 5 ? 10 :
 | 
				
			||||||
 | 
							PORT_R_WIDTH == 10 ? 9 :
 | 
				
			||||||
 | 
							8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						localparam WADDR_WIDTH =
 | 
				
			||||||
 | 
							PORT_W_WIDTH == 1 ? 12 :
 | 
				
			||||||
 | 
							PORT_W_WIDTH == 2 ? 11 :
 | 
				
			||||||
 | 
							PORT_W_WIDTH == 5 ? 10 :
 | 
				
			||||||
 | 
							PORT_W_WIDTH == 10 ? 9 :
 | 
				
			||||||
 | 
							8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						localparam READ_WIDTH = 
 | 
				
			||||||
 | 
							PORT_R_WIDTH == 1 ? 1 :
 | 
				
			||||||
 | 
							PORT_R_WIDTH == 2 ? 2 :
 | 
				
			||||||
 | 
							PORT_R_WIDTH == 5 ? (IS_5BIT ? 5 : 4) :
 | 
				
			||||||
 | 
							PORT_R_WIDTH == 10 ? (IS_5BIT ? 10 : 8) :
 | 
				
			||||||
 | 
							(IS_5BIT ? 20 : 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						localparam WRITE_WIDTH = 
 | 
				
			||||||
 | 
							PORT_W_WIDTH == 1 ? 1 :
 | 
				
			||||||
 | 
							PORT_W_WIDTH == 2 ? 2 :
 | 
				
			||||||
 | 
							PORT_W_WIDTH == 5 ? (IS_5BIT ? 5 : 4) :
 | 
				
			||||||
 | 
							PORT_W_WIDTH == 10 ? (IS_5BIT ? 10 : 8) :
 | 
				
			||||||
 | 
							(IS_5BIT ? 20 : 16);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wire [RADDR_WIDTH-1:0] RADDR = PORT_R_ADDR[11:12-RADDR_WIDTH];
 | 
				
			||||||
 | 
						wire [WADDR_WIDTH-1:0] WADDR = PORT_W_ADDR[11:12-WADDR_WIDTH];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wire [WRITE_WIDTH-1:0] WDATA;
 | 
				
			||||||
 | 
						wire [READ_WIDTH-1:0] RDATA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						generate
 | 
				
			||||||
 | 
							case (WRITE_WIDTH)
 | 
				
			||||||
 | 
							1:	assign WDATA = PORT_W_WR_DATA;
 | 
				
			||||||
 | 
							2:	assign WDATA = PORT_W_WR_DATA;
 | 
				
			||||||
 | 
							4:	assign WDATA = PORT_W_WR_DATA[3:0];
 | 
				
			||||||
 | 
							5:	assign WDATA = PORT_W_WR_DATA;
 | 
				
			||||||
 | 
							8:	assign WDATA = {
 | 
				
			||||||
 | 
								PORT_W_WR_DATA[8:5],
 | 
				
			||||||
 | 
								PORT_W_WR_DATA[3:0]
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							10:	assign WDATA = PORT_W_WR_DATA;
 | 
				
			||||||
 | 
							16:	assign WDATA = {
 | 
				
			||||||
 | 
								PORT_W_WR_DATA[18:15],
 | 
				
			||||||
 | 
								PORT_W_WR_DATA[13:10],
 | 
				
			||||||
 | 
								PORT_W_WR_DATA[8:5],
 | 
				
			||||||
 | 
								PORT_W_WR_DATA[3:0]
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							20:	assign WDATA = PORT_W_WR_DATA;
 | 
				
			||||||
 | 
							endcase
 | 
				
			||||||
 | 
							case (READ_WIDTH)
 | 
				
			||||||
 | 
							1:	assign PORT_R_RD_DATA = RDATA;
 | 
				
			||||||
 | 
							2:	assign PORT_R_RD_DATA = RDATA;
 | 
				
			||||||
 | 
							4:	assign PORT_R_RD_DATA[3:0] = RDATA;
 | 
				
			||||||
 | 
							5:	assign PORT_R_RD_DATA = RDATA;
 | 
				
			||||||
 | 
							8:	assign {
 | 
				
			||||||
 | 
								PORT_R_RD_DATA[8:5],
 | 
				
			||||||
 | 
								PORT_R_RD_DATA[3:0]
 | 
				
			||||||
 | 
							} = RDATA;
 | 
				
			||||||
 | 
							10:	assign PORT_R_RD_DATA = RDATA;
 | 
				
			||||||
 | 
							16:	assign {
 | 
				
			||||||
 | 
								PORT_R_RD_DATA[18:15],
 | 
				
			||||||
 | 
								PORT_R_RD_DATA[13:10],
 | 
				
			||||||
 | 
								PORT_R_RD_DATA[8:5],
 | 
				
			||||||
 | 
								PORT_R_RD_DATA[3:0]
 | 
				
			||||||
 | 
							} = RDATA;
 | 
				
			||||||
 | 
							20:	assign PORT_R_RD_DATA = RDATA;
 | 
				
			||||||
 | 
							endcase
 | 
				
			||||||
 | 
						endgenerate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function [255:0] init_slice;
 | 
				
			||||||
 | 
							input integer idx;
 | 
				
			||||||
 | 
							integer i;
 | 
				
			||||||
 | 
							if (IS_5BIT)
 | 
				
			||||||
 | 
								init_slice = INIT[idx * 256 +: 256];
 | 
				
			||||||
 | 
							else if (idx > 16)
 | 
				
			||||||
 | 
								init_slice = 0;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								for (i = 0; i < 64; i = i + 1)
 | 
				
			||||||
 | 
									init_slice[i*4+:4] = INIT[(idx * 64 + i) * 5+:4];
 | 
				
			||||||
 | 
						endfunction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	EFX_RAM_5K #(
 | 
						EFX_RAM_5K #(
 | 
				
			||||||
   		.READ_WIDTH(CFG_DBITS),
 | 
							.READ_WIDTH(READ_WIDTH),
 | 
				
			||||||
   		.WRITE_WIDTH(CFG_DBITS),
 | 
							.WRITE_WIDTH(WRITE_WIDTH),
 | 
				
			||||||
   		.OUTPUT_REG(1'b0),
 | 
							.OUTPUT_REG(1'b0),
 | 
				
			||||||
   		.RCLK_POLARITY(1'b1),
 | 
							.RCLK_POLARITY(PORT_R_CLK_POL),
 | 
				
			||||||
   		.RE_POLARITY(1'b1),
 | 
							.RE_POLARITY(1'b1),
 | 
				
			||||||
   		.WCLK_POLARITY(1'b1),
 | 
							.WCLK_POLARITY(PORT_W_CLK_POL),
 | 
				
			||||||
   		.WE_POLARITY(1'b1),
 | 
							.WE_POLARITY(1'b1),
 | 
				
			||||||
   		.WCLKE_POLARITY(1'b1),
 | 
							.WCLKE_POLARITY(1'b1),
 | 
				
			||||||
   		.WRITE_MODE(WRITEMODE_A),
 | 
							.WRITE_MODE(OPTION_WRITE_MODE),
 | 
				
			||||||
		.INIT_0(INIT[ 0*256 +: 256]),
 | 
							.INIT_0(init_slice('h00)),
 | 
				
			||||||
		.INIT_1(INIT[ 1*256 +: 256]),
 | 
							.INIT_1(init_slice('h01)),
 | 
				
			||||||
		.INIT_2(INIT[ 2*256 +: 256]),
 | 
							.INIT_2(init_slice('h02)),
 | 
				
			||||||
		.INIT_3(INIT[ 3*256 +: 256]),
 | 
							.INIT_3(init_slice('h03)),
 | 
				
			||||||
		.INIT_4(INIT[ 4*256 +: 256]),
 | 
							.INIT_4(init_slice('h04)),
 | 
				
			||||||
		.INIT_5(INIT[ 5*256 +: 256]),
 | 
							.INIT_5(init_slice('h05)),
 | 
				
			||||||
		.INIT_6(INIT[ 6*256 +: 256]),
 | 
							.INIT_6(init_slice('h06)),
 | 
				
			||||||
		.INIT_7(INIT[ 7*256 +: 256]),
 | 
							.INIT_7(init_slice('h07)),
 | 
				
			||||||
		.INIT_8(INIT[ 8*256 +: 256]),
 | 
							.INIT_8(init_slice('h08)),
 | 
				
			||||||
		.INIT_9(INIT[ 9*256 +: 256]),
 | 
							.INIT_9(init_slice('h09)),
 | 
				
			||||||
		.INIT_A(INIT[10*256 +: 256]),
 | 
							.INIT_A(init_slice('h0a)),
 | 
				
			||||||
		.INIT_B(INIT[11*256 +: 256]),
 | 
							.INIT_B(init_slice('h0b)),
 | 
				
			||||||
		.INIT_C(INIT[12*256 +: 256]),
 | 
							.INIT_C(init_slice('h0c)),
 | 
				
			||||||
		.INIT_D(INIT[13*256 +: 256]),
 | 
							.INIT_D(init_slice('h0d)),
 | 
				
			||||||
		.INIT_E(INIT[14*256 +: 256]),
 | 
							.INIT_E(init_slice('h0e)),
 | 
				
			||||||
		.INIT_F(INIT[15*256 +: 256]),
 | 
							.INIT_F(init_slice('h0f)),
 | 
				
			||||||
		.INIT_10(INIT[16*256 +: 256]),
 | 
							.INIT_10(init_slice('h10)),
 | 
				
			||||||
		.INIT_11(INIT[17*256 +: 256]),
 | 
							.INIT_11(init_slice('h11)),
 | 
				
			||||||
		.INIT_12(INIT[18*256 +: 256]),
 | 
							.INIT_12(init_slice('h12)),
 | 
				
			||||||
		.INIT_13(INIT[19*256 +: 256])
 | 
							.INIT_13(init_slice('h13)),
 | 
				
			||||||
	) _TECHMAP_REPLACE_ (
 | 
						) _TECHMAP_REPLACE_ (
 | 
				
			||||||
   		.WDATA(A1DATA),
 | 
							.WDATA(WDATA),
 | 
				
			||||||
   		.WADDR(A1ADDR),
 | 
							.WADDR(WADDR),
 | 
				
			||||||
   		.WE(A1EN),
 | 
							.WE(PORT_W_WR_EN),
 | 
				
			||||||
   		.WCLK(CLK2),
 | 
							.WCLK(PORT_W_CLK),
 | 
				
			||||||
   		.WCLKE(1'b1),
 | 
							.WCLKE(1'b1),
 | 
				
			||||||
   		.RDATA(B1DATA),
 | 
							.RDATA(RDATA),
 | 
				
			||||||
   		.RADDR(B1ADDR),
 | 
							.RADDR(RADDR),
 | 
				
			||||||
   		.RE(B1EN),
 | 
							.RE(PORT_R_RD_EN),
 | 
				
			||||||
   		.RCLK(CLK3)
 | 
							.RCLK(PORT_R_CLK)
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endmodule
 | 
					endmodule
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -158,11 +158,13 @@ struct SynthEfinixPass : public ScriptPass
 | 
				
			||||||
			run("synth -run coarse");
 | 
								run("synth -run coarse");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!nobram || check_label("map_bram", "(skip if -nobram)"))
 | 
							if (check_label("map_ram"))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			run("memory_bram -rules +/efinix/brams.txt");
 | 
								std::string args = "";
 | 
				
			||||||
 | 
								if (nobram)
 | 
				
			||||||
 | 
									args += " -no-auto-block";
 | 
				
			||||||
 | 
								run("memory_libmap -lib +/efinix/brams.txt" + args);
 | 
				
			||||||
			run("techmap -map +/efinix/brams_map.v");
 | 
								run("techmap -map +/efinix/brams_map.v");
 | 
				
			||||||
			run("setundef -zero -params t:EFX_RAM_5K");
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label("map_ffram"))
 | 
							if (check_label("map_ffram"))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,6 @@
 | 
				
			||||||
read_verilog ../common/lutram.v
 | 
					read_verilog ../common/lutram.v
 | 
				
			||||||
hierarchy -top lutram_1w1r
 | 
					hierarchy -top lutram_1w1r
 | 
				
			||||||
proc
 | 
					synth_efinix
 | 
				
			||||||
memory -nomap
 | 
					 | 
				
			||||||
equiv_opt -run :prove -map +/efinix/cells_sim.v synth_efinix
 | 
					 | 
				
			||||||
memory
 | 
					 | 
				
			||||||
opt -full
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
miter -equiv -flatten -make_assert -make_outputs gold gate miter
 | 
					 | 
				
			||||||
#ERROR: Called with -verify and proof did fail!
 | 
					 | 
				
			||||||
#sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter
 | 
					 | 
				
			||||||
sat -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
design -load postopt
 | 
					 | 
				
			||||||
cd lutram_1w1r
 | 
					cd lutram_1w1r
 | 
				
			||||||
select -assert-count 1 t:EFX_GBUFCE
 | 
					select -assert-count 1 t:EFX_GBUFCE
 | 
				
			||||||
select -assert-count 1 t:EFX_RAM_5K
 | 
					select -assert-count 1 t:EFX_RAM_5K
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue