Sample Verilog HDL Code for use with Synplify Software This file contains Verilog HDL code samples that infer the DSP block in the correct operation mode. Note: The syntax is slightly different for signed and unsigned representation. Important: Please see Altera AN 193: Design Guidelines for Using DSP Blocks in the Synplify Software for information on the latency or number of pipeline stages in the design passed on to the Quartus II software using the LPM_PIPELINE parameter. The sample Verilog HDL code is in the following order: -- Unsigned Multiplication: a*b (Pipeline 0) -- Unsigned Multiplication: a*b (Pipeline 1) -- Unsigned Multiplication: a*b (Pipeline 2) -- Signed Multiplication: a*b (Pipeline 0) -- Signed Multiplication: a*b (Pipeline 1) -- Signed Multiplication: a*b (Pipeline 2) -- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 0) -- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 1) -- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 2) -- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 3) -- Signed ALTMULT_ADD: a*b + c*d (Pipeline 0) -- Signed ALTMULT_ADD: a*b + c*d (Pipeline 1) -- Signed ALTMULT_ADD: a*b + c*d (Pipeline 2) -- Signed ALTMULT_ADD: a*b + c*d (Pipeline 3) -- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 1) -- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 2) -- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 3) -- Signed ALTMULT_ACCUM: a*b + x (Pipeline 1) -- Signed ALTMULT_ACCUM: a*b + x (Pipeline 2) -- Signed ALTMULT_ACCUM: a*b + x (Pipeline 3) ----------------------------------------- Unsigned Multiplication: a*b (Pipeline 0) ----------------------------------------- module lpm_mult_8_unsigned (out, a, b); //Port Declarations output [15:0] out; input [7:0] a; input [7:0] b; assign out = a * b; endmodule ----------------------------------------- Unsigned Multiplication: a*b (Pipeline 1) ----------------------------------------- module lpm_mult_8_inreg_unsigned (out, clk, a, b); //Port Declarations output [15:0] out; input clk; input [7:0] a; input [7:0] b; //Register Declarations reg [7:0] a_reg; reg [7:0] b_reg; assign out = a_reg * b_reg; always@(posedge clk) begin a_reg <= a; b_reg <= b; end endmodule ----------------------------------------- Unsigned Multiplication: a*b (Pipeline 2) ----------------------------------------- module lpm_mult_8_inreg_pipereg_unsigned (out, clk, a, b); //Port Declarations output [15:0] out; input clk; input [7:0] a; input [7:0] b; //Register Declarations reg [7:0] a_reg; reg [7:0] b_reg; reg [15:0] out; //Wire Declarations wire [15:0] mult_out; assign mult_out = a_reg * b_reg; always@(posedge clk) begin a_reg <= a; b_reg <= b; out <= mult_out; end endmodule ----------------------------------------- Signed Multiplication: a*b (Pipeline 0) ----------------------------------------- module lpm_mult_8_signed (out, a, b); //Port Declarations output signed [15:0] out; input signed [7:0] a; input signed [7:0] b; assign out = a * b; endmodule ----------------------------------------- Signed Multiplication: a*b (Pipeline 1) ----------------------------------------- module lpm_mult_8_inreg_signed (out, clk, a, b); //Port Declarations output signed [15:0] out; input clk; input signed [7:0] a; input signed [7:0] b; //Register Declarations reg signed [7:0] a_reg; reg signed [7:0] b_reg; assign out = a_reg * b_reg; always@(posedge clk) begin a_reg <= a; b_reg <= b; end endmodule ----------------------------------------- Signed Multiplication: a*b (Pipeline 2) ----------------------------------------- module lpm_mult_8_inreg_pipereg_signed (out, clk, a, b); //Port Declarations output signed [15:0] out; input clk; input signed [7:0] a; input signed [7:0] b; //Register Declarations reg signed [7:0] a_reg; reg signed [7:0] b_reg; reg signed [15:0] out; //Wire Declarations wire signed [15:0] mult_out; assign mult_out = a_reg * b_reg; always@(posedge clk) begin a_reg <= a; b_reg <= b; out <= mult_out; end endmodule -------------------------------------------- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 0) -------------------------------------------- module altmult_add_16_unsigned (dataa, datab, datac, datad, result); // Port Declaration input [15:0] dataa; input [15:0] datab; input [15:0] datac; input [15:0] datad; output [32:0] result; // Wire Declaration wire [31:0] mult0_result; wire [31:0] mult1_result; // Implementation // Each of these can go into one of the 4 mults in a DSP Block assign mult0_result = dataa * datab; assign mult1_result = datac * datad; // This adder can go into the adder in a DSP Block assign result = (mult0_result + mult1_result); endmodule -------------------------------------------- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 1) -------------------------------------------- module altmult_add_16_inreg_unsigned ( clk, aclr, clken,dataa, datab, datac, datad, result); // Port Declaration input clk; input aclr; input clken; input [15:0] dataa; input [15:0] datab; input [15:0] datac; input [15:0] datad; output [32:0] result; //Reg Declarations reg [15:0] dataa_reg; reg [15:0] datab_reg; reg [15:0] datac_reg; reg [15:0] datad_reg; // Wire Declaration wire [31:0] mult0_result; wire [31:0] mult1_result; // Implementation // Each of these can go into one of the 4 mults in a DSP Block assign mult0_result = dataa_reg * datab_reg; assign mult1_result = datac_reg * datad_reg; // This adder can go into the adder in a DSP Block assign result = (mult0_result + mult1_result); always@(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; datac_reg <= 0; datad_reg <= 0; end else if(clken) begin dataa_reg <= dataa; datab_reg <= datab; datac_reg <= datac; datad_reg <= datad; end end endmodule -------------------------------------------- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 2) -------------------------------------------- module altmult_add_16_inreg_pipereg_unsigned ( clk, aclr, clken, dataa, datab, datac, datad, result); // Port Declaration input clk; input aclr; input clken; input [15:0] dataa; input [15:0] datab; input [15:0] datac; input [15:0] datad; output [32:0] result; //Reg Declarations reg [15:0] dataa_reg; reg [15:0] datab_reg; reg [15:0] datac_reg; reg [15:0] datad_reg; reg [31:0] mult0_result_reg; reg [31:0] mult1_result_reg; // Wire Declaration wire [31:0] mult0_result; wire [31:0] mult1_result; // Implementation // Each of these can go into one of the 4 mults in a DSP Block assign mult0_result = dataa_reg * datab_reg; assign mult1_result = datac_reg * datad_reg; // This adder can go into the adder in a DSP Block assign result = (mult0_result_reg + mult1_result_reg); always@(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; datac_reg <= 0; datad_reg <= 0; mult0_result_reg <= 0; mult1_result_reg <= 0; end else if(clken) begin dataa_reg <= dataa; datab_reg <= datab; datac_reg <= datac; datad_reg <= datad; mult0_result_reg <= mult0_result; mult1_result_reg <= mult1_result; end end endmodule -------------------------------------------- Unsigned ALTMULT_ADD: a*b + c*d (Pipeline 3) -------------------------------------------- module altmult_add_16_inreg_pipereg_outreg_unsigned ( clk, aclr, clken, dataa, datab, datac, datad, result); // Port Declaration input clk; input aclr; input clken; input [15:0] dataa; input [15:0] datab; input [15:0] datac; input [15:0] datad; output [32:0] result; //Reg Declarations reg [15:0] dataa_reg; reg [15:0] datab_reg; reg [15:0] datac_reg; reg [15:0] datad_reg; reg [31:0] mult0_result_reg; reg [31:0] mult1_result_reg; reg [32:0] result; // Wire Declaration wire [31:0] mult0_result; wire [31:0] mult1_result; wire [32:0] result_wire; // Implementation // Each of these can go into one of the 4 mults in a DSP Block assign mult0_result = dataa_reg * datab_reg; assign mult1_result = datac_reg * datad_reg; // This adder can go into the adder in a DSP Block assign result_wire = (mult0_result_reg + mult1_result_reg); always@(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; datac_reg <= 0; datad_reg <= 0; mult0_result_reg <= 0; mult1_result_reg <= 0; result <= 0; end else if(clken) begin dataa_reg <= dataa; datab_reg <= datab; datac_reg <= datac; datad_reg <= datad; mult0_result_reg <= mult0_result; mult1_result_reg <= mult1_result; result <= result_wire; end end endmodule -------------------------------------------- Signed ALTMULT_ADD: a*b + c*d (Pipeline 0) -------------------------------------------- module altmult_add_16_signed ( dataa, datab, datac, datad, result); // Port Declaration output signed [32:0] result; input signed [15:0] dataa; input signed [15:0] datab; input signed [15:0] datac; input signed [15:0] datad; // Wire Declaration wire signed [31:0] mult0_result; wire signed [31:0] mult1_result; // Implementation // Each of these can go into one of the 4 mults in a DSP Block assign mult0_result = dataa * datab; assign mult1_result = datac * datad; // This adder can go into the adder in a DSP Block assign result = (mult0_result) + (mult1_result); //assign result = (dataa * datab) + (datac * datad); endmodule -------------------------------------------- Signed ALTMULT_ADD: a*b + c*d (Pipeline 1) -------------------------------------------- module altmult_add_16_inreg_signed ( clken, aclr, clk, dataa, datab, datac, datad, result); // Port Declaration input clk; input aclr; input clken; input signed [15:0] dataa; input signed [15:0] datab; input signed [15:0] datac; input signed [15:0] datad; output signed [32:0] result; //Reg Declarations reg signed [15:0] dataa_reg; reg signed [15:0] datab_reg; reg signed [15:0] datac_reg; reg signed [15:0] datad_reg; // Wire Declaration wire signed [31:0] mult0_result; wire signed [31:0] mult1_result; // Implementation // Each of these can go into one of the 4 mults in a DSP Block assign mult0_result = dataa_reg * datab_reg; assign mult1_result = datac_reg * datad_reg; // This adder can go into the adder in a DSP Block assign result = (mult0_result + mult1_result); always@(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; datac_reg <= 0; datad_reg <= 0; end else if(clken) begin dataa_reg <= dataa; datab_reg <= datab; datac_reg <= datac; datad_reg <= datad; end end endmodule -------------------------------------------- Signed ALTMULT_ADD: a*b + c*d (Pipeline 2) -------------------------------------------- module altmult_add_16_inreg_pipereg_signed ( clk, aclr, clken, dataa, datab, datac, datad, result); // Port Declaration input clk; input aclr; input clken; input signed [15:0] dataa; input signed [15:0] datab; input signed [15:0] datac; input signed [15:0] datad; output signed [32:0] result; //Reg Declarations reg signed [15:0] dataa_reg; reg signed [15:0] datab_reg; reg signed [15:0] datac_reg; reg signed [15:0] datad_reg; reg signed [31:0] mult0_result_reg; reg signed [31:0] mult1_result_reg; // Wire Declaration wire signed [31:0] mult0_result; wire signed [31:0] mult1_result; // Implementation // Each of these can go into one of the 4 mults in a DSP Block assign mult0_result = dataa_reg * datab_reg; assign mult1_result = datac_reg * datad_reg; // This adder can go into the adder in a DSP Block assign result = (mult0_result_reg + mult1_result_reg); always@(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; datac_reg <= 0; datad_reg <= 0; mult0_result_reg <= 0; mult1_result_reg <= 0; end else if(clken) begin dataa_reg <= dataa; datab_reg <= datab; datac_reg <= datac; datad_reg <= datad; mult0_result_reg <= mult0_result; mult1_result_reg <= mult1_result; end end endmodule -------------------------------------------- Signed ALTMULT_ADD: a*b + c*d (Pipeline 3) -------------------------------------------- module altmult_add_16_inreg_pipereg_outreg_signed ( clk, aclr, clken, dataa, datab, datac, datad, result); // Port Declaration input clk; input aclr; input clken; input signed [15:0] dataa; input signed [15:0] datab; input signed [15:0] datac; input signed [15:0] datad; output signed [32:0] result; //Reg Declarations reg signed [15:0] dataa_reg; reg signed [15:0] datab_reg; reg signed [15:0] datac_reg; reg signed [15:0] datad_reg; reg signed [31:0] mult0_result_reg; reg signed [31:0] mult1_result_reg; reg signed [32:0] result; // Wire Declaration wire signed [31:0] mult0_result; wire signed [31:0] mult1_result; wire signed [32:0] result_wire; // Implementation // Each of these can go into one of the 4 mults in a DSP Block assign mult0_result = dataa_reg * datab_reg; assign mult1_result = datac_reg * datad_reg; // This adder can go into the adder in a DSP Block assign result_wire = (mult0_result_reg + mult1_result_reg); always@(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; datac_reg <= 0; datad_reg <= 0; mult0_result_reg <= 0; mult1_result_reg <= 0; result <= 0; end else if(clken) begin dataa_reg <= dataa; datab_reg <= datab; datac_reg <= datac; datad_reg <= datad; mult0_result_reg <= mult0_result; mult1_result_reg <= mult1_result; result <= result_wire; end end endmodule -------------------------------------------- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 1) -------------------------------------------- module altmult_acc_8_outreg_unsigned (dataout, dataa, datab, clk, rst); //Port Declarations input [7:0] dataa; input [7:0] datab; input clk; input rst; output [31:0] dataout; //Register Declarations reg [31:0] dataout; //Wire Declarations wire [31:0] adder_out; assign adder_out = dataa * datab + dataout; always @(posedge clk or posedge rst) begin if(rst) dataout <= 0; else dataout <= adder_out; end endmodule -------------------------------------------- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 2) -------------------------------------------- module altmult_acc_8_inreg_outreg_unsigned (dataout, dataa, datab, clk, aclr); //Port Declarations input [7:0] dataa; input [7:0] datab; input clk; input aclr; output [31:0] dataout; //Register Declarations reg [31:0] dataout; reg [7:0] dataa_reg; reg [7:0] datab_reg; //Wire Declarations wire [31:0] adder_out; assign adder_out = dataa_reg * datab_reg + dataout; always @(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; dataout <= 0; end else begin dataa_reg <= dataa; datab_reg <= datab; dataout <= adder_out; end end endmodule -------------------------------------------- Unsigned ALTMULT_ACCUM: a*b + x (Pipeline 3) -------------------------------------------- module altmult_acc_8_inreg_pipereg_outreg_unsigned (dataout, dataa, datab, clk, aclr); //Port Declarations input [7:0] dataa; input [7:0] datab; input clk; input aclr; output [31:0] dataout; //Register Declarations reg [31:0] dataout; reg [7:0] dataa_reg; reg [7:0] datab_reg; reg [15:0] multa_reg; //Wire Declarations wire [15:0] multa; wire [31:0] adder_out; assign adder_out = dataa_reg * datab_reg + dataout; always @(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; multa_reg <= 0; dataout <= 0; end begin dataa_reg <= dataa; datab_reg <= datab; multa_reg <= multa; dataout <= adder_out; end end endmodule -------------------------------------------- Signed ALTMULT_ACCUM: a*b + x (Pipeline 1) -------------------------------------------- module altmult_acc_8_outreg_signed (dataout, dataa, datab, clk, aclr); //Port Declarations input signed [7:0] dataa; input signed [7:0] datab; input clk; input aclr; output signed [31:0] dataout; //Register Declarations reg signed [31:0] dataout; //Wire Declarations wire signed [31:0] adder_out; assign adder_out = dataa * datab + dataout; always @(posedge clk or posedge aclr) begin if(aclr) dataout <= 0; else dataout <= adder_out; end endmodule -------------------------------------------- Signed ALTMULT_ACCUM: a*b + x (Pipeline 2) -------------------------------------------- module altmult_acc_8_inreg_outreg_signed (dataout, dataa, datab, clk, aclr); //Port Declarations input signed [7:0] dataa; input signed [7:0] datab; input clk; input aclr; output signed [31:0] dataout; //Register Declarations reg signed [31:0] dataout; reg signed [7:0] dataa_reg; reg signed [7:0] datab_reg; //Wire Declarations wire signed [31:0] adder_out; assign adder_out = dataa_reg * datab_reg + dataout; always @(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; dataout <= 0; end else begin dataa_reg <= dataa; datab_reg <= datab; dataout <= adder_out; end end endmodule -------------------------------------------- Signed ALTMULT_ACCUM: a*b + x (Pipeline 3) -------------------------------------------- module altmult_acc_8_inreg_pipereg_outreg_signed (dataout, dataa, datab, clk, aclr); //Port Declarations input signed [7:0] dataa; input signed [7:0] datab; input clk; input aclr; output signed [31:0] dataout; //Register Declarations reg signed [31:0] dataout; reg signed [7:0] dataa_reg; reg signed [7:0] datab_reg; reg signed [15:0] multa_reg; //Wire Declarations wire signed [15:0] multa; wire signed [31:0] adder_out; assign adder_out = dataa_reg * datab_reg + dataout; always @(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; multa_reg <= 0; dataout <= 0; end begin dataa_reg <= dataa; datab_reg <= datab; multa_reg <= multa; dataout <= adder_out; end end endmodule