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 support for QuickLogic devices #89

Open
wants to merge 76 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
ab4987c
Initial synth_quicklogic implementation
glatosinski Nov 25, 2019
c140242
added ram, fifo and multiplier macros
rakeshm75 Jul 1, 2020
4421f1b
Adding -family option in synth_quicklogic option
Jul 9, 2020
a4fd9d0
Updating cells map & sim files for pp3
Jul 10, 2020
39275d2
Updating ap3 device support in yosys
Jul 10, 2020
bd445fc
Adding RAM/DSP as blackbox
Jul 10, 2020
6683abe
LUT optimizations
kgugala Jul 12, 2020
68cd7ff
Updating LUT1,2,3 cell mapping to LUT4
Jul 13, 2020
e526ffa
Adding io_reg related primitives
Jul 15, 2020
9d6fa6d
Update ap3_cells_sim.v
kkumar23 Jul 15, 2020
62bce45
Adding adder support in ap3
Jul 27, 2020
c608a38
Added techmaps for DFFE, split LUT and FF techmaps into separate files.
mkurc-ant Jul 28, 2020
9840346
Updated the synth_quicklogic pass.
mkurc-ant Jul 28, 2020
8bea714
Adder support in AP3
Jul 28, 2020
cf85873
Adder implementation where adder is inferred as carry+LUT4 instead of…
Jul 28, 2020
d38bf18
Separating LUT4 definition for PP3 & AP3
Jul 29, 2020
d4ce5e0
Merging changes from parent repo
Jul 29, 2020
e6361ee
Fixed synth_quicklogic flow to allow AP3 adder inference
mkurc-ant Jul 29, 2020
edabfad
Correcting indentation
Jul 29, 2020
76f6651
Updating latch definition in cells_map file for AP3
Jul 29, 2020
6baf3a8
Inferring adder as a cell - full_adder
Jul 30, 2020
1ab1be0
Modify options to optimize lut utilization
Aug 4, 2020
6c977f7
Comment freduce
Aug 4, 2020
bca0040
Adding nlutmap option
Aug 4, 2020
68fef98
Adding lut optimization support for AP3
Aug 5, 2020
495f443
Removing commented code
Aug 5, 2020
4d35825
Removing ap3_ff_map.v file and updating ap3_ffs_map.v file
Aug 7, 2020
83c2486
Adding AP2 device support
Aug 7, 2020
c15c367
Optimizing adder inference for AP3
Aug 10, 2020
0bdefa1
Optimizing AP2 utilization
Aug 11, 2020
b3aa28c
added support for infering and initialization of bram
tpagarani Aug 11, 2020
5636a5a
abc lut option updated for ap2
Aug 12, 2020
0ea4ec0
ram init changes
tpagarani Aug 12, 2020
b9851f1
add missing script
tpagarani Aug 12, 2020
3702f36
Changing lut option in abc for ap2
Aug 13, 2020
1b95a10
update lut option in abc command
Aug 13, 2020
3ce6a06
Adding EQN property to LUT instance in edf
Aug 14, 2020
84ca323
Adding optimizations to PP3 synthesis
Aug 17, 2020
ff560b9
Incorporating code review comments from Karol
Aug 17, 2020
43957d6
Removing latch definition which is now defined in a separate file
Aug 17, 2020
c4df691
Reverting lut option as suggested by Maciej
Aug 17, 2020
edafc0a
ram init updates
tpagarani Aug 21, 2020
3690841
Modified the ram models to support initialization
rakeshm75 Aug 24, 2020
7469cbe
Reenabled LUT4 inference
mkurc-ant Aug 24, 2020
11f615c
correct the clock ports for RAM8k
tpagarani Aug 24, 2020
cdd9800
modified to correct the yosys compilation error
rakeshm75 Aug 25, 2020
17773c4
Updating copyright name
Aug 26, 2020
eef91bd
initialize bram primitives from hex file
tpagarani Aug 26, 2020
ae7599c
update make file to remove FIFO and RAM block depedencies
tpagarani Aug 27, 2020
62b0a70
change file parameters name
tpagarani Aug 27, 2020
16aa52a
support RAM initialization
rakeshm75 Aug 27, 2020
f2de916
map_bram is run only for PP3 as of now
Aug 28, 2020
74667b0
Modified pp3_cells_sim.v file to support RAM init
rakeshm75 Aug 31, 2020
e3b4247
Adding cell mapping for _DFFSR_NPP_ & _DFFSR_PPP_
Aug 31, 2020
8b2d548
change init file format for 16k block
tpagarani Aug 31, 2020
9eb639c
adding d_buf inference
Sep 1, 2020
18dcfe7
Adding review comments
Sep 1, 2020
b6dfc39
Supporting d_buff inference for AP3
Sep 2, 2020
61ad3ff
Adding io_map file for AP3
Sep 2, 2020
bf12ea9
Infer clk port in in_reg or out_reg as ck_buff for AP3 & AP2 devices.
Sep 2, 2020
15fcd26
Adding external pad property to rst port
Sep 2, 2020
3584ec5
Rectifying clkbuf property on in_reg in AP2
Sep 2, 2020
e806fe9
Fixing an issue in RAM/DSP cell mapping
Sep 2, 2020
d419b9c
Updating in_reg/out_reg def in AP3. Replacing in_reg, out_reg with io…
Sep 4, 2020
6972972
Rectifying d_buff declaration issue
Sep 4, 2020
ed5475e
Fixing a compilation error in verilog
Sep 4, 2020
e83319c
Changing QL_CARRY to full_adder for AP2 & AP3 device
Sep 7, 2020
c762206
Commenting redundant code
Sep 7, 2020
bcc08e1
Replacing adder instance to full_adder for AP2, like AP3
Sep 8, 2020
4e521aa
Changing to uppercase for primitive cell names of AP3
Sep 23, 2020
cc35a56
Fix wrong rebase strategy remains
rw1nkler Oct 8, 2020
77f5dc8
Substitute YS_OVERRIDE with override
rw1nkler Oct 8, 2020
331a421
Updating IO names to lower case
Oct 8, 2020
ac34e8d
Added additional ABC optimizations to synth_quicklogic
mkurc-ant Sep 10, 2020
7759094
Allow less efficient use of BRAM resources
olofk Oct 11, 2020
054855b
Fix missing new lines and improve code formatting
rw1nkler Oct 12, 2020
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
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ passes/opt/opt_lut.cc @whitequark
# accidentally disable any of the above rules.

