mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-28 18:29:25 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1058 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
			
		
		
	
	
			1058 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
| (* abc9_lut=1, lib_whitebox *)
 | |
| module LUT4(input A, B, C, D, output Z);
 | |
| 	parameter INIT = "0x0000";
 | |
| `include "parse_init.vh"
 | |
| 	localparam initp = parse_init(INIT);
 | |
| 	wire [7:0] s3 = D ?     initp[15:8] :    initp[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];
 | |
| 
 | |
| 	// Per-input delay differences are considered 'interconnect'
 | |
| 	// so not known yet
 | |
| 	specify
 | |
| 		(A => Z) = 233;
 | |
| 		(B => Z) = 233;
 | |
| 		(C => Z) = 233;
 | |
| 		(D => Z) = 233;
 | |
| 	endspecify
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| // This is a placeholder for ABC9 to extract the area/delay
 | |
| //   cost of 5-input LUTs and is not intended to be instantiated
 | |
| (* abc9_lut=2 *)
 | |
| module \$__ABC9_LUT5 (input SEL, D, C, B, A, output Z);
 | |
| 	specify
 | |
| 		(SEL => Z) = 171;
 | |
| 		(D => Z) = 303;
 | |
| 		(C => Z) = 311;
 | |
| 		(B => Z) = 309;
 | |
| 		(A => Z) = 306;
 | |
| 	endspecify
 | |
| endmodule
 | |
| 
 | |
| // Two LUT4s and MUX2
 | |
| module WIDEFN9(input A0, B0, C0, D0, A1, B1, C1, D1, SEL, output Z);
 | |
| 	parameter INIT0 = "0x0000";
 | |
| 	parameter INIT1 = "0x0000";
 | |
| 	wire z0, z1;
 | |
| 	LUT4 #(.INIT(INIT0)) lut4_0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(z0));
 | |
| 	LUT4 #(.INIT(INIT1)) lut4_1 (.A(A1), .B(B1), .C(C1), .D(D1), .Z(z1));
 | |
| 	assign Z = SEL ? z1 : z0;
 | |
| endmodule
 | |
| 
 | |
| (* abc9_box, lib_whitebox *)
 | |
| module INV(input A, output Z);
 | |
| 	assign Z = !A;
 | |
| 
 | |
| 	specify
 | |
| 		(A => Z) = 10;
 | |
| 	endspecify
 | |
| endmodule
 | |
| 
 | |
| // Bidirectional IO buffer
 | |
| module BB(input T, I, output O,
 | |
| 	(* iopad_external_pin *) inout B);
 | |
| 	assign B = T ? 1'bz : I;
 | |
| 	assign O = B;
 | |
| endmodule
 | |
| 
 | |
| // Input buffer
 | |
| module IB(
 | |
| 	(* iopad_external_pin *) input I,
 | |
| 	output O);
 | |
| 	assign O = I;
 | |
| endmodule
 | |
| 
 | |
| // Output buffer
 | |
| module OB(input I,
 | |
| 	(* iopad_external_pin *) output O);
 | |
| 	assign O = I;
 | |
| endmodule
 | |
| 
 | |
| // Output buffer with tristate
 | |
| module OBZ(input I, T,
 | |
| 	(* iopad_external_pin *) output O);
 | |
| 	assign O = T ? 1'bz : I;
 | |
| endmodule
 | |
| 
 | |
| // Constants
 | |
| module VLO(output Z);
 | |
| 	assign Z = 1'b0;
 | |
| endmodule
 | |
| 
 | |
| module VHI(output Z);
 | |
| 	assign Z = 1'b1;
 | |
| endmodule
 | |
| 
 | |
| // Vendor flipflops
 | |
| // (all have active high clock, enable and set/reset - use INV to invert)
 | |
| 
 | |
| // Async preset
 | |
| (* abc9_box, lib_whitebox *)
 | |
| module FD1P3BX(input D, CK, SP, PD, output reg Q);
 | |
| 	parameter GSR = "DISABLED";
 | |
| 	initial Q = 1'b1;
 | |
| 	always @(posedge CK or posedge PD)
 | |
| 		if (PD)
 | |
| 			Q <= 1'b1;
 | |
| 		else if (SP)
 | |
| 			Q <= D;
 | |
| 	specify
 | |
| 		$setup(D, posedge CK, 0);
 | |
| 		$setup(SP, posedge CK, 212);
 | |
| 		$setup(PD, posedge CK, 224);
 | |
| `ifndef YOSYS
 | |
| 		if (PD) (posedge CLK => (Q : 1)) = 0;
 | |
| `else
 | |
| 		if (PD) (PD => Q) = 0; 	// Technically, this should be an edge sensitive path
 | |
| 								// but for facilitating a bypass box, let's pretend it's
 | |
| 								// a simple path
 | |
| `endif
 | |
| 		if (!PD && SP) (posedge CK => (Q : D)) = 336;
 | |
| 	endspecify
 | |
| endmodule
 | |
| 
 | |
| // Async clear
 | |
| (* abc9_box, lib_whitebox *)
 | |
| module FD1P3DX(input D, CK, SP, CD, output reg Q);
 | |
| 	parameter GSR = "DISABLED";
 | |
| 	initial Q = 1'b0;
 | |
| 	always @(posedge CK or posedge CD)
 | |
| 		if (CD)
 | |
| 			Q <= 1'b0;
 | |
| 		else if (SP)
 | |
| 			Q <= D;
 | |
| 	specify
 | |
| 		$setup(D, posedge CK, 0);
 | |
| 		$setup(SP, posedge CK, 212);
 | |
| 		$setup(CD, posedge CK, 224);
 | |
| `ifndef YOSYS
 | |
| 		if (CD) (posedge CLK => (Q : 0)) = 0;
 | |
| `else
 | |
| 		if (CD) (CD => Q) = 0; 	// Technically, this should be an edge sensitive path
 | |
| 								// but for facilitating a bypass box, let's pretend it's
 | |
| 								// a simple path
 | |
| `endif
 | |
| 		if (!CD && SP) (posedge CK => (Q : D)) = 336;
 | |
| 	endspecify
 | |
| endmodule
 | |
| 
 | |
| // Sync clear
 | |
| (* abc9_flop, lib_whitebox *)
 | |
| module FD1P3IX(input D, CK, SP, CD, output reg Q);
 | |
| 	parameter GSR = "DISABLED";
 | |
| 	initial Q = 1'b0;
 | |
| 	always @(posedge CK)
 | |
| 		if (CD)
 | |
| 			Q <= 1'b0;
 | |
| 		else if (SP)
 | |
| 			Q <= D;
 | |
| 	specify
 | |
| 		$setup(D, posedge CK, 0);
 | |
| 		$setup(SP, posedge CK, 212);
 | |
| 		$setup(CD, posedge CK, 224);
 | |
| 		if (!CD && SP) (posedge CK => (Q : D)) = 336;
 | |
| 	endspecify
 | |
| endmodule
 | |
| 
 | |
| // Sync preset
 | |
| (* abc9_flop, lib_whitebox *)
 | |
| module FD1P3JX(input D, CK, SP, PD, output reg Q);
 | |
| 	parameter GSR = "DISABLED";
 | |
| 	initial Q = 1'b1;
 | |
| 	always @(posedge CK)
 | |
| 		if (PD)
 | |
| 			Q <= 1'b1;
 | |
| 		else if (SP)
 | |
| 			Q <= D;
 | |
| 	specify
 | |
| 		$setup(D, posedge CK, 0);
 | |
| 		$setup(SP, posedge CK, 212);
 | |
| 		$setup(PD, posedge CK, 224);
 | |
| 		if (!PD && SP) (posedge CK => (Q : D)) = 336;
 | |
| 	endspecify
 | |
| endmodule
 | |
| 
 | |
| // LUT4 with LUT3 tap for CCU2 use only
 | |
| (* lib_whitebox *)
 | |
| module LUT4_3(input A, B, C, D, output Z, Z3);
 | |
| 	parameter INIT = "0x0000";
 | |
| `include "parse_init.vh"
 | |
| 	localparam initp = parse_init(INIT);
 | |
| 	wire [7:0] s3 = D ?     initp[15:8] :     initp[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];
 | |
| 
 | |
| 	wire [3:0] s2_3 = C ?   initp[ 7:4] :     initp[3:0];
 | |
| 	wire [1:0] s1_3 = B ?    s2_3[ 3:2] :      s2_3[1:0];
 | |
| 	assign Z3 =       A ?       s1_3[1] :        s1_3[0];
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| // Carry primitive (incoporating two LUTs)
 | |
| (* abc9_box, lib_whitebox *)
 | |
| module CCU2(
 | |
| 	(* abc9_carry *) input CIN,
 | |
| 	input A1, B1, C1, D1, A0, B0, C0, D0,
 | |
| 	output S1, S0,
 | |
| 	(* abc9_carry *) output COUT);
 | |
| 	parameter INJECT = "YES";
 | |
| 	parameter INIT0 = "0x0000";
 | |
| 	parameter INIT1 = "0x1111";
 | |
| 
 | |
| 	localparam inject_p = (INJECT == "YES") ? 1'b1 : 1'b0;
 | |
| 
 | |
| 	wire LUT3_0, LUT4_0, LUT3_1, LUT4_1, carry_0;
 | |
| 	LUT4_3 #(.INIT(INIT0)) lut0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0), .Z3(LUT3_0));
 | |
| 	LUT4_3 #(.INIT(INIT1)) lut1 (.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1), .Z3(LUT3_1));
 | |
| 
 | |
| 	assign S0 = LUT4_0 ^ (CIN & ~inject_p);
 | |
| 	assign carry_0 = LUT4_0 ? CIN : (LUT3_0 & ~inject_p);
 | |
| 	assign S1 = LUT4_1 ^ (carry_0 & ~inject_p);
 | |
| 	assign COUT = LUT4_1 ? carry_0 : (LUT3_1 & ~inject_p);
 | |
| 
 | |
| 	specify
 | |
| 		(A0 => S0) = 233;
 | |
| 		(B0 => S0) = 233;
 | |
| 		(C0 => S0) = 233;
 | |
| 		(D0 => S0) = 233;
 | |
| 		(CIN => S0) = 228;
 | |
| 		(A0 => S1) = 481;
 | |
| 		(B0 => S1) = 481;
 | |
| 		(C0 => S1) = 481;
 | |
| 		(D0 => S1) = 481;
 | |
| 		(A1 => S1) = 233;
 | |
| 		(B1 => S1) = 233;
 | |
| 		(C1 => S1) = 233;
 | |
| 		(D1 => S1) = 233;
 | |
| 		(CIN => S1) = 307;
 | |
| 		(A0 => COUT) = 347;
 | |
| 		(B0 => COUT) = 347;
 | |
| 		(C0 => COUT) = 347;
 | |
| 		(D0 => COUT) = 347;
 | |
| 		(A1 => COUT) = 347;
 | |
| 		(B1 => COUT) = 347;
 | |
| 		(C1 => COUT) = 347;
 | |
| 		(D1 => COUT) = 347;
 | |
| 		(CIN => COUT) = 59;
 | |
| 	endspecify
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| // Packed flipflop
 | |
| module OXIDE_FF(input CLK, LSR, CE, DI, M, output reg Q);
 | |
| 	parameter GSR = "ENABLED";
 | |
| 	parameter [127:0] CEMUX = "1";
 | |
| 	parameter CLKMUX = "CLK";
 | |
| 	parameter LSRMUX = "LSR";
 | |
| 	parameter REGDDR = "DISABLED";
 | |
| 	parameter SRMODE = "LSR_OVER_CE";
 | |
| 	parameter REGSET = "RESET";
 | |
| 	parameter [127:0] LSRMODE = "LSR";
 | |
| 
 | |
| 	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 muxclk = (CLKMUX == "INV") ? ~CLK : CLK;
 | |
| 	wire srval;
 | |
| 	generate
 | |
| 		if (LSRMODE == "PRLD")
 | |
| 			assign srval = M;
 | |
| 		else
 | |
| 			assign srval = (REGSET == "SET") ? 1'b1 : 1'b0;
 | |
| 	endgenerate
 | |
| 
 | |
| 	initial Q = srval;
 | |
| 
 | |
| 	generate
 | |
| 		if (REGDDR == "ENABLED") begin
 | |
| 			if (SRMODE == "ASYNC") begin
 | |
| 				always @(posedge muxclk, negedge muxclk, posedge muxlsr)
 | |
| 					if (muxlsr)
 | |
| 						Q <= srval;
 | |
| 					else if (muxce)
 | |
| 						Q <= DI;
 | |
| 			end else begin
 | |
| 				always @(posedge muxclk, negedge muxclk)
 | |
| 					if (muxlsr)
 | |
| 						Q <= srval;
 | |
| 					else if (muxce)
 | |
| 						Q <= DI;
 | |
| 			end
 | |
| 		end else begin
 | |
| 			if (SRMODE == "ASYNC") begin
 | |
| 				always @(posedge muxclk, posedge muxlsr)
 | |
| 					if (muxlsr)
 | |
| 						Q <= srval;
 | |
| 					else if (muxce)
 | |
