Skip to content

Instantly share code, notes, and snippets.

@ZipCPU
Created March 23, 2017 12:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZipCPU/40117a78f403b533d8de04e521f21236 to your computer and use it in GitHub Desktop.
Save ZipCPU/40117a78f403b533d8de04e521f21236 to your computer and use it in GitHub Desktop.
///////////////////////////////////////////////////////////////////////////
//
// Filename: sgnmpy_16x16.v
//
// Project: A simple, better, multiply generator
//
// Purpose: This verilog file multiplies two numbers together, without
// using any hardware acceleration. The file itself is
// computer generated, so please (for your sake) don't
// make any edits to the file lest you regenerate it and
// they be lost.
//
//
// Creator: Dan Gisselquist, Ph.D.
// Gisselquist Tecnology, LLC
//
///////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program. If not, see <http://www.gnu.org/licenses/> for a
// copy.
//
// License: GPL, v3, as defined and found on www.gnu.org,
// http://www.gnu.org/licenses/gpl.html
//
//
///////////////////////////////////////////////////////////////////////////
module sgnmpy_16x16(i_clk, i_rst, i_ce, i_a, i_b, i_aux, o_p, o_aux);
parameter NA=16, NB=16;
input i_clk, i_rst, i_ce;
input signed [(NA-1):0] i_a;
input signed [(NB-1):0] i_b;
input i_aux;
output reg signed [(NA+NB-1):0] o_p;
output reg o_aux;
// Clock zero: build our Tableau only.
// There will be one row for every bit in i_a, and each
// row will contain one more bit than i_b, to allow
// for signed arithmetic manipulation.
//
wire [NB:0] S_0_00;
wire [NB:0] S_0_01;
wire [NB:0] S_0_02;
wire [NB:0] S_0_03;
wire [NB:0] S_0_04;
wire [NB:0] S_0_05;
wire [NB:0] S_0_06;
wire [NB:0] S_0_07;
wire [NB:0] S_0_08;
wire [NB:0] S_0_09;
wire [NB:0] S_0_10;
wire [NB:0] S_0_11;
wire [NB:0] S_0_12;
wire [NB:0] S_0_13;
wire [NB:0] S_0_14;
wire [NB:0] S_0_15;
wire A_0;
assign S_0_00 = { 1'b1, {(i_a[0])?(~i_b[NB-1]):1'b1},
(i_a[0])?i_b[NB-2:0]:{(NB-1){1'b0}} };
assign S_0_01 = { 1'b0, ((i_a[1])?(~i_b[(NB-1)]):1'b1),
((i_a[1]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_02 = { 1'b0, ((i_a[2])?(~i_b[(NB-1)]):1'b1),
((i_a[2]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_03 = { 1'b0, ((i_a[3])?(~i_b[(NB-1)]):1'b1),
((i_a[3]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_04 = { 1'b0, ((i_a[4])?(~i_b[(NB-1)]):1'b1),
((i_a[4]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_05 = { 1'b0, ((i_a[5])?(~i_b[(NB-1)]):1'b1),
((i_a[5]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_06 = { 1'b0, ((i_a[6])?(~i_b[(NB-1)]):1'b1),
((i_a[6]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_07 = { 1'b0, ((i_a[7])?(~i_b[(NB-1)]):1'b1),
((i_a[7]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_08 = { 1'b0, ((i_a[8])?(~i_b[(NB-1)]):1'b1),
((i_a[8]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_09 = { 1'b0, ((i_a[9])?(~i_b[(NB-1)]):1'b1),
((i_a[9]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_10 = { 1'b0, ((i_a[10])?(~i_b[(NB-1)]):1'b1),
((i_a[10]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_11 = { 1'b0, ((i_a[11])?(~i_b[(NB-1)]):1'b1),
((i_a[11]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_12 = { 1'b0, ((i_a[12])?(~i_b[(NB-1)]):1'b1),
((i_a[12]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_13 = { 1'b0, ((i_a[13])?(~i_b[(NB-1)]):1'b1),
((i_a[13]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_14 = { 1'b0, ((i_a[14])?(~i_b[(NB-1)]):1'b1),
((i_a[14]) ? i_b[(NB-2):0] : {(NB-1){1'b0}}) };
assign S_0_15 = { 1'b1, ((i_a[15])?i_b[NB-1]:1'b0),
((i_a[15])?(~i_b[(NB-2):0]):{(NB-1){1'b1}}) };
assign A_0 = i_aux;
//
// Round #0, clock = 0, nz = 1, nbits = 17, nrows = 16
reg [(19-1):0] S_1_00;
reg [(19-1):0] S_1_01;
reg [(19-1):0] S_1_02;
reg [(19-1):0] S_1_03;
reg [(19-1):0] S_1_04;
reg [(19-1):0] S_1_05;
reg [(19-1):0] S_1_06;
reg [(19-1):0] S_1_07;
reg A_1;
always @(posedge i_clk)
if (i_ce)
begin
S_1_00 <= { 1'b0, S_0_00 } + { S_0_01, 1'b0 };
S_1_01 <= { 1'b0, S_0_02 } + { S_0_03, 1'b0 };
S_1_02 <= { 1'b0, S_0_04 } + { S_0_05, 1'b0 };
S_1_03 <= { 1'b0, S_0_06 } + { S_0_07, 1'b0 };
S_1_04 <= { 1'b0, S_0_08 } + { S_0_09, 1'b0 };
S_1_05 <= { 1'b0, S_0_10 } + { S_0_11, 1'b0 };
S_1_06 <= { 1'b0, S_0_12 } + { S_0_13, 1'b0 };
S_1_07 <= { 1'b0, S_0_14 } + { S_0_15, 1'b0 };
end
always @(posedge i_clk)
if (i_rst)
A_1 <= 1'b0;
else if (i_ce)
A_1 <= A_0;
//
// Round #1, clock = 1, nz = 2, nbits = 19, nrows = 8
reg [(22-1):0] S_2_00;
reg [(22-1):0] S_2_01;
reg [(22-1):0] S_2_02;
reg [(22-1):0] S_2_03;
reg A_2;
always @(posedge i_clk)
if (i_ce)
begin
S_2_00 <= { 2'b0, S_1_00 } + { S_1_01, 2'b0 };
S_2_01 <= { 2'b0, S_1_02 } + { S_1_03, 2'b0 };
S_2_02 <= { 2'b0, S_1_04 } + { S_1_05, 2'b0 };
S_2_03 <= { 2'b0, S_1_06 } + { S_1_07, 2'b0 };
end
always @(posedge i_clk)
if (i_rst)
A_2 <= 1'b0;
else if (i_ce)
A_2 <= A_1;
//
// Round #2, clock = 2, nz = 4, nbits = 22, nrows = 4
reg [(27-1):0] S_3_00;
reg [(27-1):0] S_3_01;
reg A_3;
always @(posedge i_clk)
if (i_ce)
begin
S_3_00 <= { 4'b0, S_2_00 } + { S_2_01, 4'b0 };
S_3_01 <= { 4'b0, S_2_02 } + { S_2_03, 4'b0 };
end
always @(posedge i_clk)
if (i_rst)
A_3 <= 1'b0;
else if (i_ce)
A_3 <= A_2;
//
// Round #3, clock = 3, nz = 8, nbits = 27, nrows = 2
reg [(32-1):0] S_4_00;
reg A_4;
always @(posedge i_clk)
if (i_ce)
begin
S_4_00 <= { 5'b0, S_3_00 } + { S_3_01[23:0], 8'b0 };
end
always @(posedge i_clk)
if (i_rst)
A_4 <= 1'b0;
else if (i_ce)
A_4 <= A_3;
always @(posedge i_clk)
if (i_ce)
o_p <= S_4_00[(NA+NB-1):0];
always @(posedge i_clk)
if (i_rst)
o_aux <= 1'b0;
else if (i_ce)
o_aux <= A_4;
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment