yosys/techlibs/rapidflex/alkaidL/cell_sim_dsp.v

546 lines
10 KiB
Verilog

//-------------------------------------------------
// DSP Primitives
//-------------------------------------------------
//-------------------------------------------------
// Multiply accumulators
module quad_mac12x10 (A0, B0, A1, B1, A2, B2, A3, B3, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
input [0:A_WIDTH-1] A2;
input [0:B_WIDTH-1] B2;
input [0:A_WIDTH-1] A3;
input [0:B_WIDTH-1] B3;
output [0:Y_WIDTH-1] Y;
assign Y = A0 * B0 + A1 * B1 + A2 * B2 + A3 * B3;
endmodule
//-------------------------------------------------
// Multiply accumulators with input registering
module quad_mac12x10_regi (CLK, RSTB, A0, B0, A1, B1, A2, B2, A3, B3, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
input [0:A_WIDTH-1] A2;
input [0:B_WIDTH-1] B2;
input [0:A_WIDTH-1] A3;
input [0:B_WIDTH-1] B3;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A0_reg;
reg [0:B_WIDTH-1] B0_reg;
reg [0:A_WIDTH-1] A1_reg;
reg [0:B_WIDTH-1] B1_reg;
reg [0:A_WIDTH-1] A2_reg;
reg [0:B_WIDTH-1] B2_reg;
reg [0:A_WIDTH-1] A3_reg;
reg [0:B_WIDTH-1] B3_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A0_reg <= 0;
B0_reg <= 0;
A1_reg <= 0;
B1_reg <= 0;
A2_reg <= 0;
B2_reg <= 0;
A3_reg <= 0;
B3_reg <= 0;
end else begin
A0_reg <= A0;
B0_reg <= B0;
A1_reg <= A1;
B1_reg <= B1;
A2_reg <= A2;
B2_reg <= B2;
A3_reg <= A3;
B3_reg <= B3;
end
end
assign Y = A0_reg * B0_reg + A1_reg * B1_reg + A2_reg * B2_reg + A3_reg * B3_reg;
endmodule
//-------------------------------------------------
// Multiply accumulators with output registering
module quad_mac12x10_rego (CLK, RSTB, A0, B0, A1, B1, A2, B2, A3, B3, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
input [0:A_WIDTH-1] A2;
input [0:B_WIDTH-1] B2;
input [0:A_WIDTH-1] A3;
input [0:B_WIDTH-1] B3;
output [0:Y_WIDTH-1] Y;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
Y_reg <= 0;
end else begin
Y_reg <= A0 * B0 + A1 * B1 + A2 * B2 + A3 * B3;
end
end
assign Y = Y_reg;
endmodule
//-------------------------------------------------
// Multiply accumulators with input and output registering
module quad_mac12x10_regio (CLK, RSTB, A0, B0, A1, B1, A2, B2, A3, B3, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
input [0:A_WIDTH-1] A2;
input [0:B_WIDTH-1] B2;
input [0:A_WIDTH-1] A3;
input [0:B_WIDTH-1] B3;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A0_reg;
reg [0:B_WIDTH-1] B0_reg;
reg [0:A_WIDTH-1] A1_reg;
reg [0:B_WIDTH-1] B1_reg;
reg [0:A_WIDTH-1] A2_reg;
reg [0:B_WIDTH-1] B2_reg;
reg [0:A_WIDTH-1] A3_reg;
reg [0:B_WIDTH-1] B3_reg;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A0_reg <= 0;
B0_reg <= 0;
A1_reg <= 0;
B1_reg <= 0;
A2_reg <= 0;
B2_reg <= 0;
A3_reg <= 0;
B3_reg <= 0;
Y_reg <= 0;
end else begin
A0_reg <= A0;
B0_reg <= B0;
A1_reg <= A1;
B1_reg <= B1;
A2_reg <= A2;
B2_reg <= B2;
A3_reg <= A3;
B3_reg <= B3;
Y_reg <= A0_reg * B0_reg + A1_reg * B1_reg + A2_reg * B2_reg + A3_reg * B3_reg;
end
end
assign Y = Y_reg;
endmodule
module quad_mac12x10_dual_output (A0, B0, A1, B1, A2, B2, A3, B3, Y0, Y1);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
input [0:A_WIDTH-1] A2;
input [0:B_WIDTH-1] B2;
input [0:A_WIDTH-1] A3;
input [0:B_WIDTH-1] B3;
output [0:Y_WIDTH-1] Y0;
output [0:Y_WIDTH-1] Y1;
assign Y0 = A0 * B0 + A1 * B1 + A2 * B2 + A3 * B3;
assign Y1 = A2 * B2 + A3 * B3;
endmodule
module mac12x10 (A0, B0, A1, B1, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
output [0:Y_WIDTH-1] Y;
assign Y = A0 * B0 + A1 * B1;
endmodule
module mac12x10_regi (CLK, RSTB, A0, B0, A1, B1, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A0_reg;
reg [0:B_WIDTH-1] B0_reg;
reg [0:A_WIDTH-1] A1_reg;
reg [0:B_WIDTH-1] B1_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A0_reg <= 0;
B0_reg <= 0;
A1_reg <= 0;
B1_reg <= 0;
end else begin
A0_reg <= A0;
B0_reg <= B0;
A1_reg <= A1;
B1_reg <= B1;
end
end
assign Y = A0_reg * B0_reg + A1_reg * B1_reg;
endmodule
module mac12x10_rego (CLK, RSTB, A0, B0, A1, B1, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
output [0:Y_WIDTH-1] Y;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
Y_reg <= 0;
end else begin
Y_reg <= A0 * B0 + A1 * B1;
end
end
assign Y = Y_reg;
endmodule
module mac12x10_regio (CLK, RSTB, A0, B0, A1, B1, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A0;
input [0:B_WIDTH-1] B0;
input [0:A_WIDTH-1] A1;
input [0:B_WIDTH-1] B1;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A0_reg;
reg [0:B_WIDTH-1] B0_reg;
reg [0:A_WIDTH-1] A1_reg;
reg [0:B_WIDTH-1] B1_reg;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A0_reg <= 0;
B0_reg <= 0;
A1_reg <= 0;
B1_reg <= 0;
Y_reg <= 0;
end else begin
A0_reg <= A0;
B0_reg <= B0;
A1_reg <= A1;
B1_reg <= B1;
Y_reg = A0_reg * B0_reg + A1_reg * B1_reg;
end
end
assign Y = Y_reg;
endmodule
//-------------------------------------------------
// Multipliers
module mult12x10 (A, B, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
assign Y = A * B;
endmodule
module mult12x10_regi (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A_reg;
reg [0:B_WIDTH-1] B_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A_reg <= 0;
B_reg <= 0;
end else begin
A_reg <= A;
B_reg <= B;
end
end
assign Y = A_reg * B_reg;
endmodule
module mult12x10_rego (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
Y_reg <= 0;
end else begin
Y_reg <= A * B;
end
end
assign Y = Y_reg;
endmodule
module mult12x10_regio (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A_reg;
reg [0:B_WIDTH-1] B_reg;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A_reg <= 0;
B_reg <= 0;
Y_reg <= 0;
end else begin
A_reg <= A;
B_reg <= B;
Y_reg <= A_reg * B_reg;
end
end
assign Y = Y_reg;
endmodule
module mult24x20 (A, B, Y);
// Parameters
parameter A_WIDTH = 24;
parameter B_WIDTH = 20;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
assign Y = A * B;
endmodule
module mult24x20_regi (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 24;
parameter B_WIDTH = 20;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A_reg;
reg [0:B_WIDTH-1] B_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A_reg <= 0;
B_reg <= 0;
end else begin
A_reg <= A;
B_reg <= B;
end
end
assign Y = A_reg * B_reg;
endmodule
module mult24x20_rego (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 24;
parameter B_WIDTH = 20;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
Y_reg <= 0;
end else begin
Y_reg <= A * B;
end
end
assign Y = Y_reg;
endmodule
module mult24x20_regio (CLK, RSTB, A, B, Y);
// Parameters
parameter A_WIDTH = 24;
parameter B_WIDTH = 20;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input CLK;
input RSTB;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH-1] Y;
reg [0:A_WIDTH-1] A_reg;
reg [0:B_WIDTH-1] B_reg;
reg [0:Y_WIDTH-1] Y_reg;
always @(posedge CLK) begin
if (RSTB == 1'b0) begin
A_reg <= 0;
B_reg <= 0;
Y_reg <= 0;
end else begin
A_reg <= A;
B_reg <= B;
Y_reg <= A_reg * B_reg;
end
end
assign Y = Y_reg;
endmodule
// A half multiplier which only output the most significant 11 bit
module half_mult12x10 (A, B, Y);
// Parameters
parameter A_WIDTH = 12;
parameter B_WIDTH = 10;
parameter Y_WIDTH = A_WIDTH + B_WIDTH;
input [0:A_WIDTH-1] A;
input [0:B_WIDTH-1] B;
output [0:Y_WIDTH/2-1] Y;
wire [0:Y_WIDTH-1] mult_out;
mult12x10 FULL_MULT (.A(A),
.B(B),
.Y(mult_out)
);
assign Y = mult_out[0:Y_WIDTH/2-1];
endmodule