Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add qlf_k4n8 plugin #85

Merged
merged 1 commit into from
Mar 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PLUGIN_LIST := fasm xdc params sdc ql-iob design_introspection integrateinv
PLUGIN_LIST := fasm xdc params sdc ql-iob design_introspection integrateinv ql-qlf-k4n8
PLUGINS := $(foreach plugin,$(PLUGIN_LIST),$(plugin).so)
PLUGINS_INSTALL := $(foreach plugin,$(PLUGIN_LIST),install_$(plugin))
PLUGINS_CLEAN := $(foreach plugin,$(PLUGIN_LIST),clean_$(plugin))
Expand Down
1 change: 1 addition & 0 deletions Makefile_plugin.common
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ CXXFLAGS = $(shell yosys-config --cxxflags) #-DSDC_DEBUG
LDFLAGS = $(shell yosys-config --ldflags)
LDLIBS = $(shell yosys-config --ldlibs)
PLUGINS_DIR = $(shell yosys-config --datdir)/plugins
DATA_DIR = $(shell yosys-config --datdir)

OBJS := $(SOURCES:cc=o)

Expand Down
10 changes: 10 additions & 0 deletions ql-qlf-k4n8-plugin/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
NAME = ql-qlf-k4n8
SOURCES = synth_quicklogic.cc
include ../Makefile_plugin.common

VERILOG_MODULES = cells_sim.v qlf_k4n8_arith_map.v qlf_k4n8_cells_sim.v

install_modules: $(VERILOG_MODULES)
$(foreach f,$^,install -D $(f) $(DATA_DIR)/quicklogic/$(f);)

install: install_modules
24 changes: 24 additions & 0 deletions ql-qlf-k4n8-plugin/cells_sim.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

module inv(output Q, input A);
assign Q = A ? 0 : 1;
endmodule

module buff(output Q, input A);
assign Q = A;
endmodule

module logic_0(output a);
assign a = 0;
endmodule

module logic_1(output a);
assign a = 1;
endmodule

(* blackbox *)
module gclkbuff (input A, output Z);

assign Z = A;

endmodule

135 changes: 135 additions & 0 deletions ql-qlf-k4n8-plugin/qlf_k4n8_arith_map.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
(* techmap_celltype = "$alu" *)
module _80_quicklogic_alu (A, B, CI, BI, X, Y, CO);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 1;
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;

parameter _TECHMAP_CONSTMSK_CI_ = 0;
parameter _TECHMAP_CONSTVAL_CI_ = 0;

(* force_downto *)
input [A_WIDTH-1:0] A;
(* force_downto *)
input [B_WIDTH-1:0] B;
(* force_downto *)
output [Y_WIDTH-1:0] X, Y;

input CI, BI;
(* force_downto *)
output [Y_WIDTH-1:0] CO;

wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;

(* force_downto *)
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));

(* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
(* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
(* force_downto *)
wire [Y_WIDTH-1:0] C;

assign CO = C[Y_WIDTH-1];

genvar i;
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice

wire ci;
wire co;

// First in chain
generate if (i == 0) begin

// CI connected to a constant
if (_TECHMAP_CONSTMSK_CI_ == 1) begin

localparam INIT = (_TECHMAP_CONSTVAL_CI_ == 0) ?
16'b0110_0000_0000_0001 :
16'b1001_0000_0000_0111;

// LUT4 configured as 1-bit adder with CI=const
adder_lut4 #(
.LUT(INIT),
.IN2_IS_CIN(1'b0)
) lut_ci_adder (
.in({AA[i], BB[i], 1'b0, 1'b0}),
.cin(),
.lut4_out(Y[i]),
.cout(ci)
);

// CI connected to a non-const driver
end else begin

// LUT4 configured as passthrough to drive CI of the next stage
adder_lut4 #(
.LUT(16'b1100_0000_0000_0011),
.IN2_IS_CIN(1'b0)
) lut_ci (
.in({1'b0,CI,1'b0,1'b0}),
.cin(),
.lut4_out(),
.cout(ci)
);
end

// Not first in chain
end else begin
assign ci = C[i-1];

end endgenerate

// ....................................................

// Single 1-bit adder, mid-chain adder or non-const CI
// adder
generate if ((i == 0 && _TECHMAP_CONSTMSK_CI_ == 0) || (i > 0)) begin

// LUT4 configured as full 1-bit adder
adder_lut4 #(
.LUT(16'b0110_1001_0110_0001),
.IN2_IS_CIN(1'b1)
) lut_adder (
.in({AA[i], BB[i], 1'b0, 1'b0}),
.cin(ci),
.lut4_out(Y[i]),
.cout(co)
);
end else begin
assign co = ci;

end endgenerate

// ....................................................

// Last in chain
generate if (i == Y_WIDTH-1) begin

// LUT4 configured for passing its CI input to output. This should
// get pruned if the actual CO port is not connected anywhere.
adder_lut4 #(
.LUT(16'b0000_1111_0000_1111),
.IN2_IS_CIN(1'b1)
) lut_co (
.in({1'b0, co, 1'b0, 1'b0}),
.cin(co),
.lut4_out(C[i]),
.cout()
);
// Not last in chain
end else begin
assign C[i] = co;

end endgenerate

end: slice
endgenerate

/* End implementation */
assign X = AA ^ BB;
endmodule
70 changes: 70 additions & 0 deletions ql-qlf-k4n8-plugin/qlf_k4n8_cells_sim.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
(* abc9_box, lib_whitebox *)
module adder_lut4(
output lut4_out,
(* abc9_carry *)
output cout,
input [0:3] in,
(* abc9_carry *)
input cin
);
parameter [0:15] LUT=0;
parameter IN2_IS_CIN = 0;

wire [0:3] li = (IN2_IS_CIN) ? {in[0], in[1], cin, in[3]} : {in[0], in[1], in[2], in[3]};

// Output function
wire [0:7] s1 = li[0] ?
{LUT[1], LUT[3], LUT[5], LUT[7], LUT[9], LUT[11], LUT[13], LUT[15]}:
{LUT[0], LUT[2], LUT[4], LUT[6], LUT[8], LUT[10], LUT[12], LUT[14]};

wire [0:3] s2 = li[1] ? {s1[1], s1[3], s1[5], s1[7]} :
{s1[0], s1[2], s1[4], s1[6]};

wire [0:1] s3 = li[2] ? {s2[1], s2[3]} : {s2[0], s2[2]};

assign lut4_out = li[3] ? s3[1] : s3[0];

// Carry out function
assign cout = (s2[2]) ? cin : s2[3];
endmodule

(* abc9_lut=1, lib_whitebox *)
module frac_lut4(
input [0:3] in,
output [0:1] lut2_out,
output lut4_out
);
parameter [0:15] LUT = 0;

// Effective LUT input
wire [0:3] li = in;

// Output function
wire [0:7] s1 = li[0] ?
{LUT[1], LUT[3], LUT[5], LUT[7], LUT[9], LUT[11], LUT[13], LUT[15]}:
{LUT[0], LUT[2], LUT[4], LUT[6], LUT[8], LUT[10], LUT[12], LUT[14]};

wire [0:3] s2 = li[1] ? {s1[1], s1[3], s1[5], s1[7]} :
{s1[0], s1[2], s1[4], s1[6]};

wire [0:1] s3 = li[2] ? {s2[1], s2[3]} : {s2[0], s2[2]};

assign lut2_out[0] = s2[2];
assign lut2_out[1] = s2[3];

assign lut4_out = li[3] ? s3[1] : s3[0];

endmodule

(* abc9_flop, lib_whitebox *)
module scff(
output reg Q,
input D,
input clk
);
parameter [0:0] INIT = 1'b0;
initial Q = INIT;

always @(posedge clk)
Q <= D;
endmodule
Loading