blob: d292f066e8785dda319f4f5a8dcb438c85a1209c [file] [log] [blame] [edit]
`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