techlibs/intel_alm/ @ZirconiumX
techlibs/quicklogic/ @kgugala

# pyosys
misc/*.py @btut
Expand Down
6 changes: 6 additions & 0 deletions passes/pmgen/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,9 @@ passes/pmgen/peepopt_pm.h: passes/pmgen/pmgen.py $(PEEPOPT_PATTERN)
OBJS += passes/pmgen/xilinx_srl.o
passes/pmgen/xilinx_srl.o: passes/pmgen/xilinx_srl_pm.h
$(eval $(call add_extra_objs,passes/pmgen/xilinx_srl_pm.h))

# --------------------------------------

OBJS += passes/pmgen/ap3_wrapcarry.o
passes/pmgen/ap3_wrapcarry.o: passes/pmgen/ap3_wrapcarry_pm.h
$(eval $(call add_extra_objs,passes/pmgen/ap3_wrapcarry_pm.h))
158 changes: 158 additions & 0 deletions passes/pmgen/ap3_wrapcarry.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2020 QuickLogic Corp.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/

#include "kernel/yosys.h"
#include "kernel/sigtools.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

#include "passes/pmgen/ap3_wrapcarry_pm.h"

void create_ap3_wrapcarry(ap3_wrapcarry_pm &pm)
{
auto &st = pm.st_ap3_wrapcarry;

#if 0
log("\n");
log("carry: %s\n", log_id(st.carry, "--"));
log("lut: %s\n", log_id(st.lut, "--"));
#endif

log(" replacing LUT4 + QL_CARRY with $__AP3_CARRY_WRAPPER cell.\n");

Cell *cell = pm.module->addCell(NEW_ID, ID($__AP3_CARRY_WRAPPER));
pm.module->swap_names(cell, st.carry);

cell->setPort(ID::A, st.carry->getPort(ID(I0)));
cell->setPort(ID::B, st.carry->getPort(ID(I1)));
auto CI = st.carry->getPort(ID::CI);
cell->setPort(ID::CI, CI);
cell->setPort(ID::CO, st.carry->getPort(ID::CO));

auto I2 = st.lut->getPort(ID(I2));
if (pm.sigmap(CI) == pm.sigmap(I2)) {
cell->setParam(ID(I2_IS_CI), State::S1);
I2 = State::Sx;
}
else
cell->setParam(ID(I2_IS_CI), State::S0);
cell->setPort(ID(I2), I2);
cell->setPort(ID(I3), st.lut->getPort(ID(I3)));
cell->setPort(ID::O, st.lut->getPort(ID::O));
cell->setParam(ID::LUT, st.lut->getParam(ID(INIT)));

for (const auto &a : st.carry->attributes)
cell->attributes[stringf("\\QL_CARRY.%s", a.first.c_str())] = a.second;
for (const auto &a : st.lut->attributes)
cell->attributes[stringf("\\LUT4.%s", a.first.c_str())] = a.second;
cell->attributes[ID(LUT4.name)] = Const(st.lut->name.str());
if (st.carry->get_bool_attribute(ID::keep) || st.lut->get_bool_attribute(ID::keep))
cell->attributes[ID::keep] = true;

pm.autoremove(st.carry);
pm.autoremove(st.lut);
}

struct AP3WrapCarryPass : public Pass {
litghost marked this conversation as resolved.
Show resolved Hide resolved
AP3WrapCarryPass() : Pass("ap3_wrapcarry", "AP3: wrap carries") { }
void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" ap3_wrapcarry [selection]\n");
log("\n");
log("Wrap manually instantiated QL_CARRY cells, along with their associated LUT4s,\n");
log("into an internal $__AP3_CARRY_WRAPPER cell for preservation across technology\n");
log("mapping.\n");
log("\n");
log("Attributes on both cells will have their names prefixed with 'QL_CARRY.' or\n");
log("'LUT4.' and attached to the wrapping cell.\n");
log("A (* keep *) attribute on either cell will be logically OR-ed together.\n");
log("\n");
log(" -unwrap\n");
log(" unwrap $__AP3_CARRY_WRAPPER cells back into QL_CARRYs and LUT4s,\n");
log(" including restoring their attributes.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
bool unwrap = false;

log_header(design, "Executing ap3_wrapcarry pass (wrap carries).\n");

size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
if (args[argidx] == "-unwrap") {
unwrap = true;
continue;
}
break;
}
extra_args(args, argidx, design);

for (auto module : design->selected_modules()) {
if (!unwrap) {
ap3_wrapcarry_pm(module, module->selected_cells()).run_ap3_wrapcarry(create_ap3_wrapcarry);
} else {
for (auto cell : module->selected_cells()) {
if (cell->type != ID($__AP3_CARRY_WRAPPER))
continue;

auto carry = module->addCell(NEW_ID, ID(QL_CARRY));
carry->setPort(ID(I0), cell->getPort(ID::A));
carry->setPort(ID(I1), cell->getPort(ID::B));
carry->setPort(ID::CI, cell->getPort(ID::CI));
carry->setPort(ID::CO, cell->getPort(ID::CO));
module->swap_names(carry, cell);
auto lut_name = cell->attributes.at(ID(LUT4.name), Const(NEW_ID.str())).decode_string();
auto lut = module->addCell(lut_name, ID($lut));
lut->setParam(ID::WIDTH, 4);
lut->setParam(ID::LUT, cell->getParam(ID::LUT));
auto I2 = cell->getPort(cell->getParam(ID(I2_IS_CI)).as_bool() ? ID::CI : ID(I2));
lut->setPort(ID::A, {cell->getPort(ID(I3)), I2, cell->getPort(ID::B), cell->getPort(ID::A)});
lut->setPort(ID::Y, cell->getPort(ID::O));

Const src;
for (const auto &a : cell->attributes)
if (a.first.begins_with("\\QL_CARRY.\\"))
carry->attributes[a.first.c_str() + strlen("\\QL_CARRY.")] = a.second;
else if (a.first.begins_with("\\LUT4.\\"))
lut->attributes[a.first.c_str() + strlen("\\LUT4.")] = a.second;
else if (a.first == ID::src)
src = a.second;
else if (a.first.in(ID(LUT4.name), ID::keep, ID::module_not_derived))
continue;
else
log_abort();

if (!src.empty()) {
carry->attributes.insert(std::make_pair(ID::src, src));
lut->attributes.insert(std::make_pair(ID::src, src));
}

module->remove(cell);
}
}
}
}
} AP3WrapCarryPass;

PRIVATE_NAMESPACE_END
15 changes: 15 additions & 0 deletions passes/pmgen/ap3_wrapcarry.pmg
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pattern ap3_wrapcarry

match carry
select carry->type.in(\QL_CARRY)
endmatch

match lut
select lut->type.in(\LUT4)
index <SigSpec> port(lut, \I0) === port(carry, \I0)
index <SigSpec> port(lut, \I1) === port(carry, \I1)
endmatch

code
accept;
endcode
34 changes: 34 additions & 0 deletions techlibs/quicklogic/MULT_16BIT_X2.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module MULT_16BIT_X2 ( Amult1, Bmult1, Valid_mult1, Cmult1,
Amult2, Bmult2, Valid_mult2, Cmult2
);

input [15:0] Amult1;
input [15:0] Bmult1;
input Valid_mult1;
output [31:0] Cmult1;

input [15:0] Amult2;
input [15:0] Bmult2;
input Valid_mult2;
output [31:0] Cmult2;

wire [31:0] amult_int;
wire [31:0] bmult_int;
wire [63:0] cmult_int;
wire [1:0] valit_int;

assign valit_int = {Valid_mult2,Valid_mult1};
assign amult_int = {Amult2,Amult1};
assign bmult_int = {Bmult2,Bmult1};
assign Cmult1 = cmult_int[31:0];
assign Cmult2 = cmult_int[63:32];

//qlal4s3_mult_cell_macro
qlal4s3_mult_cell_macro u_qlal4s3_mult_cell_macro (
.Amult(amult_int),
.Bmult(bmult_int),
.Valid_mult(valit_int),
.sel_mul_32x32(1'b0),
.Cmult(cmult_int)
);
endmodule
21 changes: 21 additions & 0 deletions techlibs/quicklogic/MULT_32BIT.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module MULT_32BIT (Amult, Bmult, Valid_mult, Cmult);

input [31:0] Amult;
input [31:0] Bmult;
input Valid_mult;
output [63:0] Cmult;

wire [1:0] valit_int;

assign valit_int = {Valid_mult,Valid_mult};

//qlal4s3_mult_cell_macro
qlal4s3_mult_cell_macro u_qlal4s3_mult_cell_macro (
.Amult(Amult),
.Bmult(Bmult),
.Valid_mult(valit_int),
.sel_mul_32x32(1'b1),
.Cmult(Cmult)
);

endmodule
53 changes: 53 additions & 0 deletions techlibs/quicklogic/Makefile.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
OBJS += techlibs/quicklogic/synth_quicklogic.o
#OBJS += techlibs/quicklogic/ap3_opt.o
OBJS += techlibs/quicklogic/quicklogic_eqn.o
OBJS += techlibs/quicklogic/pp3_braminit.o
#OBJS += techlibs/quicklogic/quicklogic_fixcarry.o


$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap3_ffs_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap2_ffs_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_ffs_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap3_lut_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap2_lut_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_lut_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap3_latches_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap2_latches_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_latches_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap3_cells_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap2_cells_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_cells_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap3_arith_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap2_arith_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap2_io_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap3_io_map.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/cells_sim.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_cells_sim.v))

$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap3_cells_sim.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap2_cells_sim.v))

$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/MULT_16BIT_X2.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/MULT_32BIT.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/abc9_model.v))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_brams.txt))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_brams_map.v))

$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/pp3_lutdefs.txt))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap2_lutdefs.txt))
$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/ap3_lutdefs.txt))

EXTRA_OBJS += techlibs/quicklogic/brams_init.mk
.SECONDARY: techlibs/quicklogic/brams_init.mk

techlibs/quicklogic/brams_init.mk: techlibs/quicklogic/brams_init.py
$(Q) mkdir -p techlibs/quicklogic
$(P) $(PYTHON_EXECUTABLE) $<
$(Q) touch $@


techlibs/quicklogic/bram_init_8_16.vh: techlibs/quicklogic/brams_init.mk
techlibs/quicklogic/bram_init_32.vh: techlibs/quicklogic/brams_init.mk

$(eval $(call add_gen_share_file,share/quicklogic,techlibs/quicklogic/bram_init_8_16.vh))
$(eval $(call add_gen_share_file,share/quicklogic,techlibs/quicklogic/bram_init_32.vh))
29 changes: 29 additions & 0 deletions techlibs/quicklogic/abc9_model.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
(* abc9_box, lib_whitebox *)
module \$__AP3_CARRY_WRAPPER (
(* abc9_carry *)
output CO,
output O,
input A, B,
(* abc9_carry *)
input CI,
input I2, I3
);
parameter LUT = 0;
parameter I2_IS_CI = 0;
wire I2_OR_CI = I2_IS_CI ? CI : I2;
QL_CARRY carry (
.I0(A),
.I1(B),
.CI(CI),
.CO(CO)
);
LUT4 #(
.INIT(LUT)
) adder (
.I0(A),
.I1(B),
.I2(I2_OR_CI),
.I3(I3),
.O(O)
);
endmodule
64 changes: 64 additions & 0 deletions techlibs/quicklogic/ap2_arith_map.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
(* 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;

(* 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 = {CO, CI};

full_adder first_inst(
.A(AA[0]),
.B(BB[0]),
.CI(CI),
.CO(CO[0]),
.S(Y[0]));

genvar i;
generate for (i = 1; i < Y_WIDTH-1; i = i + 1) begin: slice
full_adder inst_i (
.A(AA[i]),
.B(BB[i]),
.CI(CO[i-1]),
.CO(CO[i]),
.S(Y[i])
);

end: slice
endgenerate

full_adder inst_last (
.A(AA[Y_WIDTH-1]),
.B(BB[Y_WIDTH-1]),
.CI(CO[Y_WIDTH-2]),
.CO(CO[Y_WIDTH-1]),
.S(Y[Y_WIDTH-1])
);

/* End implementation */
assign X = AA ^ BB;
endmodule
Loading