-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgcd_tb.v
158 lines (144 loc) · 2.85 KB
/
gcd_tb.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
module GCD_test;
reg [15:0] data_in;
reg clk, start;
wire done;
reg [15:0] A, B;
GCD_datapath DP (gt, lt, eq, ldA, ldB, sel1, sel2, sel_in, data_in, clk);
controller CON (ldA, ldB, sel1, sel2, sel_in, done, clk, lt, gt, eq, start);
initial
begin
clk = 1'b0;
#3 start = 1'b1;
#1000 $finish;
end
always #5 clk = ~clk;
initial
begin
#12 data_in = 143;
#10 data_in = 78;
end
initial
begin
$monitor ($time, " %d %b", DP.Aout, done);
end
endmodule
module GCD_datapath (gt, lt, eq, ldA, ldB, sel1, sel2, sel_in,data_in, clk);
input ldA, ldB, sel1, sel2, sel_in, clk;
input [15:0] data_in;
output gt, lt, eq;
wire [15:0] Aout, Bout, X, Y, Bus, SubOut;
PIPO A (Aout, Bus, ldA, clk);
PIPO B (Bout, Bus, ldB, clk);
MUX MUX_in1 (X, Aout, Bout, sel1);
MUX MUX_in2 (Y, Aout, Bout, sel2);
MUX MUX_load (Bus, SubOut, data_in, sel_in);
SUB SB (SubOut, X, Y);
COMPARE COMP (lt, gt, eq, Aout, Bout);
endmodule
module PIPO (data_out, data_in,
load, clk);
input [15:0] data_in;
input load, clk;
output reg [15:0] data_out;
always @(posedge clk)
if (load) data_out <= data_in;
endmodule
module SUB (out, in1, in2);
input [15:0] in1, in2;
output reg [15:0] out;
always @(*)
out = in1 - in2;
endmodule
module COMPARE (lt, gt, eq, data1,
data2);
input [15:0] data1, data2;
output lt, gt, eq;
assign lt = data1 < data2;
assign gt = data1 > data2;
assign eq = data1 == data2;
endmodule
module MUX (out, in0, in1, sel);
input [15:0] in0, in1;
input sel;
output [15:0] out;
assign out = sel ? in1 : in0;
endmodule
module controller (ldA, ldB, sel1, sel2, sel_in, done, clk, lt, gt, eq, start);
input clk, lt, gt, eq, start;
output reg ldA, ldB, sel1, sel2, sel_in, done;
reg [2:0] state;
parameter S0=3'b000, S1=3'b001, S2=3'b010, S3=3'b011, S4=3'b100, S5=3'b101;
always @(posedge clk)
begin
case (state)
S0:
if (start) state <= S1;
S1:
state <= S2;
S2:
#2 if (eq) state <= S5;
else if (lt) state <= S3;
else if (gt) state <= S4;
S3:
#2 if (eq) state <= S5;
else if (lt) state <= S3;
else if (gt) state <= S4;
S4:
#2 if (eq) state <= S5;
else if (lt) state <= S3;
else if (gt) state <= S4;
S5:
state <= S5;
default: state <= S0;
endcase
end
always @(state)
begin
case (state)
S0:
begin sel_in = 1; ldA = 1; ldB = 0; done = 0; end
S1:
begin sel_in = 1; ldA = 0; ldB = 1; end
S2:
if (eq) done= 1;
else if (lt)
begin
sel1 = 1; sel2 = 0; sel_in = 0;
#1 ldA = 0; ldB = 1;
end
else if (gt)
begin
sel1 = 0; sel2 = 1; sel_in = 0;
#1 ldA = 1; ldB = 0;
end
S3:
if (eq) done = 1;
else if (lt)
begin
sel1 = 1; sel2 = 0; sel_in = 0;
#1 ldA = 0; ldB = 1;
end
else if (gt)
begin
sel1 = 0; sel2 = 1; sel_in = 0;
#1 ldA = 1; ldB = 0;
end
S4:
if (eq) done = 1;
else if (lt) begin
sel1 = 1; sel2 = 0; sel_in = 0;
#1 ldA = 0; ldB = 1;
end
else if (gt) begin
sel1 = 0; sel2 = 1; sel_in = 0;
#1 ldA = 1; ldB = 0;
end
S5:
begin
done = 1; sel1 = 0; sel2 = 0; ldA = 0;
ldB = 0;
end
default: begin ldA = 0; ldB = 0; end
endcase
end
endmodule