yosys/techlibs/machxo2/cells_sim.v

386 lines
12 KiB
Verilog

module LUT2(input A, B, output Z);
parameter [3:0] INIT = 4'h0;
wire [1:0] s1 = B ? INIT[ 3:2] : INIT[1:0];
assign Z = A ? s1[1] : s1[0];
endmodule
module LUT4 #(
parameter [15:0] INIT = 0
) (
input A, B, C, D,
output Z
);
// This form of LUT propagates as few x's as possible.
wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0];
wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0];
wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0];
assign Z = A ? s1[1] : s1[0];
endmodule
module TRELLIS_FF #(
parameter GSR = "ENABLED",
parameter CEMUX = "1",
parameter CLKMUX = "0",
parameter LSRMUX = "LSR",
parameter LSRONMUX = "LSRMUX",
parameter SRMODE = "LSR_OVER_CE",
parameter REGSET = "SET",
parameter REGMODE = "FF"
) (
input CLK, DI, LSR, CE,
output reg Q
);
wire muxce;
generate
case (CEMUX)
"1": assign muxce = 1'b1;
"0": assign muxce = 1'b0;
"INV": assign muxce = ~CE;
default: assign muxce = CE;
endcase
endgenerate
wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR;
wire muxlsron = (LSRONMUX == "LSRMUX") ? muxlsr : 1'b0;
wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK;
wire srval = (REGSET == "SET") ? 1'b1 : 1'b0;
initial Q = srval;
generate
if (REGMODE == "FF") begin
if (SRMODE == "ASYNC") begin
always @(posedge muxclk, posedge muxlsron)
if (muxlsron)
Q <= srval;
else if (muxce)
Q <= DI;
end else begin
always @(posedge muxclk)
if (muxlsron)
Q <= srval;
else if (muxce)
Q <= DI;
end
end else if (REGMODE == "LATCH") begin
ERROR_UNSUPPORTED_FF_MODE error();
end else begin
ERROR_UNKNOWN_FF_MODE error();
end
endgenerate
endmodule
/* For consistency with ECP5; represents F0/F1 => OFX0 mux in a slice. */
module PFUMX (input ALUT, BLUT, C0, output Z);
assign Z = C0 ? ALUT : BLUT;
endmodule
/* For consistency with ECP5; represents FXA/FXB => OFX1 mux in a slice. */
module L6MUX21 (input D0, D1, SD, output Z);
assign Z = SD ? D1 : D0;
endmodule
/* For consistency, input order matches TRELLIS_SLICE even though the BELs in
prjtrellis were filled in clockwise order from bottom left. */
module TRELLIS_SLICE #(
parameter MODE = "LOGIC",
parameter GSR = "ENABLED",
parameter SRMODE = "LSR_OVER_CE",
parameter CEMUX = "1",
parameter CLKMUX = "0",
parameter LSRMUX = "LSR",
parameter LSRONMUX = "LSRMUX",
parameter LUT0_INITVAL = 16'hFFFF,
parameter LUT1_INITVAL = 16'hFFFF,
parameter REGMODE = "FF",
parameter REG0_SD = "1",
parameter REG1_SD = "1",
parameter REG0_REGSET = "SET",
parameter REG1_REGSET = "SET",
parameter CCU2_INJECT1_0 = "YES",
parameter CCU2_INJECT1_1 = "YES",
parameter WREMUX = "INV"
) (
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
);
generate
if (MODE == "LOGIC") begin
L6MUX21 FXMUX (.D0(FXA), .D1(FXB), .SD(M1), .Z(OFX1));
wire k0;
wire k1;
PFUMX K0K1MUX (.ALUT(k1), .BLUT(k0), .C0(M0), .Z(OFX0));
LUT4 #(.INIT(LUT0_INITVAL)) LUT_0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k0));
LUT4 #(.INIT(LUT1_INITVAL)) LUT_1 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k1));
assign F0 = k0;
assign F1 = k1;
end else if (MODE == "CCU2") begin
ERROR_UNSUPPORTED_SLICE_MODE error();
end else if (MODE == "DPRAM") begin
ERROR_UNSUPPORTED_SLICE_MODE error();
end else begin
ERROR_UNKNOWN_SLICE_MODE error();
end
endgenerate
/* Reg can be fed either by M, or DI inputs; DI inputs muxes OFX and F
outputs (in other words, feeds back into TRELLIS_SLICE). */
wire di0 = (REG0_SD == "1") ? DI0 : M0;
wire di1 = (REG1_SD == "1") ? DI1 : M1;
TRELLIS_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX),
.LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG0_REGSET),
.REGMODE(REGMODE)) REG_0 (.CLK(CLK), .DI(di0), .LSR(LSR), .CE(CE), .Q(Q0));
TRELLIS_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX),
.LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG1_REGSET),
.REGMODE(REGMODE)) REG_1 (.CLK(CLK), .DI(di1), .LSR(LSR), .CE(CE), .Q(Q1));
endmodule
module TRELLIS_IO #(
parameter DIR = "INPUT"
) (
(* iopad_external_pin *)
inout B,
input I, T,
output O
);
generate
if (DIR == "INPUT") begin
assign O = B;
end else if (DIR == "OUTPUT") begin
assign B = T ? 1'bz : I;
end else if (DIR == "BIDIR") begin
assign B = T ? 1'bz : I;
assign O = B;
end else begin
ERROR_UNKNOWN_IO_MODE error();
end
endgenerate
endmodule
(* abc9_box, lib_whitebox *)
module TRELLIS_DPR16X4 (
input [3:0] DI,
input [3:0] WAD,
input WRE,
input WCK,
input [3:0] RAD,
output [3:0] DO
);
parameter WCKMUX = "WCK";
parameter WREMUX = "WRE";
parameter [63:0] INITVAL = 64'h0000000000000000;
reg [3:0] mem[15:0];
integer i;
initial begin
for (i = 0; i < 16; i = i + 1)
mem[i] <= INITVAL[4*i +: 4];
end
wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK;
reg muxwre;
always @(*)
case (WREMUX)
"1": muxwre = 1'b1;
"0": muxwre = 1'b0;
"INV": muxwre = ~WRE;
default: muxwre = WRE;
endcase
always @(posedge muxwck)
if (muxwre)
mem[WAD] <= DI;
assign DO = mem[RAD];
specify
// TODO
(RAD *> DO) = 0;
endspecify
endmodule
(* abc9_box, lib_whitebox *)
module DPR16X4C (
input [3:0] DI,
input WCK, WRE,
input [3:0] RAD,
input [3:0] WAD,
output [3:0] DO
);
parameter INITVAL = "0x0000000000000000";
function [63:0] convert_initval;
input [143:0] hex_initval;
reg done;
reg [63:0] temp;
reg [7:0] char;
integer i;
begin
done = 1'b0;
temp = 0;
for (i = 0; i < 16; i = i + 1) begin
if (!done) begin
char = hex_initval[8*i +: 8];
if (char == "x") begin
done = 1'b1;
end else begin
if (char >= "0" && char <= "9")
temp[4*i +: 4] = char - "0";
else if (char >= "A" && char <= "F")
temp[4*i +: 4] = 10 + char - "A";
else if (char >= "a" && char <= "f")
temp[4*i +: 4] = 10 + char - "a";
end
end
end
convert_initval = temp;
end
endfunction
localparam conv_initval = convert_initval(INITVAL);
reg [3:0] ram[0:15];
integer i;
initial begin
for (i = 0; i < 15; i = i + 1) begin
ram[i] <= conv_initval[4*i +: 4];
end
end
always @(posedge WCK)
if (WRE)
ram[WAD] <= DI;
assign DO = ram[RAD];
endmodule
// ---------------------------------------
(* lib_whitebox *)
module CCU2D (
input CIN,
input A0, B0, C0, D0, A1, B1, C1, D1,
output S0, S1,
output COUT
);
parameter [15:0] INIT0 = 16'h0000;
parameter [15:0] INIT1 = 16'h0000;
parameter INJECT1_0 = "YES";
parameter INJECT1_1 = "YES";
// First half
wire LUT4_0, LUT2_0;
LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0));
LUT2 #(.INIT(~INIT0[15:12])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0));
wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN;
assign S0 = LUT4_0 ^ gated_cin_0;
wire gated_lut2_0 = (INJECT1_0 == "YES") ? 1'b0 : LUT2_0;
wire cout_0 = (~LUT4_0 & gated_lut2_0) | (LUT4_0 & CIN);
// Second half
wire LUT4_1, LUT2_1;
LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1));
LUT2 #(.INIT(~INIT1[15:12])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1));
wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0;
assign S1 = LUT4_1 ^ gated_cin_1;
wire gated_lut2_1 = (INJECT1_1 == "YES") ? 1'b0 : LUT2_1;
assign COUT = (~LUT4_1 & gated_lut2_1) | (LUT4_1 & cout_0);
endmodule
(* blackbox *)
module DP8KC(
input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0,
input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0,
input CEA, OCEA, CLKA, WEA, RSTA,
input CSA2, CSA1, CSA0,
output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0,
input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0,
input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0,
input CEB, OCEB, CLKB, WEB, RSTB,
input CSB2, CSB1, CSB0,
output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0
);
parameter DATA_WIDTH_A = 9;
parameter DATA_WIDTH_B = 9;
parameter REGMODE_A = "NOREG";
parameter REGMODE_B = "NOREG";
parameter RESETMODE = "SYNC";
parameter ASYNC_RESET_RELEASE = "SYNC";
parameter CSDECODE_A = "0b000";
parameter CSDECODE_B = "0b000";
parameter WRITEMODE_A = "NORMAL";
parameter WRITEMODE_B = "NORMAL";
parameter GSR = "ENABLED";
parameter INIT_DATA = "STATIC";
parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
endmodule
`ifndef NO_INCLUDES
`include "cells_io.vh"
`endif