forked from JCScheunemann/Multiplicador-Booth
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtb_multipliers.v
167 lines (141 loc) · 6.61 KB
/
tb_multipliers.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*************************************************************************
* Multiplier Testbench *
* This testbench tests multiplications with basics and randons values *
* *
* Developer: Mateus Beck Fonseca Oct, 13, 2009 *
* [email protected] V. 2 *
* Corrector: Marlon Soares Sigales Oct, 14, 2015 *
* [email protected] V. 3 *
*************************************************************************/
`timescale 1 ns / 1 ns
module tb_multipliers;
// Defining parameters size
localparam integer PERIOD = 10; //clk period
parameter integer
TAM = 16 , // bits size of operators
NULO = 0 , // zero
UM_POS = 1 , // one
UM_NEG = 2 , // minus one
ALEATORIO = 3 ; // random numbers
integer i ; // counter for loop
// Signal declarations
// inputs to the DUT
reg signed [TAM-1:0] A ;
reg signed [TAM-1:0] B ;
// outputs to the DUT
wire signed [TAM*2-1:0] S;
// local internal signals
reg clk;
reg alow_random ; // flag to alow or not random multiplication
reg [45*8:1] message ; // Define a vector with 8 bits for each ASCII character
reg signed [TAM-1:0]
value_A, value_B ; // alocation for random values
wire [TAM*2-1:0] // basic values declarations need 2*TAM for tool calculations
ZERO = {(TAM*2-1){1'b0}}, //- zero -> 0...16'b0000
POS_ONE = {ZERO,1'b1}, // 1 -> one ... 16'b0001
NEG_ONE = {(TAM*2){1'b1}}; // -1 -> minus one...16'hFFFF
reg signed [TAM*2-1:0] S_test ; // result of multiplicaton test
// Multiplier instantiation
/*booth4*/booth4 #(.TAM(TAM))DUT ( // replace "array_m2_vector" by the entity name in VHDL
// booth4beta #(.TAM(TAM))DUT (
//booth4 DUT (
.A ( A ) , // .name_hear (name_instance)
.B ( B ) ,
.S ( S )
);
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// clk generation
initial clk = 1'b0;
always #(PERIOD/2) clk = ~clk;
// random value generation
always @(negedge clk) // one diferent value ate each negative edge clock
begin
if ( alow_random )
begin
/*random comand sintax:
min + {$random(seed)}%(max-min+1) or can use $dist_uniform(seed, min, max) */
value_A <= 16'h1 + {$random}%(16'hFFFF) ;
value_B <= 0 + {$random}%(65536) ;
end
end
// messages display
always @(message) // every check have message
begin
$display (" %s ", message);
//$stop; // this command may cause trouble in Mentor, just coment
end
// ------------------------ Apply stimulus ---------------------------------------------------------------
initial // sempre em um initial eh sequencial e nao acontecem ao mesmo tempo
begin
@(posedge clk) alow_random = 0; // disable ramdom values,
calculate (POS_ONE, POS_ONE); // 1 x 1 = 1!
@(negedge clk) check_out (UM_POS);
repeat(2) @(posedge clk);
calculate (NEG_ONE, POS_ONE); // -1 x 1 = -1!
@(negedge clk) check_out (UM_NEG);
repeat(2) @(posedge clk);
calculate (POS_ONE, NEG_ONE); // 1 x -1 = -1!
@(negedge clk) check_out (UM_NEG);
repeat(2) @(posedge clk);
calculate (NEG_ONE, NEG_ONE); // -1 x -1 = 1!
@(negedge clk) check_out (UM_POS);
repeat(2) @(posedge clk);
calculate (ZERO, POS_ONE); // 0 x 1 = 0!
@(negedge clk) check_out (NULO);
repeat(2) @(posedge clk);
calculate (NEG_ONE, ZERO); // -1 x 0 = 0!
@(negedge clk) check_out (NULO);
// random values
@(posedge clk) alow_random = 1; // alow random values
for (i=0; i <= 20; i=i+1)
begin
repeat(2) @(posedge clk); // wait for some clocks
calculate (value_A, value_B); // random inputs
@(negedge clk) check_out (ALEATORIO); // compare with tool calculation
end
end // --------------------end stimulus --------------------------------------------------------------------------
// tasks and functions -----------------------------------------------------------------------------------------------
task calculate (input reg [TAM*2-1:0] a, input reg [TAM*2-1:0] b); // input values to calculate in the DUT
begin
A = a; // A[TAM] but a[TAM*2] so => truncate!
B = b;
// HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
S_test = a*b; // need to improve this, tool don't use complement of two for 16 bits, only 32!!!-------------------
// HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
end
endtask
task check_out ( input integer expected ); // 0=ZERO; 1= ONE; 2= MINUS ONE; 3= random inputs in multiplicator, must compare.
begin
case (expected)
NULO : if (S !== 0 || S !== S_test )
begin
message = "***** Expected zero ***** MULTIPLIER TEST FAILED ";
$display($time,S," | ",S_test);
end
else
message = " MULTIPLIER ZERO TEST PASSED ";
UM_POS : if ( S !== 1 || S !== S_test ) begin
message = "***** Expected one ****** MULTIPLIER TEST FAILED ";
$display($time,S," | ",S_test);
end
else
message = " MULTIPLIER ONE TEST PASSED ";
UM_NEG : if ( S !== {(TAM*2){1'b1}} || S !== S_test ) begin
message = "***** Expected minus one ***** MULTIPLIER TEST FAILED";
$display($time,S," | ",S_test);
end
else
message = " MULTIPLIER MINUS ONE TEST PASSED ";
ALEATORIO : if ( S !== S_test ) begin
message = "***** RANDOM NUMBERS ***** TEST FAILED ";
$display("xxxxxxxxxxxxxxxxxxxxx",$time," ",S," | ",S_test);
end
else begin
message = " MULTIPLIER RANDOM TEST PASSED ";
//$display(">>>>>>>>>Passou ",$time,"::::: ",A,"*",B," = ",S," | ",S_test);
end
default: message = " MULTIPLIER BASIC TEST PASSED ";
endcase
end
endtask
endmodule