Skip to content

Commit b50a0f2

Browse files
authored
Merge pull request #1 from lnsharma/add_qlf_k4n8_dev
Adding qlf_k4n8 device support to yosys
2 parents 40d9e12 + ab89e91 commit b50a0f2

File tree

16 files changed

+674
-0
lines changed

16 files changed

+674
-0
lines changed

techlibs/quicklogic/Makefile.inc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
OBJS += techlibs/quicklogic/synth_quicklogic.o
3+
4+
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/cells_sim.v))
5+
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/qlf_k4n8_cells_sim.v))
6+
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/qlf_k4n8_arith_map.v))
7+

techlibs/quicklogic/cells_sim.v

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
module inv(output Q, input A);
3+
assign Q = A ? 0 : 1;
4+
endmodule
5+
6+
module buff(output Q, input A);
7+
assign Q = A;
8+
endmodule
9+
10+
module logic_0(output a);
11+
assign a = 0;
12+
endmodule
13+
14+
module logic_1(output a);
15+
assign a = 1;
16+
endmodule
17+
18+
(* blackbox *)
19+
module gclkbuff (input A, output Z);
20+
21+
assign Z = A;
22+
23+
endmodule
24+
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
(* techmap_celltype = "$alu" *)
2+
module _80_quicklogic_alu (A, B, CI, BI, X, Y, CO);
3+
parameter A_SIGNED = 0;
4+
parameter B_SIGNED = 0;
5+
parameter A_WIDTH = 1;
6+
parameter B_WIDTH = 1;
7+
parameter Y_WIDTH = 1;
8+
9+
parameter _TECHMAP_CONSTMSK_CI_ = 0;
10+
parameter _TECHMAP_CONSTVAL_CI_ = 0;
11+
12+
(* force_downto *)
13+
input [A_WIDTH-1:0] A;
14+
(* force_downto *)
15+
input [B_WIDTH-1:0] B;
16+
(* force_downto *)
17+
output [Y_WIDTH-1:0] X, Y;
18+
19+
input CI, BI;
20+
(* force_downto *)
21+
output [Y_WIDTH-1:0] CO;
22+
23+
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
24+
25+
(* force_downto *)
26+
wire [Y_WIDTH-1:0] A_buf, B_buf;
27+
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
28+
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
29+
30+
(* force_downto *)
31+
wire [Y_WIDTH-1:0] AA = A_buf;
32+
(* force_downto *)
33+
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
34+
(* force_downto *)
35+
wire [Y_WIDTH-1:0] C;
36+
37+
assign CO = C[Y_WIDTH-1];
38+
39+
genvar i;
40+
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice
41+
42+
wire ci;
43+
wire co;
44+
45+
// First in chain
46+
generate if (i == 0) begin
47+
48+
// CI connected to a constant
49+
if (_TECHMAP_CONSTMSK_CI_ == 1) begin
50+
51+
localparam INIT = (_TECHMAP_CONSTVAL_CI_ == 0) ?
52+
16'b0110_0000_0000_0001 :
53+
16'b1001_0000_0000_0111;
54+
55+
// LUT4 configured as 1-bit adder with CI=const
56+
adder_lut4 #(
57+
.LUT(INIT),
58+
.IN2_IS_CIN(1'b0)
59+
) lut_ci_adder (
60+
.in({AA[i], BB[i], 1'b0, 1'b0}),
61+
.cin(),
62+
.lut4_out(Y[i]),
63+
.cout(ci)
64+
);
65+
66+
// CI connected to a non-const driver
67+
end else begin
68+
69+
// LUT4 configured as passthrough to drive CI of the next stage
70+
adder_lut4 #(
71+
.LUT(16'b1100_0000_0000_0011),
72+
.IN2_IS_CIN(1'b0)
73+
) lut_ci (
74+
.in({1'b0,CI,1'b0,1'b0}),
75+
.cin(),
76+
.lut4_out(),
77+
.cout(ci)
78+
);
79+
end
80+
81+
// Not first in chain
82+
end else begin
83+
assign ci = C[i-1];
84+
85+
end endgenerate
86+
87+
// ....................................................
88+
89+
// Single 1-bit adder, mid-chain adder or non-const CI
90+
// adder
91+
generate if ((i == 0 && _TECHMAP_CONSTMSK_CI_ == 0) || (i > 0)) begin
92+
93+
// LUT4 configured as full 1-bit adder
94+
adder_lut4 #(
95+
.LUT(16'b0110_1001_0110_0001),
96+
.IN2_IS_CIN(1'b1)
97+
) lut_adder (
98+
.in({AA[i], BB[i], 1'b0, 1'b0}),
99+
.cin(ci),
100+
.lut4_out(Y[i]),
101+
.cout(co)
102+
);
103+
end else begin
104+
assign co = ci;
105+
106+
end endgenerate
107+
108+
// ....................................................
109+
110+
// Last in chain
111+
generate if (i == Y_WIDTH-1) begin
112+
113+
// LUT4 configured for passing its CI input to output. This should
114+
// get pruned if the actual CO port is not connected anywhere.
115+
adder_lut4 #(
116+
.LUT(16'b0000_1111_0000_1111),
117+
.IN2_IS_CIN(1'b1)
118+
) lut_co (
119+
.in({1'b0, co, 1'b0, 1'b0}),
120+
.cin(co),
121+
.lut4_out(C[i]),
122+
.cout()
123+
);
124+
// Not last in chain
125+
end else begin
126+
assign C[i] = co;
127+
128+
end endgenerate
129+
130+
end: slice
131+
endgenerate
132+
133+
/* End implementation */
134+
assign X = AA ^ BB;
135+
endmodule
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
(* abc9_box, lib_whitebox *)
2+
module adder_lut4(
3+
output lut4_out,
4+
(* abc9_carry *)
5+
output cout,
6+
input [0:3] in,
7+
(* abc9_carry *)
8+
input cin
9+
);
10+
parameter [0:15] LUT=0;
11+
parameter IN2_IS_CIN = 0;
12+
13+
wire [0:3] li = (IN2_IS_CIN) ? {in[0], in[1], cin, in[3]} : {in[0], in[1], in[2], in[3]};
14+
15+
// Output function
16+
wire [0:7] s1 = li[0] ?
17+
{LUT[1], LUT[3], LUT[5], LUT[7], LUT[9], LUT[11], LUT[13], LUT[15]}:
18+
{LUT[0], LUT[2], LUT[4], LUT[6], LUT[8], LUT[10], LUT[12], LUT[14]};
19+
20+
wire [0:3] s2 = li[1] ? {s1[1], s1[3], s1[5], s1[7]} :
21+
{s1[0], s1[2], s1[4], s1[6]};
22+
23+
wire [0:1] s3 = li[2] ? {s2[1], s2[3]} : {s2[0], s2[2]};
24+
25+
assign lut4_out = li[3] ? s3[1] : s3[0];
26+
27+
// Carry out function
28+
assign cout = (s2[2]) ? cin : s2[3];
29+
endmodule
30+
31+
(* abc9_lut=1, lib_whitebox *)
32+
module frac_lut4(
33+
input [0:3] in,
34+
output [0:1] lut2_out,
35+
output lut4_out
36+
);
37+
parameter [0:15] LUT = 0;
38+
39+
// Effective LUT input
40+
wire [0:3] li = in;
41+
42+
// Output function
43+
wire [0:7] s1 = li[0] ?
44+
{LUT[1], LUT[3], LUT[5], LUT[7], LUT[9], LUT[11], LUT[13], LUT[15]}:
45+
{LUT[0], LUT[2], LUT[4], LUT[6], LUT[8], LUT[10], LUT[12], LUT[14]};
46+
47+
wire [0:3] s2 = li[1] ? {s1[1], s1[3], s1[5], s1[7]} :
48+
{s1[0], s1[2], s1[4], s1[6]};
49+
50+
wire [0:1] s3 = li[2] ? {s2[1], s2[3]} : {s2[0], s2[2]};
51+
52+
assign lut2_out[0] = s2[2];
53+
assign lut2_out[1] = s2[3];
54+
55+
assign lut4_out = li[3] ? s3[1] : s3[0];
56+
57+
endmodule
58+
59+
(* abc9_flop, lib_whitebox *)
60+
module scff(
61+
output reg Q,
62+
input D,
63+
input clk
64+
);
65+
parameter [0:0] INIT = 1'b0;
66+
initial Q = INIT;
67+
68+
always @(posedge clk)
69+
Q <= D;
70+
endmodule

0 commit comments

Comments
 (0)