| 						Q <= DI;
 | |
| 			end else begin
 | |
| 				always @(posedge muxclk)
 | |
| 					if (muxlsr)
 | |
| 						Q <= srval;
 | |
| 					else if (muxce)
 | |
| 						Q <= DI;
 | |
| 			end
 | |
| 		end
 | |
| 	endgenerate
 | |
| endmodule
 | |
| 
 | |
| // Packed combinational logic (for post-pnr sim)
 | |
| module OXIDE_COMB(
 | |
| 	input A, B, C, D, // LUT inputs
 | |
| 	input SEL, // mux select input
 | |
| 	input F1, // output from LUT 1 for mux
 | |
| 	input FCI, // carry input
 | |
| 	input WAD0, WAD1, WAD2, WAD3, // LUTRAM write address inputs
 | |
| 	input WD, // LUTRAM write data input
 | |
| 	input WCK, WRE, // LUTRAM write clock and enable
 | |
| 	output F, // LUT/carry output
 | |
| 	output OFX // mux output
 | |
| );
 | |
| 	parameter MODE = "LOGIC"; // LOGIC, CCU2, DPRAM
 | |
| 	parameter [15:0] INIT = 16'h0000;
 | |
| 	parameter INJECT = "YES";
 | |
| 
 | |
| 	localparam inject_p = (INJECT == "YES") ? 1'b1 : 1'b0;
 | |
| 
 | |
| 	reg [15:0] lut = INIT;
 | |
| 
 | |
| 	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];
 | |
| 	wire Z =        A ?          s1[1] :         s1[0];
 | |
| 
 | |
| 	wire [3:0] s2_3 = C ?   INIT[ 7:4] :     INIT[3:0];
 | |
| 	wire [1:0] s1_3 = B ?   s2_3[ 3:2] :     s2_3[1:0];
 | |
| 	wire Z3 =         A ?      s1_3[1] :       s1_3[0];
 | |
| 
 | |
| 	generate
 | |
| 		if (MODE == "DPRAM") begin
 | |
| 			always @(posedge WCK)
 | |
| 				if (WRE)
 | |
| 					lut[{WAD3, WAD2, WAD1, WAD0}] <= WD;
 | |
| 		end
 | |
| 		if (MODE == "CCU2") begin
 | |
| 			assign F = Z ^ (FCI & ~inject_p);
 | |
| 			assign FCO = Z ? FCI : (Z3 & ~inject_p);
 | |
| 		end else begin
 | |
| 			assign F = Z;
 | |
| 		end
 | |
| 	endgenerate
 | |
| 
 | |
| 	assign OFX = SEL ? F1 : F;
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| // LUTRAM
 | |
| module DPR16X4(
 | |
| 	input [3:0] RAD, DI, WAD,
 | |
| 	input WRE, WCK,
 | |
| 	output [3:0] DO
 | |
| );
 | |
| 	parameter INITVAL = "0x0000000000000000";
 | |
