//
//							acc12s.v - 12-bit accumulator
//
//					(C) Copyright 2004-2008 John B. Stephensen
//
// This Verilog source file and all its derivatives are licensed only for
// personal non-profit educational use in the Amateur Radio Service and
// the license is not transferrable. The information is provided as-is for
// experimental purposes and the author does not warranty its freedom
// from defects or its suitability for any specific application.
//
// This accumulator support loading the input, loading the 2's complement
// of the input, adding to or subtracting from the current value.
//
//		ACC	SUB	Operation
//		 0		 0		A = B
//		 0		 1		A = -B
//		 1		 0		A = A - B
//		 1		 1		A = A + B
//
// 7 slices used. 228 MHz maximum.
//
module acc12s (
    input SUB,
	 input ACC,
    input [11:0] B,
    output [11:0] Q,
	 output CO,
    input CLK,
	 input CE,
	 input SCLR
    );
// internal signals
wire [11:0] c;	// carry propogation
// use 12 one-bit adder-subtracters with bypass
acc1as a11 (.SUB(SUB), .ACC(ACC), .B(B[11]), .CI(c[10]), .CO(c[11]), .Q(Q[11]), .CLK(CLK), .CE(CE), .RST(SCLR));
acc1as a10 (.SUB(SUB), .ACC(ACC), .B(B[10]), .CI(c[9]), .CO(c[10]), .Q(Q[10]), .CLK(CLK), .CE(CE), .RST(SCLR));
acc1as a9 (.SUB(SUB), .ACC(ACC), .B(B[9]), .CI(c[8]), .CO(c[9]), .Q(Q[9]), .CLK(CLK), .CE(CE), .RST(SCLR));
acc1as a8 (.SUB(SUB), .ACC(ACC), .B(B[8]), .CI(c[7]), .CO(c[8]), .Q(Q[8]), .CLK(CLK), .CE(CE), .RST(SCLR));
acc1as a7 (.SUB(SUB), .ACC(ACC), .B(B[7]), .CI(c[6]), .CO(c[7]), .Q(Q[7]), .CLK(CLK), .CE(CE), .RST(SCLR));
acc1as a6 (.SUB(SUB), .ACC(ACC), .B(B[6]), .CI(c[5]), .CO(c[6]), .Q(Q[6]), .CLK(CLK), .CE(CE), .RST(SCLR));
acc1as a5 (.SUB(SUB), .ACC(ACC), .B(B[5]), .CI(c[4]), .CO(c[5]), .Q(Q[5]), .CLK(CLK), .CE(CE), .RST(SCLR));
acc1as a4 (.SUB(SUB), .ACC(ACC), .B(B[4]), .CI(c[3]), .CO(c[4]), .Q(Q[4]), .CLK(CLK), .CE(CE), .RST(SCLR));
acc1as a3 (.SUB(SUB), .ACC(ACC), .B(B[3]), .CI(c[2]), .CO(c[3]), .Q(Q[3]), .CLK(CLK), .CE(CE), .RST(SCLR));
acc1as a2 (.SUB(SUB), .ACC(ACC), .B(B[2]), .CI(c[1]), .CO(c[2]), .Q(Q[2]), .CLK(CLK), .CE(CE), .RST(SCLR));
acc1as a1 (.SUB(SUB), .ACC(ACC), .B(B[1]), .CI(c[0]), .CO(c[1]), .Q(Q[1]), .CLK(CLK), .CE(CE), .RST(SCLR));
acc1as a0 (.SUB(SUB), .ACC(ACC), .B(B[0]), .CI(SUB), .CO(c[0]), .Q(Q[0]), .CLK(CLK), .CE(CE), .RST(SCLR));
// register carry output
FDCE ff (.D(c[11]), .C(CLK), .CE(CE), .CLR(SCLR), .Q(CO));
endmodule
