Added serial/parallel multiplier.

This commit is contained in:
Niels Moseley 2017-10-10 02:27:48 +02:00
parent 1d624a482a
commit 4f30621f28
5 changed files with 204 additions and 1 deletions

View File

@ -7,7 +7,7 @@
module PWMDAC_TB;
reg clk, rst_an;
reg signed [0:7] din;
reg signed [7:0] din;
wire dacout, din_ack;
real accu;

View File

@ -1,4 +1,5 @@
mkdir bin
del bin\pwmdac.vvp
C:\iverilog\bin\iverilog -o bin\pwmdac.vvp -m va_math -g2005 -s PWMDAC_TB pwmdac.v pwmdac_tb.v
cd bin
C:\iverilog\bin\vvp pwmdac.vvp

6
verilog/spmul/run_tb.bat Normal file
View File

@ -0,0 +1,6 @@
mkdir bin
del bin\spmul.vvp
C:\iverilog\bin\iverilog -o bin\spmul.vvp -m va_math -g2005 -s SPMUL_TB spmul.v spmul_tb.v
cd bin
C:\iverilog\bin\vvp spmul.vvp
cd ..

148
verilog/spmul/spmul.v Normal file
View File

@ -0,0 +1,148 @@
//
// 16bit x 10bit signed serial/parallel multiplier.
//
// Niels Moseley - Moseley Instruments 2017
// http://www.moseleyinstruments.com
//
//
//
module SPMUL (
clk,
rst_an,
sig_in,
coef_in,
result_out,
start,
done
);
//////////// CLOCK //////////
input clk;
//////////// RESET, ACTIVE LOW //////////
input rst_an;
//////////// MULTIPLIER INPUTS //////////
input signed [15:0] sig_in;
input signed [9:0] coef_in;
input start;
//////////// MULTIPLIER OUTPUT //////////
output reg signed [15:0] result_out;
output reg done;
//////////// internal signals //////////
reg signed [24:0] accumulator;
reg signed [9:0] coefreg;
reg signed [15:0] sigreg;
reg [3:0] state; // state machine state
wire signed [15:0] bmul;
reg domul,accu_clr;
// accumulator
always @(posedge clk, negedge rst_an)
begin
if ((rst_an == 0) || (accu_clr == 1))
begin
accumulator <= 0;
end
else if (domul == 1)
begin
if (coefreg[9] == 1'b1)
accumulator <= {accumulator[23:0], 1'b0} + sigreg;
else
accumulator <= {accumulator[23:0], 1'b0};
coefreg <= {coefreg[8:0], 1'b0};
end
end
always @(posedge clk, negedge rst_an)
begin
if (rst_an == 0)
begin
// reset values
result_out <= 0;
done <= 0;
coefreg <= 0;
sigreg <= 0;
state <= 0;
domul <= 0;
accu_clr <= 1;
end
else
begin
// default values
accu_clr <= 0;
done <= 0;
domul <= 0;
state <= state + 4'b0001;
casex(state)
4'b0000:
begin
coefreg <= coef_in;
sigreg <= sig_in;
accu_clr <= 1;
if (start == 1)
begin
state <= 4'b0001;
end
else
state <= 4'b0000;
end
4'b0001:
begin
domul <= 1;
end
4'b0010:
begin
domul <= 1;
end
4'b0011:
begin
domul <= 1;
end
4'b0100:
begin
domul <= 1;
end
4'b0101:
begin
domul <= 1;
end
4'b0110:
begin
domul <= 1;
end
4'b0111:
begin
domul <= 1;
end
4'b1000:
begin
domul <= 1;
end
4'b1001:
begin
domul <= 1;
end
4'b1010:
begin
domul <= 1;
end
4'b1011:
begin
domul <= 0;
done <= 1;
result_out <= accumulator[23:8];
state <= 0;
end
default:
state <= 0;
endcase
end
end
endmodule

48
verilog/spmul/spmul_tb.v Normal file
View File

@ -0,0 +1,48 @@
//
// SPMUL testbench
//
// Niels Moseley - Moseley Instruments 2017
// http://www.moseleyinstruments.com
//
module SPMUL_TB;
reg clk, rst_an, start;
reg signed [15:0] sig;
reg signed [9:0] coef;
wire signed [15:0] result;
wire done;
SPMUL u_spmul (
.clk (clk),
.rst_an (rst_an),
.sig_in (sig),
.coef_in (coef),
.result_out (result),
.start (start),
.done (done)
);
initial
begin
$dumpfile ("spmul.vcd");
$dumpvars;
clk = 0;
rst_an = 0;
sig = 16'h7FFF;
coef = 10'h1FF;
start = 0;
#3
rst_an = 1;
#3
start = 1;
#1024;
end
always
#5 clk = !clk;
always @(posedge done)
if (done == 1)
$finish;
endmodule