diff options
Diffstat (limited to 'techlibs/efinix')
| -rw-r--r-- | techlibs/efinix/brams.txt | 51 | ||||
| -rw-r--r-- | techlibs/efinix/brams_map.v | 194 | ||||
| -rw-r--r-- | techlibs/efinix/synth_efinix.cc | 8 | 
3 files changed, 163 insertions, 90 deletions
diff --git a/techlibs/efinix/brams.txt b/techlibs/efinix/brams.txt index 0b3fd9308..271fc4fc4 100644 --- a/techlibs/efinix/brams.txt +++ b/techlibs/efinix/brams.txt @@ -1,32 +1,19 @@ -bram $__EFINIX_5K -  init 1 - -  abits 8  @a8d16 -  dbits 16 @a8d16 -  abits 9  @a9d8 -  dbits 8  @a9d8 -  abits 10 @a10d4 -  dbits 4  @a10d4 -  abits 11 @a11d2 -  dbits 2  @a11d2 -  abits 12 @a12d1 -  dbits 1  @a12d1 -  abits 8  @a8d20 -  dbits 20 @a8d20 -  abits 9  @a9d10 -  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 +ram block $__EFINIX_5K_ { +	abits 12; +	widths 1 2 5 10 20 per_port; +	cost 32; +	init no_undef; +	port sr "R" { +		clock anyedge; +		rden; +	} +	port sw "W" { +		clock anyedge; +		option "WRITE_MODE" "READ_FIRST" { +			wrtrans "R" old; +		} +		option "WRITE_MODE" "WRITE_FIRST" { +			wrtrans "R" new; +		} +	} +} diff --git a/techlibs/efinix/brams_map.v b/techlibs/efinix/brams_map.v index 6786ae769..752010f45 100644 --- a/techlibs/efinix/brams_map.v +++ b/techlibs/efinix/brams_map.v @@ -1,65 +1,149 @@ -module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); -	parameter CFG_ABITS = 8; -	parameter CFG_DBITS = 20; -	parameter CFG_ENABLE_A = 1; +module $__EFINIX_5K_ (...); +	parameter INIT = 0; +	parameter OPTION_WRITE_MODE = "READ_FIRST"; -	parameter CLKPOL2 = 1; -	parameter CLKPOL3 = 1; -	parameter [5119:0] INIT = 5119'bx; -	parameter TRANSP2 = 0; +	parameter PORT_R_WIDTH = 20; +	parameter PORT_R_CLK_POL = 1; +	parameter PORT_W_WIDTH = 20; +	parameter PORT_W_CLK_POL = 1; -	input CLK2; -	input CLK3; +	input PORT_R_CLK; +	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 [CFG_DBITS-1:0] A1DATA; -	input [CFG_ENABLE_A-1:0] A1EN; +	input PORT_W_CLK; +	input PORT_W_WR_EN; +	input [11:0] PORT_W_ADDR; +	input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; -	input [CFG_ABITS-1:0] B1ADDR; -	output [CFG_DBITS-1:0] B1DATA; -	input B1EN; +	localparam IS_5BIT = PORT_R_WIDTH >= 5 && PORT_W_WIDTH >= 5; -	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 #( -   		.READ_WIDTH(CFG_DBITS), -   		.WRITE_WIDTH(CFG_DBITS), -   		.OUTPUT_REG(1'b0), -   		.RCLK_POLARITY(1'b1), -   		.RE_POLARITY(1'b1), -   		.WCLK_POLARITY(1'b1), -   		.WE_POLARITY(1'b1), -   		.WCLKE_POLARITY(1'b1), -   		.WRITE_MODE(WRITEMODE_A), -		.INIT_0(INIT[ 0*256 +: 256]), -		.INIT_1(INIT[ 1*256 +: 256]), -		.INIT_2(INIT[ 2*256 +: 256]), -		.INIT_3(INIT[ 3*256 +: 256]), -		.INIT_4(INIT[ 4*256 +: 256]), -		.INIT_5(INIT[ 5*256 +: 256]), -		.INIT_6(INIT[ 6*256 +: 256]), -		.INIT_7(INIT[ 7*256 +: 256]), -		.INIT_8(INIT[ 8*256 +: 256]), -		.INIT_9(INIT[ 9*256 +: 256]), -		.INIT_A(INIT[10*256 +: 256]), -		.INIT_B(INIT[11*256 +: 256]), -		.INIT_C(INIT[12*256 +: 256]), -		.INIT_D(INIT[13*256 +: 256]), -		.INIT_E(INIT[14*256 +: 256]), -		.INIT_F(INIT[15*256 +: 256]), -		.INIT_10(INIT[16*256 +: 256]), -		.INIT_11(INIT[17*256 +: 256]), -		.INIT_12(INIT[18*256 +: 256]), -		.INIT_13(INIT[19*256 +: 256]) +		.READ_WIDTH(READ_WIDTH), +		.WRITE_WIDTH(WRITE_WIDTH), +		.OUTPUT_REG(1'b0), +		.RCLK_POLARITY(PORT_R_CLK_POL), +		.RE_POLARITY(1'b1), +		.WCLK_POLARITY(PORT_W_CLK_POL), +		.WE_POLARITY(1'b1), +		.WCLKE_POLARITY(1'b1), +		.WRITE_MODE(OPTION_WRITE_MODE), +		.INIT_0(init_slice('h00)), +		.INIT_1(init_slice('h01)), +		.INIT_2(init_slice('h02)), +		.INIT_3(init_slice('h03)), +		.INIT_4(init_slice('h04)), +		.INIT_5(init_slice('h05)), +		.INIT_6(init_slice('h06)), +		.INIT_7(init_slice('h07)), +		.INIT_8(init_slice('h08)), +		.INIT_9(init_slice('h09)), +		.INIT_A(init_slice('h0a)), +		.INIT_B(init_slice('h0b)), +		.INIT_C(init_slice('h0c)), +		.INIT_D(init_slice('h0d)), +		.INIT_E(init_slice('h0e)), +		.INIT_F(init_slice('h0f)), +		.INIT_10(init_slice('h10)), +		.INIT_11(init_slice('h11)), +		.INIT_12(init_slice('h12)), +		.INIT_13(init_slice('h13)),  	) _TECHMAP_REPLACE_ ( -   		.WDATA(A1DATA), -   		.WADDR(A1ADDR), -   		.WE(A1EN), -   		.WCLK(CLK2), -   		.WCLKE(1'b1), -   		.RDATA(B1DATA), -   		.RADDR(B1ADDR), -   		.RE(B1EN), -   		.RCLK(CLK3) +		.WDATA(WDATA), +		.WADDR(WADDR), +		.WE(PORT_W_WR_EN), +		.WCLK(PORT_W_CLK), +		.WCLKE(1'b1), +		.RDATA(RDATA), +		.RADDR(RADDR), +		.RE(PORT_R_RD_EN), +		.RCLK(PORT_R_CLK)  	); +  endmodule diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index ace56bee9..bbc389444 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -158,11 +158,13 @@ struct SynthEfinixPass : public ScriptPass  			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("setundef -zero -params t:EFX_RAM_5K");  		}  		if (check_label("map_ffram"))  | 
