| `include "../../primitives/slice/CCU2C/CCU2C.sim.v" | 
 | `include "../../primitives/slice/L6MUX21/L6MUX21.sim.v" | 
 | `include "../../primitives/slice/LUT4/LUT4.sim.v" | 
 | `include "../../primitives/slice/PFUMX/PFUMX.sim.v" | 
 | `include "../../primitives/slice/TRELLIS_FF/TRELLIS_FF.sim.v" | 
 | `include "../../primitives/slice/TRELLIS_RAM16X2/TRELLIS_RAM16X2.sim.v" | 
 |  | 
 | `default_nettype none | 
 | module TRELLIS_SLICE( | 
 | 	input A0, B0, C0, D0, | 
 | 	input A1, B1, C1, D1, | 
 | 	input M0, M1, | 
 | 	input FCI, FXA, FXB, | 
 |  | 
 | 	input CLK, LSR, CE, | 
 | 	input DI0, DI1, | 
 |  | 
 | 	input WD0, WD1, | 
 | 	input WAD0, WAD1, WAD2, WAD3, | 
 | 	input WRE, WCK, | 
 |  | 
 | 	output F0, Q0, | 
 | 	output F1, Q1, | 
 | 	output FCO, OFX0, OFX1, | 
 |  | 
 | 	output WDO0, WDO1, WDO2, WDO3, | 
 | 	output WADO0, WADO1, WADO2, WADO3 | 
 | ); | 
 |  | 
 | 	parameter MODE = "LOGIC"; | 
 | 	parameter GSR = "ENABLED"; | 
 | 	parameter SRMODE = "LSR_OVER_CE"; | 
 | 	parameter [127:0] CEMUX = "1"; | 
 | 	parameter CLKMUX = "CLK"; | 
 | 	parameter LSRMUX = "LSR"; | 
 | 	parameter LUT0_INITVAL = 16'h0000; | 
 | 	parameter LUT1_INITVAL = 16'h0000; | 
 | 	parameter REG0_SD = "0"; | 
 | 	parameter REG1_SD = "0"; | 
 | 	parameter REG0_REGSET = "RESET"; | 
 | 	parameter REG1_REGSET = "RESET"; | 
 | 	parameter [127:0] CCU2_INJECT1_0 = "NO"; | 
 | 	parameter [127:0] CCU2_INJECT1_1 = "NO"; | 
 | 	parameter WREMUX = "WRE"; | 
 |  | 
 | 	function [15:0] permute_initval; | 
 | 		input [15:0] initval; | 
 | 		integer i; | 
 | 		begin | 
 | 			for (i = 0; i < 16; i = i + 1) begin | 
 | 				permute_initval[{i[0], i[2], i[1], i[3]}] = initval[i]; | 
 | 			end | 
 | 		end | 
 | 	endfunction | 
 |  | 
 | 	generate | 
 | 		if (MODE == "LOGIC") begin | 
 | 			// LUTs | 
 | 			LUT4 #( | 
 | 				.INIT(LUT0_INITVAL) | 
 | 			) lut4_0 ( | 
 | 				.A(A0), .B(B0), .C(C0), .D(D0), | 
 | 				.Z(F0) | 
 | 			); | 
 | 			LUT4 #( | 
 | 				.INIT(LUT1_INITVAL) | 
 | 			) lut4_1 ( | 
 | 				.A(A1), .B(B1), .C(C1), .D(D1), | 
 | 				.Z(F1) | 
 | 			); | 
 | 			// LUT expansion muxes | 
 | 			PFUMX lut5_mux (.ALUT(F1), .BLUT(F0), .C0(M0), .Z(OFX0)); | 
 | 			L6MUX21 lutx_mux (.D0(FXA), .D1(FXB), .SD(M1), .Z(OFX1)); | 
 | 		end else if (MODE == "CCU2") begin | 
 | 			CCU2C #( | 
 | 				.INIT0(LUT0_INITVAL), | 
 | 				.INIT1(LUT1_INITVAL), | 
 | 				.INJECT1_0(CCU2_INJECT1_0), | 
 | 				.INJECT1_1(CCU2_INJECT1_1) | 
 | 		  ) ccu2c_i ( | 
 | 				.CIN(FCI), | 
 | 				.A0(A0), .B0(B0), .C0(C0), .D0(D0), | 
 | 				.A1(A1), .B1(B1), .C1(C1), .D1(D1), | 
 | 				.S0(F0), .S1(F1), | 
 | 				.COUT(FCO) | 
 | 			); | 
 | 		end else if (MODE == "RAMW") begin | 
 | 			assign WDO0 = C1; | 
 | 			assign WDO1 = A1; | 
 | 			assign WDO2 = D1; | 
 | 			assign WDO3 = B1; | 
 | 			assign WADO0 = D0; | 
 | 			assign WADO1 = B0; | 
 | 			assign WADO2 = C0; | 
 | 			assign WADO3 = A0; | 
 | 		end else if (MODE == "DPRAM") begin | 
 | 			TRELLIS_RAM16X2 #( | 
 | 				.INITVAL_0(permute_initval(LUT0_INITVAL)), | 
 | 				.INITVAL_1(permute_initval(LUT1_INITVAL)), | 
 | 				.WREMUX(WREMUX) | 
 | 			) ram_i ( | 
 | 				.DI0(WD0), .DI1(WD1), | 
 | 				.WAD0(WAD0), .WAD1(WAD1), .WAD2(WAD2), .WAD3(WAD3), | 
 | 				.WRE(WRE), .WCK(WCK), | 
 | 				.RAD0(D0), .RAD1(B0), .RAD2(C0), .RAD3(A0), | 
 | 				.DO0(F0), .DO1(F1) | 
 | 			); | 
 | 			// TODO: confirm RAD and INITVAL ordering | 
 | 			// DPRAM mode contract? | 
 | 			always @(*) begin | 
 | 				assert(A0==A1); | 
 | 				assert(B0==B1); | 
 | 				assert(C0==C1); | 
 | 				assert(D0==D1); | 
 | 			end | 
 | 		end else begin | 
 | 			ERROR_UNKNOWN_SLICE_MODE error(); | 
 | 		end | 
 | 	endgenerate | 
 |  | 
 | 	// FF input selection muxes | 
 | 	wire muxdi0 = (REG0_SD == "1") ? DI0 : M0; | 
 | 	wire muxdi1 = (REG1_SD == "1") ? DI1 : M1; | 
 | 	// Flipflops | 
 | 	TRELLIS_FF #( | 
 | 		.GSR(GSR), | 
 | 		.CEMUX(CEMUX), | 
 | 		.CLKMUX(CLKMUX), | 
 | 		.LSRMUX(LSRMUX), | 
 | 		.SRMODE(SRMODE), | 
 | 		.REGSET(REG0_REGSET) | 
 | 	) ff_0 ( | 
 | 		.CLK(CLK), .LSR(LSR), .CE(CE), | 
 | 		.DI(muxdi0), | 
 | 		.Q(Q0) | 
 | 	); | 
 | 	TRELLIS_FF #( | 
 | 		.GSR(GSR), | 
 | 		.CEMUX(CEMUX), | 
 | 		.CLKMUX(CLKMUX), | 
 | 		.LSRMUX(LSRMUX), | 
 | 		.SRMODE(SRMODE), | 
 | 		.REGSET(REG1_REGSET) | 
 | 	) ff_1 ( | 
 | 		.CLK(CLK), .LSR(LSR), .CE(CE), | 
 | 		.DI(muxdi1), | 
 | 		.Q(Q1) | 
 | 	); | 
 | endmodule |