| `include "parse_init.vh"
 | |
| 	localparam [63:0] parsed_init = parse_init_64(INITVAL);
 | |
| 
 | |
| 	reg [3:0] mem[0:15];
 | |
| 	integer i;
 | |
| 	initial begin
 | |
| 		for (i = 0; i < 15; i++)
 | |
| 			mem[i] = parsed_init[i * 4 +: 4];
 | |
| 	end
 | |
| 
 | |
| 	always @(posedge WCK)
 | |
| 		if (WRE)
 | |
| 			mem[WAD] <= DI;
 | |
| 	assign DO = mem[RAD];
 | |
| endmodule
 | |
| 
 | |
| // Used for all the DSP models to reduce duplication
 | |
| module OXIDE_DSP_REG #(
 | |
| 	parameter W = 18,
 | |
| 	parameter USED = "REGISTER",
 | |
| 	parameter RESETMODE = "SYNC"
 | |
| ) (
 | |
| 	input CLK, CE, RST,
 | |
| 	input [W-1:0] D,
 | |
| 	output reg [W-1:0] Q
 | |
| );
 | |
| 	generate
 | |
| 		if (USED == "BYPASS")
 | |
| 			always @* Q = D;
 | |
| 		else if (USED == "REGISTER") begin
 | |
| 			initial Q = 0;
 | |
| 			if (RESETMODE == "ASYNC")
 | |
| 				always @(posedge CLK, posedge RST) begin
 | |
| 					if (RST)
 | |
| 						Q <= 0;
 | |
| 					else if (CE)
 | |
| 						Q <= D;
 | |
| 				end
 | |
| 			else if (RESETMODE == "SYNC")
 | |
| 				always @(posedge CLK) begin
 | |
| 					if (RST)
 | |
| 						Q <= 0;
 | |
| 					else if (CE)
 | |
| 						Q <= D;
 | |
| 				end
 | |
| 		end
 | |
| 	endgenerate
 | |
| endmodule
 | |
| 
 | |
| module OXIDE_DSP_SIM #(
 | |
| 	// User facing parameters
 | |
| 	parameter REGINPUTA = "BYPASS",
 | |
| 	parameter REGINPUTB = "BYPASS",
 | |
| 	parameter REGINPUTC = "BYPASS",
 | |
| 	parameter REGADDSUB = "BYPASS",
 | |
| 	parameter REGLOADC = "BYPASS",
 | |
| 	parameter REGLOADC2 = "BYPASS",
 | |
| 	parameter REGCIN = "BYPASS",
 | |
| 	parameter REGPIPELINE = "BYPASS",
 | |
| 	parameter REGOUTPUT = "BYPASS",
 | |
| 	parameter GSR = "ENABLED",
 | |
| 	parameter RESETMODE = "SYNC",
 | |
| 	// Internally used parameters
 | |
| 	parameter A_WIDTH = 36,
 | |
| 	parameter B_WIDTH = 36,
 | |
| 	parameter C_WIDTH = 36,
 | |
| 	parameter Z_WIDTH = 72,
 | |
| 	parameter PREADD_USED = 0,
 | |
| 	parameter ADDSUB_USED = 0
 | |
| ) (
 | |
| 	input [A_WIDTH-1:0] A,
 | |
| 	input [B_WIDTH-1:0] B,
 | |
| 	input [C_WIDTH-1:0] C,
 | |
| 	input SIGNEDA,
 | |
| 	input SIGNEDB,
 | |
| 	input SIGNEDC,
 | |
| 	input CIN,
 | |
| 	input LOADC,
 | |
| 	input ADDSUB,
 | |
| 	input CLK,
 | |
| 	input CEA, CEB, CEC, CEPIPE, CECTRL, CECIN, CEOUT,
 | |
| 	input RSTA, RSTB, RSTC, RSTPIPE, RSTCTRL, RSTCIN, RSTOUT,
 | |
| 	output wire [Z_WIDTH-1:0] Z
 | |
| );
 | |
| 	
 | |
| 	localparam M_WIDTH = (A_WIDTH+B_WIDTH);
 | |
| 
 | |
| 	/******** REGISTERS ********/
 | |
| 
 | |
| 	wire [M_WIDTH-1:0] pipe_d, pipe_q;
 | |
| 	wire [Z_WIDTH-1:0] z_d;
 | |
| 
 | |
| 	wire [A_WIDTH-1:0] a_r;
 | |
| 	wire [B_WIDTH-1:0] b_r;
 | |
| 	wire [C_WIDTH-1:0] c_r, c_r2;
 | |
| 	wire asgd_r, bsgd_r, csgd_r, csgd_r2;
 | |
| 
 | |
| 	wire addsub_r, addsub_r2, cin_r, cin_r2, sgd_r, sgd_r2;
 | |
| 	wire loadc_r, loadc_r2;
 | |
| 
 | |
| 	OXIDE_DSP_REG #(A_WIDTH+1, REGINPUTA, RESETMODE) a_reg(CLK, CEA, RSTA, {SIGNEDA, A}, {asgd_r, a_r});
 | |
| 	OXIDE_DSP_REG #(B_WIDTH+1, REGINPUTB, RESETMODE) b_reg(CLK, CEB, RSTB, {SIGNEDB, B}, {bsgd_r, b_r});
 | |
| 	OXIDE_DSP_REG #(C_WIDTH+1, REGINPUTC, RESETMODE) c_reg(CLK, CEC, RSTC, {SIGNEDC, C}, {csgd_r, c_r});
 | |
| 
 | |
| 	OXIDE_DSP_REG #(M_WIDTH, REGPIPELINE, RESETMODE) pipe_reg(CLK, CEPIPE, RSTPIPE, pipe_d, pipe_q);
 | |
| 
 | |
| 	OXIDE_DSP_REG #(2, REGADDSUB, RESETMODE) addsub_reg(CLK, CECTRL, RSTCTRL, {SIGNEDA, ADDSUB}, {sgd_r, addsub_r});
 | |
| 	OXIDE_DSP_REG #(1, REGLOADC, RESETMODE) loadc_reg(CLK, CECTRL, RSTCTRL, LOADC, loadc_r);
 | |
| 	OXIDE_DSP_REG #(2, REGPIPELINE, RESETMODE) addsub2_reg(CLK, CECTRL, RSTCTRL, {sgd_r, addsub_r}, {sgd_r2, addsub_r2});
 | |
| 	OXIDE_DSP_REG #(1, REGLOADC2, RESETMODE) loadc2_reg(CLK, CECTRL, RSTCTRL, loadc_r, loadc_r2);
 | |
| 
 | |
| 	OXIDE_DSP_REG #(1, REGCIN, RESETMODE) cin_reg(CLK, CECIN, RSTCIN, CIN, cin_r);
 | |
| 	OXIDE_DSP_REG #(1, REGPIPELINE, RESETMODE) cin2_reg(CLK, CECIN, RSTCIN, cin_r, cin_r2);
 | |
| 
 | |
| 	OXIDE_DSP_REG #(C_WIDTH+1, REGPIPELINE, RESETMODE) c2_reg(CLK, CEC, RSTC, {csgd_r, c_r}, {csgd_r2, c_r2});
 | |
| 
 | |
| 	OXIDE_DSP_REG #(Z_WIDTH, REGOUTPUT, RESETMODE) z_reg(CLK, CEOUT, RSTOUT, z_d, Z);
 | |
| 
 | |
| 	/******** PREADDER ********/
 | |
| 
 | |
| 	wire [B_WIDTH-1:0] mult_b;
 | |
| 	wire mult_b_sgd;
 | |
| 
 | |
| 	generate
 | |
| 		if (PREADD_USED) begin
 | |
| 			assign mult_b = (b_r + c_r);
 | |
| 			assign mult_b_sgd = (bsgd_r | csgd_r);
 | |
| 		end else begin
 | |
| 			assign mult_b = b_r;
 | |
| 			assign mult_b_sgd = bsgd_r;
 | |
| 		end
 | |
| 	endgenerate
 | |
| 
 | |
| 	/******** MULTIPLIER ********/
 | |
| 
 | |
| 	// sign extend operands if needed
 | |
| 	wire [M_WIDTH-1:0] mult_a_ext = {{(M_WIDTH-A_WIDTH){asgd_r ? a_r[A_WIDTH-1] : 1'b0}}, a_r};
 | |
| 	wire [M_WIDTH-1:0] mult_b_ext = {{(M_WIDTH-B_WIDTH){mult_b_sgd ? mult_b[B_WIDTH-1] : 1'b0}}, mult_b};
 | |
| 
 | |
| 	wire [M_WIDTH-1:0] mult_m = mult_a_ext * mult_b_ext;
 | |
| 
 | |
| 	/******** ACCUMULATOR ********/
 | |
| 
 | |
| 	wire [Z_WIDTH-1:0] m_ext;
 | |
| 
 | |
| 	generate
 | |
| 		if (ADDSUB_USED) begin
 | |
| 			assign pipe_d = mult_m;
 | |
| 			assign m_ext = {{(Z_WIDTH-M_WIDTH){sgd_r2 ? pipe_q[M_WIDTH-1] : 1'b0}}, pipe_q};
 | |
| 			assign z_d = (loadc_r2 ? c_r2 : Z) + cin_r2 + (addsub_r2 ? -m_ext : m_ext);  
 | |
| 		end else begin
 | |
| 			assign z_d = mult_m;
 | |
| 		end
 | |
| 	endgenerate
 | |
| 
 | |
| 
 | |
| endmodule
 | |
| 
 | |
| module MULT9X9 #(
 | |
| 	parameter REGINPUTA = "REGISTER",
 | |
| 	parameter REGINPUTB = "REGISTER",
 | |
| 	parameter REGOUTPUT = "REGISTER",
 | |
| 	parameter GSR = "ENABLED",
 | |
| 	parameter RESETMODE = "SYNC"
 | |
| ) (
 | |
| 	input [8:0] A,
 | |
| 	input [8:0] B,
 | |
| 	input CLK,
 | |
| 	input CEA,
 | |
| 	input RSTA,
 | |
| 	input CEB,
 | |
| 	input RSTB,
 | |
| 	input SIGNEDA,
 | |
| 	input SIGNEDB,
 | |
| 	input RSTOUT,
 | |
| 	input CEOUT,
 | |
| 	output [17:0] Z
 | |
| );
 | |
| 	OXIDE_DSP_SIM #(
 | |
| 		.REGINPUTA(REGINPUTA),
 | |
| 		.REGINPUTB(REGINPUTB),
 | |
| 		.REGOUTPUT(REGOUTPUT),
 | |
| 		.GSR(GSR),
 | |
| 		.RESETMODE(RESETMODE),
 | |
| 
 | |
| 		.A_WIDTH(9),
 | |
| 		.B_WIDTH(9),
 | |
| 		.Z_WIDTH(18),
 | |
| 		.PREADD_USED(0),
 | |
| 		.ADDSUB_USED(0)
 | |
| 	) dsp_i (
 | |
| 		.A(A), .B(B),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA), .RSTA(RSTA),
 | |
| 		.CEB(CEB), .RSTB(RSTB),
 | |
| 		.SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB),
 | |
| 		.RSTOUT(RSTOUT), .CEOUT(CEOUT),
 | |
| 		.Z(Z)
 | |
| 	);
 | |
| endmodule
 | |
| 
 | |
| module MULT18X18 #(
 | |
| 	parameter REGINPUTA = "REGISTER",
 | |
| 	parameter REGINPUTB = "REGISTER",
 | |
| 	parameter REGOUTPUT = "REGISTER",
 | |
| 	parameter GSR = "ENABLED",
 | |
| 	parameter RESETMODE = "SYNC"
 | |
| ) (
 | |
| 	input [17:0] A,
 | |
| 	input [17:0] B,
 | |
| 	input CLK,
 | |
| 	input CEA,
 | |
| 	input RSTA,
 | |
| 	input CEB,
 | |
| 	input RSTB,
 | |
| 	input SIGNEDA,
 | |
| 	input SIGNEDB,
 | |
| 	input RSTOUT,
 | |
| 	input CEOUT,
 | |
| 	output [35:0] Z
 | |
| );
 | |
| 	OXIDE_DSP_SIM #(
 | |
| 		.REGINPUTA(REGINPUTA),
 | |
| 		.REGINPUTB(REGINPUTB),
 | |
| 		.REGOUTPUT(REGOUTPUT),
 | |
| 		.GSR(GSR),
 | |
| 		.RESETMODE(RESETMODE),
 | |
| 
 | |
| 		.A_WIDTH(18),
 | |
| 		.B_WIDTH(18),
 | |
| 		.Z_WIDTH(36),
 | |
| 		.PREADD_USED(0),
 | |
| 		.ADDSUB_USED(0)
 | |
| 	) dsp_i (
 | |
| 		.A(A), .B(B),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA), .RSTA(RSTA),
 | |
| 		.CEB(CEB), .RSTB(RSTB),
 | |
| 		.SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB),
 | |
| 		.RSTOUT(RSTOUT), .CEOUT(CEOUT),
 | |
| 		.Z(Z)
 | |
| 	);
 | |
| endmodule
 | |
| 
 | |
| module MULT18X36 #(
 | |
| 	parameter REGINPUTA = "REGISTER",
 | |
| 	parameter REGINPUTB = "REGISTER",
 | |
| 	parameter REGOUTPUT = "REGISTER",
 | |
| 	parameter GSR = "ENABLED",
 | |
| 	parameter RESETMODE = "SYNC"
 | |
| ) (
 | |
| 	input [17:0] A,
 | |
| 	input [35:0] B,
 | |
| 	input CLK,
 | |
| 	input CEA,
 | |
| 	input RSTA,
 | |
| 	input CEB,
 | |
| 	input RSTB,
 | |
| 	input SIGNEDA,
 | |
| 	input SIGNEDB,
 | |
| 	input RSTOUT,
 | |
| 	input CEOUT,
 | |
| 	output [53:0] Z
 | |
| );
 | |
| 	OXIDE_DSP_SIM #(
 | |
| 		.REGINPUTA(REGINPUTA),
 | |
| 		.REGINPUTB(REGINPUTB),
 | |
| 		.REGOUTPUT(REGOUTPUT),
 | |
| 		.GSR(GSR),
 | |
| 		.RESETMODE(RESETMODE),
 | |
| 
 | |
| 		.A_WIDTH(18),
 | |
| 		.B_WIDTH(36),
 | |
| 		.Z_WIDTH(54),
 | |
| 		.PREADD_USED(0),
 | |
| 		.ADDSUB_USED(0)
 | |
| 	) dsp_i (
 | |
| 		.A(A), .B(B),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA), .RSTA(RSTA),
 | |
| 		.CEB(CEB), .RSTB(RSTB),
 | |
| 		.SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB),
 | |
| 		.RSTOUT(RSTOUT), .CEOUT(CEOUT),
 | |
| 		.Z(Z)
 | |
| 	);
 | |
| endmodule
 | |
| 
 | |
| module MULT36X36 #(
 | |
| 	parameter REGINPUTA = "REGISTER",
 | |
| 	parameter REGINPUTB = "REGISTER",
 | |
| 	parameter REGOUTPUT = "REGISTER",
 | |
| 	parameter GSR = "ENABLED",
 | |
| 	parameter RESETMODE = "SYNC"
 | |
| ) (
 | |
| 	input [35:0] A,
 | |
| 	input [35:0] B,
 | |
| 	input CLK,
 | |
| 	input CEA,
 | |
| 	input RSTA,
 | |
| 	input CEB,
 | |
| 	input RSTB,
 | |
| 	input SIGNEDA,
 | |
| 	input SIGNEDB,
 | |
| 	input RSTOUT,
 | |
| 	input CEOUT,
 | |
| 	output [71:0] Z
 | |
| );
 | |
| 	OXIDE_DSP_SIM #(
 | |
| 		.REGINPUTA(REGINPUTA),
 | |
| 		.REGINPUTB(REGINPUTB),
 | |
| 		.REGOUTPUT(REGOUTPUT),
 | |
| 		.GSR(GSR),
 | |
| 		.RESETMODE(RESETMODE),
 | |
| 
 | |
| 		.A_WIDTH(36),
 | |
| 		.B_WIDTH(36),
 | |
| 		.Z_WIDTH(72),
 | |
| 		.PREADD_USED(0),
 | |
| 		.ADDSUB_USED(0)
 | |
| 	) dsp_i (
 | |
| 		.A(A), .B(B),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA), .RSTA(RSTA),
 | |
| 		.CEB(CEB), .RSTB(RSTB),
 | |
| 		.SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB),
 | |
| 		.RSTOUT(RSTOUT), .CEOUT(CEOUT),
 | |
| 		.Z(Z)
 | |
| 	);
 | |
| endmodule
 | |
| 
 | |
| 
 | |
| module MULTPREADD9X9 #(
 | |
| 	parameter REGINPUTA = "REGISTER",
 | |
| 	parameter REGINPUTB = "REGISTER",
 | |
| 	parameter REGINPUTC = "REGISTER",
 | |
| 	parameter REGOUTPUT = "REGISTER",
 | |
| 	parameter GSR = "ENABLED",
 | |
| 	parameter RESETMODE = "SYNC"
 | |
| ) (
 | |
| 	input [8:0] A,
 | |
| 	input [8:0] B,
 | |
| 	input [8:0] C,
 | |
| 	input CLK,
 | |
| 	input CEA,
 | |
| 	input RSTA,
 | |
| 	input CEB,
 | |
| 	input RSTB,
 | |
| 	input CEC,
 | |
| 	input RSTC,
 | |
| 	input SIGNEDA,
 | |
| 	input SIGNEDB,
 | |
| 	input SIGNEDC,
 | |
| 	input RSTOUT,
 | |
| 	input CEOUT,
 | |
| 	output [17:0] Z
 | |
| );
 | |
| 	OXIDE_DSP_SIM #(
 | |
| 		.REGINPUTA(REGINPUTA),
 | |
| 		.REGINPUTB(REGINPUTB),
 | |
| 		.REGINPUTC(REGINPUTC),
 | |
| 		.REGOUTPUT(REGOUTPUT),
 | |
| 		.GSR(GSR),
 | |
| 		.RESETMODE(RESETMODE),
 | |
| 
 | |
| 		.A_WIDTH(9),
 | |
| 		.B_WIDTH(9),
 | |
| 		.C_WIDTH(9),
 | |
| 		.Z_WIDTH(18),
 | |
| 		.PREADD_USED(1),
 | |
| 		.ADDSUB_USED(0)
 | |
| 	) dsp_i (
 | |
| 		.A(A), .B(B), .C(C),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA), .RSTA(RSTA),
 | |
| 		.CEB(CEB), .RSTB(RSTB),
 | |
| 		.CEC(CEC), .RSTC(RSTC),
 | |
| 		.SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), .SIGNEDC(SIGNEDC),
 | |
| 		.RSTOUT(RSTOUT), .CEOUT(CEOUT),
 | |
| 		.Z(Z)
 | |
| 	);
 | |
| endmodule
 | |
| 
 | |
| 
 | |
| module MULTPREADD18X18 #(
 | |
| 	parameter REGINPUTA = "REGISTER",
 | |
| 	parameter REGINPUTB = "REGISTER",
 | |
| 	parameter REGINPUTC = "REGISTER",
 | |
| 	parameter REGOUTPUT = "REGISTER",
 | |
| 	parameter GSR = "ENABLED",
 | |
| 	parameter RESETMODE = "SYNC"
 | |
| ) (
 | |
| 	input [17:0] A,
 | |
| 	input [17:0] B,
 | |
| 	input [17:0] C,
 | |
| 	input CLK,
 | |
| 	input CEA,
 | |
| 	input RSTA,
 | |
| 	input CEB,
 | |
| 	input RSTB,
 | |
| 	input CEC,
 | |
| 	input RSTC,
 | |
| 	input SIGNEDA,
 | |
| 	input SIGNEDB,
 | |
| 	input SIGNEDC,
 | |
| 	input RSTOUT,
 | |
| 	input CEOUT,
 | |
| 	output [35:0] Z
 | |
| );
 | |
| 	OXIDE_DSP_SIM #(
 | |
| 		.REGINPUTA(REGINPUTA),
 | |
| 		.REGINPUTB(REGINPUTB),
 | |
| 		.REGINPUTC(REGINPUTC),
 | |
| 		.REGOUTPUT(REGOUTPUT),
 | |
| 		.GSR(GSR),
 | |
| 		.RESETMODE(RESETMODE),
 | |
| 
 | |
| 		.A_WIDTH(18),
 | |
| 		.B_WIDTH(18),
 | |
| 		.C_WIDTH(18),
 | |
| 		.Z_WIDTH(36),
 | |
| 		.PREADD_USED(1),
 | |
| 		.ADDSUB_USED(0)
 | |
| 	) dsp_i (
 | |
| 		.A(A), .B(B), .C(C),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA), .RSTA(RSTA),
 | |
| 		.CEB(CEB), .RSTB(RSTB),
 | |
| 		.CEC(CEC), .RSTC(RSTC),
 | |
| 		.SIGNEDA(SIGNEDA), .SIGNEDB(SIGNEDB), .SIGNEDC(SIGNEDC),
 | |
| 		.RSTOUT(RSTOUT), .CEOUT(CEOUT),
 | |
| 		.Z(Z)
 | |
| 	);
 | |
| endmodule
 | |
| 
 | |
| 
 | |
| module MULTADDSUB18X18 #(
 | |
| 	parameter REGINPUTA = "REGISTER",
 | |
| 	parameter REGINPUTB = "REGISTER",
 | |
| 	parameter REGINPUTC = "REGISTER",
 | |
| 	parameter REGADDSUB = "REGISTER",
 | |
| 	parameter REGLOADC = "REGISTER",
 | |
| 	parameter REGLOADC2 = "REGISTER",
 | |
| 	parameter REGCIN = "REGISTER",
 | |
| 	parameter REGPIPELINE = "REGISTER",
 | |
| 	parameter REGOUTPUT = "REGISTER",
 | |
| 	parameter GSR = "ENABLED",
 | |
| 	parameter RESETMODE = "SYNC"
 | |
| ) (
 | |
| 	input [17:0] A,
 | |
| 	input [17:0] B,
 | |
| 	input [53:0] C,
 | |
|     input CLK,
 | |
|     input CEA,
 | |
|     input RSTA,
 | |
|     input CEB,
 | |
|     input RSTB,
 | |
|     input CEC,
 | |
|     input RSTC,
 | |
|     input SIGNED,
 | |
|     input RSTPIPE,
 | |
|     input CEPIPE,
 | |
|     input RSTCTRL,
 | |
|     input CECTRL,
 | |
|     input RSTCIN,
 | |
|     input CECIN,
 | |
|     input LOADC,
 | |
|     input ADDSUB,
 | |
|     output [53:0] Z,
 | |
|     input RSTOUT,
 | |
|     input CEOUT,
 | |
|     input CIN
 | |
| );
 | |
| 	OXIDE_DSP_SIM #(
 | |
| 		.REGINPUTA(REGINPUTA),
 | |
| 		.REGINPUTB(REGINPUTB),
 | |
| 		.REGINPUTC(REGINPUTC),
 | |
| 		.REGADDSUB(REGADDSUB),
 | |
| 		.REGLOADC(REGLOADC),
 | |
| 		.REGLOADC2(REGLOADC2),
 | |
| 		.REGCIN(REGCIN),
 | |
| 		.REGPIPELINE(REGPIPELINE),
 | |
| 		.REGOUTPUT(REGOUTPUT),
 | |
| 		.GSR(GSR),
 | |
| 		.RESETMODE(RESETMODE),
 | |
| 
 | |
| 		.A_WIDTH(18),
 | |
| 		.B_WIDTH(18),
 | |
| 		.C_WIDTH(54),
 | |
| 		.Z_WIDTH(54),
 | |
| 		.PREADD_USED(0),
 | |
| 		.ADDSUB_USED(1)
 | |
| 	) dsp_i (
 | |
| 		.A(A), .B(B), .C(C),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA), .RSTA(RSTA),
 | |
| 		.CEB(CEB), .RSTB(RSTB),
 | |
| 		.CEC(CEC), .RSTC(RSTC),
 | |
| 		.CEPIPE(CEPIPE), .RSTPIPE(RSTPIPE),
 | |
| 		.CECTRL(CECTRL), .RSTCTRL(RSTCTRL),
 | |
| 		.CECIN(CECIN), .RSTCIN(RSTCIN),
 | |
| 		.CIN(CIN), .LOADC(LOADC), .ADDSUB(ADDSUB),
 | |
| 		.SIGNEDA(SIGNED), .SIGNEDB(SIGNED), .SIGNEDC(SIGNED),
 | |
| 		.RSTOUT(RSTOUT), .CEOUT(CEOUT),
 | |
| 		.Z(Z)
 | |
| 	);
 | |
| endmodule
 | |
| 
 | |
| 
 | |
| module MULTADDSUB36X36 #(
 | |
| 	parameter REGINPUTA = "REGISTER",
 | |
| 	parameter REGINPUTB = "REGISTER",
 | |
| 	parameter REGINPUTC = "REGISTER",
 | |
| 	parameter REGADDSUB = "REGISTER",
 | |
| 	parameter REGLOADC = "REGISTER",
 | |
| 	parameter REGLOADC2 = "REGISTER",
 | |
| 	parameter REGCIN = "REGISTER",
 | |
| 	parameter REGPIPELINE = "REGISTER",
 | |
| 	parameter REGOUTPUT = "REGISTER",
 | |
| 	parameter GSR = "ENABLED",
 | |
| 	parameter RESETMODE = "SYNC"
 | |
| ) (
 | |
| 	input [35:0] A,
 | |
| 	input [35:0] B,
 | |
| 	input [107:0] C,
 | |
|     input CLK,
 | |
|     input CEA,
 | |
|     input RSTA,
 | |
|     input CEB,
 | |
|     input RSTB,
 | |
|     input CEC,
 | |
|     input RSTC,
 | |
|     input SIGNED,
 | |
|     input RSTPIPE,
 | |
|     input CEPIPE,
 | |
|     input RSTCTRL,
 | |
|     input CECTRL,
 | |
|     input RSTCIN,
 | |
|     input CECIN,
 | |
|     input LOADC,
 | |
|     input ADDSUB,
 | |
|     output [107:0] Z,
 | |
|     input RSTOUT,
 | |
|     input CEOUT,
 | |
|     input CIN
 | |
| );
 | |
| 	OXIDE_DSP_SIM #(
 | |
| 		.REGINPUTA(REGINPUTA),
 | |
| 		.REGINPUTB(REGINPUTB),
 | |
| 		.REGINPUTC(REGINPUTC),
 | |
| 		.REGADDSUB(REGADDSUB),
 | |
| 		.REGLOADC(REGLOADC),
 | |
| 		.REGLOADC2(REGLOADC2),
 | |
| 		.REGCIN(REGCIN),
 | |
| 		.REGPIPELINE(REGPIPELINE),
 | |
| 		.REGOUTPUT(REGOUTPUT),
 | |
| 		.GSR(GSR),
 | |
| 		.RESETMODE(RESETMODE),
 | |
| 
 | |
| 		.A_WIDTH(36),
 | |
| 		.B_WIDTH(36),
 | |
| 		.C_WIDTH(108),
 | |
| 		.Z_WIDTH(108),
 | |
| 		.PREADD_USED(0),
 | |
| 		.ADDSUB_USED(1)
 | |
| 	) dsp_i (
 | |
| 		.A(A), .B(B), .C(C),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA), .RSTA(RSTA),
 | |
| 		.CEB(CEB), .RSTB(RSTB),
 | |
| 		.CEC(CEC), .RSTC(RSTC),
 | |
| 		.CEPIPE(CEPIPE), .RSTPIPE(RSTPIPE),
 | |
| 		.CECTRL(CECTRL), .RSTCTRL(RSTCTRL),
 | |
| 		.CECIN(CECIN), .RSTCIN(RSTCIN),
 | |
| 		.CIN(CIN), .LOADC(LOADC), .ADDSUB(ADDSUB),
 | |
| 		.SIGNEDA(SIGNED), .SIGNEDB(SIGNED), .SIGNEDC(SIGNED),
 | |
| 		.RSTOUT(RSTOUT), .CEOUT(CEOUT),
 | |
| 		.Z(Z)
 | |
| 	);
 | |
| endmodule
 | |
| 
 | |
| module MULTADDSUB9X9WIDE #(
 | |
| 	parameter REGINPUTAB0 = "REGISTER",
 | |
| 	parameter REGINPUTAB1 = "REGISTER",
 | |
| 	parameter REGINPUTAB2 = "REGISTER",
 | |
| 	parameter REGINPUTAB3 = "REGISTER",
 | |
| 	parameter REGINPUTC = "REGISTER",
 | |
| 	parameter REGADDSUB = "REGISTER",
 | |
| 	parameter REGLOADC = "REGISTER",
 | |
| 	parameter REGLOADC2 = "REGISTER",
 | |
| 	parameter REGPIPELINE = "REGISTER",
 | |
| 	parameter REGOUTPUT = "REGISTER",
 | |
| 	parameter GSR = "ENABLED",
 | |
| 	parameter RESETMODE = "SYNC"
 | |
| ) (
 | |
| 	input [8:0] A0, B0, A1, B1, A2, B2, A3, B3,
 | |
| 	input [53:0] C,
 | |
| 	input CLK,
 | |
| 	input CEA0A1, CEA2A3,
 | |
| 	input RSTA0A1, RSTA2A3,
 | |
| 	input CEB0B1, CEB2B3,
 | |
| 	input RSTB0B1, RSTB2B3,
 | |
| 	input CEC, RSTC,
 | |
| 	input CECTRL, RSTCTRL,
 | |
| 	input SIGNED,
 | |
| 	input RSTPIPE, CEPIPE,
 | |
| 	input RSTOUT, CEOUT,
 | |
| 	input LOADC,
 | |
| 	input [3:0] ADDSUB,
 | |
| 	output [53:0] Z
 | |
| );
 | |
| 	wire [17:0] m0, m1, m2, m3;
 | |
| 
 | |
| 	localparam M_WIDTH = 18;
 | |
| 	localparam Z_WIDTH = 54;
 | |
| 
 | |
| 	MULT9X9 #(
 | |
| 		.REGINPUTA(REGINPUTAB0), .REGINPUTB(REGINPUTAB0), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE)
 | |
| 	) m9_0 (
 | |
| 		.A(A0), .B(B0), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA0A1), .RSTA(RSTA0A1),
 | |
| 		.CEB(CEB0B1), .RSTB(RSTB0B1),
 | |
| 		.CEOUT(CEPIPE), .RSTOUT(RSTPIPE),
 | |
| 		.Z(m0)
 | |
| 	);
 | |
| 	MULT9X9 #(
 | |
| 		.REGINPUTA(REGINPUTAB1), .REGINPUTB(REGINPUTAB1), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE)
 | |
| 	) m9_1 (
 | |
| 		.A(A1), .B(B1), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA0A1), .RSTA(RSTA0A1),
 | |
| 		.CEB(CEB0B1), .RSTB(RSTB0B1),
 | |
| 		.CEOUT(CEPIPE), .RSTOUT(RSTPIPE),
 | |
| 		.Z(m1)
 | |
| 	);
 | |
| 	MULT9X9 #(
 | |
| 		.REGINPUTA(REGINPUTAB2), .REGINPUTB(REGINPUTAB2), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE)
 | |
| 	) m9_2 (
 | |
| 		.A(A2), .B(B2), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA2A3), .RSTA(RSTA2A3),
 | |
| 		.CEB(CEB2B3), .RSTB(RSTB2B3),
 | |
| 		.CEOUT(CEPIPE), .RSTOUT(RSTPIPE),
 | |
| 		.Z(m2)
 | |
| 	);
 | |
| 	MULT9X9 #(
 | |
| 		.REGINPUTA(REGINPUTAB3), .REGINPUTB(REGINPUTAB3), .REGOUTPUT(REGPIPELINE), .GSR(GSR), .RESETMODE(RESETMODE)
 | |
| 	) m9_3 (
 | |
| 		.A(A3), .B(B3), .SIGNEDA(SIGNED), .SIGNEDB(SIGNED),
 | |
| 		.CLK(CLK),
 | |
| 		.CEA(CEA2A3), .RSTA(RSTA2A3),
 | |
| 		.CEB(CEB2B3), .RSTB(RSTB2B3),
 | |
| 		.CEOUT(CEPIPE), .RSTOUT(RSTPIPE),
 | |
| 		.Z(m3)
 | |
| 	);
 | |
| 
 | |
| 	wire [53:0] c_r, c_r2;
 | |
| 	wire [3:0] addsub_r, addsub_r2;
 | |
| 	wire sgd_r, sgd_r2, csgd_r, csgd_r2;
 | |
| 	wire loadc_r, loadc_r2;
 | |
| 
 | |
| 	OXIDE_DSP_REG #(5, REGADDSUB, RESETMODE) addsub_reg(CLK, CECTRL, RSTCTRL, {SIGNED, ADDSUB}, {sgd_r, addsub_r});
 | |
| 	OXIDE_DSP_REG #(5, REGADDSUB, RESETMODE) addsub2_reg(CLK, CECTRL, RSTCTRL, {sgd_r, addsub_r}, {sgd_r2, addsub_r2});
 | |
| 
 | |
| 	OXIDE_DSP_REG #(1, REGLOADC, RESETMODE) loadc_reg(CLK, CECTRL, RSTCTRL, LOADC, loadc_r);
 | |
| 	OXIDE_DSP_REG #(1, REGLOADC2, RESETMODE) loadc2_reg(CLK, CECTRL, RSTCTRL, loadc_r, loadc_r2);
 | |
| 
 | |
| 	OXIDE_DSP_REG #(55, REGINPUTC, RESETMODE) c_reg(CLK, CEC, RSTC, {SIGNED, C}, {csgd_r, c_r});
 | |
| 	OXIDE_DSP_REG #(55, REGPIPELINE, RESETMODE) c2_reg(CLK, CEC, RSTC, {csgd_r, c_r}, {csgd_r2, c_r2});
 | |
| 
 | |
| 
 | |
| 	wire [18:0] m0_ext, m1_ext, m2_ext, m3_ext;
 | |
| 
 | |
| 	assign m0_ext = {sgd_r2 ? m0[M_WIDTH-1] : 1'b0, m0};
 | |
| 	assign m1_ext = {sgd_r2 ? m1[M_WIDTH-1] : 1'b0, m1};
 | |
| 	assign m2_ext = {sgd_r2 ? m2[M_WIDTH-1] : 1'b0, m2};
 | |
| 	assign m3_ext = {sgd_r2 ? m3[M_WIDTH-1] : 1'b0, m3};
 | |
| 
 | |
| 	wire [18:0] s0 = addsub_r2[2] ? (m0_ext - m1_ext) : (m0_ext + m1_ext);
 | |
| 	wire [18:0] s1 = addsub_r2[3] ? (m2_ext - m3_ext) : (m2_ext + m3_ext);
 | |
| 
 | |
| 	wire [53:0] s0_ext = {{(54-19){sgd_r2 ? s0[18] : 1'b0}}, s0};
 | |
| 	wire [53:0] s1_ext = {{(54-19){sgd_r2 ? s1[18] : 1'b0}}, s1};
 | |
| 
 | |
| 	wire [53:0] c_op = loadc_r2 ? c_r2 : Z;
 | |
| 
 | |
| 	// The diagram in the docs is wrong! It is not two cascaded 2-input add/subs as shown,
 | |
| 	// but a three-input unit with negation controls on two inputs (i.e. addsub_r2[0]
 | |
| 	// negates s1 not (s1 +/- s0))
 | |
| 	wire [53:0] z_d =  c_op + (addsub_r2[0] ? -s1_ext : s1_ext) + (addsub_r2[1] ? -s0_ext : s0_ext);
 | |
| 
 | |
| 	OXIDE_DSP_REG #(Z_WIDTH, REGOUTPUT, RESETMODE) z_reg(CLK, CEOUT, RSTOUT, z_d, Z);
 | |
| 
 | |
| endmodule
 |