Sample Verilog HDL Code for use with the LeonardoSpectrum 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 194: Design Guidelines for Using DSP Blocks in the LeonardoSpectrum 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) -- Unsigned Multiplication: a*b (Pipeline 3) -- Signed Multiplication: a*b (Pipeline 0) -- Signed Multiplication: a*b (Pipeline 1) -- Signed Multiplication: a*b (Pipeline 2) -- Signed Multiplication: a*b (Pipeline 3) -- 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 ----------------------------------------- Unsigned Multiplication: a*b (Pipeline 3) ----------------------------------------- module lpm_mult_8_inreg_pipereg_outreg_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] mult_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; mult_reg <= mult_out; out <= mult_reg; end endmodule ----------------------------------------- Signed Multiplication: a*b (Pipeline 0) ----------------------------------------- module lpm_mult_8_signed (out, a, b); //Port Declarations output [15:0] out; input [7:0] a; input [7:0] b; assign out = a * `signed b; endmodule ----------------------------------------- Signed Multiplication: a*b (Pipeline 1) ----------------------------------------- module lpm_mult_8_inreg_signed (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 * `signed 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 [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 * `signed b_reg; always@(posedge clk) begin a_reg <= a; b_reg <= b; out <= mult_out; end endmodule ----------------------------------------- Signed Multiplication: a*b (Pipeline 3) ----------------------------------------- module lpm_mult_8_inreg_pipereg_outreg_signed (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] mult_reg; reg [15:0] out; //Wire Declarations wire [15:0] mult_out; assign mult_out = a_reg * `signed b_reg; always@(posedge clk) begin a_reg <= a; b_reg <= b; mult_reg <= mult_out; out <= mult_reg; 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 [32:0] result; input [15:0] dataa; input [15:0] datab; input [15:0] datac; input [15:0] datad; // 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 * `signed datab; assign mult1_result = datac * `signed datad; // This adder can go into the adder in a DSP block assign result = (mult0_result + `signed mult1_result); 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 [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 * `signed datab_reg; assign mult1_result = datac_reg * `signed datad_reg; // This adder can go into the adder in a DSP block assign result = (mult0_result + `signed 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 [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 * `signed datab_reg; assign mult1_result = datac_reg * `signed datad_reg; // This adder can go into the adder in a DSP block assign result = (mult0_result_reg + `signed 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 [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 * `signed datab_reg; assign mult1_result = datac_reg * `signed datad_reg; // This adder can go into the adder in a DSP block assign result_wire = (mult0_result_reg + `signed 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_ACC: a*b + x (Pipeline 1) --------------------------------------------- module altmult_acc_8_outreg_unsigned (dataout, dataa, datab, clk, aclr, clken); //Port Declarations input [7:0] dataa; input [7:0] datab; input clk; input aclr; input clken; output [31:0] dataout; //Register Declarations reg [31:0] dataout; //Wire Declarations wire [15:0] multa; wire [31:0] adder_out; assign multa = dataa * datab; assign adder_out = multa + dataout; always @(posedge clk or posedge aclr) begin if(aclr) begin dataout <= 0; end else if(clken) begin dataout <= adder_out; end end endmodule --------------------------------------------- Unsigned ALTMULT_ACC: a*b + x (Pipeline 2) --------------------------------------------- module altmult_acc_8_inreg_outreg_unsigned (dataout, dataa, datab, clk, aclr, clken); //Port Declarations input [7:0] dataa; input [7:0] datab; input clk; input aclr; input clken; output [31:0] dataout; //Register Declarations reg [31:0] dataout; reg [7:0] dataa_reg; reg [7:0] datab_reg; //Wire Declarations wire [15:0] multa; wire [31:0] adder_out; assign multa = dataa_reg * datab_reg; assign adder_out = multa + dataout; always @(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; dataout <= 0; end else if(clken) begin dataa_reg <= dataa; datab_reg <= datab; dataout <= adder_out; end end endmodule --------------------------------------------- Unsigned ALTMULT_ACC: a*b + x (Pipeline 3) --------------------------------------------- module altmult_acc_8_inreg_pipereg_outreg_unsigned (dataout, dataa, datab, clk, aclr, clken); //Port Declarations input [7:0] dataa; input [7:0] datab; input clk; input aclr; input clken; 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 multa = dataa_reg * datab_reg; assign adder_out = multa_reg + dataout; always @(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; multa_reg <= 0; dataout <= 0; end else if(clken) begin dataa_reg <= dataa; datab_reg <= datab; multa_reg <= multa; dataout <= adder_out; end end endmodule --------------------------------------------- Signed ALTMULT_ACC: a*b + x (Pipeline 1) --------------------------------------------- module altmult_acc_8_outreg_signed (dataout, dataa, datab, clk, aclr, clken); //Port Declarations input [7:0] dataa; input [7:0] datab; input clk; input aclr; input clken; output [31:0] dataout; //Register Declarations reg [31:0] dataout; //Wire Declarations wire [15:0] multa; wire [31:0] adder_out; assign multa = dataa * `signed datab; assign adder_out = multa + `signed dataout; always @(posedge clk or posedge aclr) begin if(aclr) begin dataout <= 0; end else if(clken) begin dataout <= adder_out; end end endmodule --------------------------------------------- Signed ALTMULT_ACC: a*b + x (Pipeline 2) --------------------------------------------- module altmult_acc_8_inreg_outreg_signed (dataout, dataa, datab, clk, aclr, clken); //Port Declarations input [7:0] dataa; input [7:0] datab; input clk; input aclr; input clken; output [31:0] dataout; //Register Declarations reg [31:0] dataout; reg [7:0] dataa_reg; reg [7:0] datab_reg; //Wire Declarations wire [15:0] multa; wire [31:0] adder_out; assign multa = dataa_reg * `signed datab_reg; assign adder_out = multa + `signed dataout; always @(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; dataout <= 0; end else if(clken) begin dataa_reg <= dataa; datab_reg <= datab; dataout <= adder_out; end end endmodule --------------------------------------------- Signed ALTMULT_ACC: a*b + x (Pipeline 3) --------------------------------------------- module altmult_acc_8_inreg_pipereg_outreg_signed (dataout, dataa, datab, clk, aclr, clken); //Port Declarations input [7:0] dataa; input [7:0] datab; input clk; input aclr; input clken; 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 multa = dataa_reg * `signed datab_reg; assign adder_out = multa_reg + `signed dataout; always @(posedge clk or posedge aclr) begin if(aclr) begin dataa_reg <= 0; datab_reg <= 0; multa_reg <= 0; dataout <= 0; end else if(clken) begin dataa_reg <= dataa; datab_reg <= datab; multa_reg <= multa; dataout <= adder_out; end end endmodule