forked from sheldonucr/ucr-eecs168-lab
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgcd_ctrl.v
112 lines (90 loc) · 2.78 KB
/
gcd_ctrl.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
//=========================================================================
// RTL Model of GCD Unit Control
//-------------------------------------------------------------------------
//
module gcdGCDUnitCtrl
(
input clk, reset, operands_val, result_rdy,
input B_zero, A_lt_B,
output reg result_val, operands_rdy,
output reg [1:0] A_mux_sel,
output reg B_mux_sel, A_en, B_en
);
// Describe the control part as a stage machine
// Define state bits
parameter CALC = 2'b00;
parameter IDLE = 2'b10;
parameter DONE = 2'b11;
// Note that the only flip flop in the design is "state",
// nextstate must also be declared as a reg because
// it is reference from the always @* block, even though
// it isn't actually a register and is only a wire
reg [1:0] state;
reg [1:0] nextstate;
// Combinational logic decides what the next stage should be
always @* begin
// Start by defining default values
nextstate = state;// Stay in the same state by default
// Only want to allow A/B registers to take new values when
// we are sure the data on their inputs is valid
A_en = 0;
B_en = 0;
result_val = 0;
operands_rdy = 0;
B_mux_sel = 0;
A_mux_sel = 2'b00;
case (state)
//IDLE STATE
IDLE : begin
operands_rdy = 1;
if(operands_val == 1'b1) begin
nextstate = CALC;
A_en = 1;
B_en = 1;
end else begin
nextstate = IDLE;
end
end
//CALC STATE
CALC : begin
if(A_lt_B == 1'b1) begin
//SWAP
B_mux_sel = 1;
A_mux_sel = 2'b01;
A_en = 1;
B_en = 1;
nextstate = CALC;
end else if (B_zero == 1'b0) begin
//SUBTRACT
A_mux_sel = 2'b10;
A_en = 1;
nextstate = CALC;
end else begin
//DONE
nextstate = DONE;
end
end
//DONE STATE
DONE : begin
// see if outside is ready to take the result
// if so, send it, and say that operands are ready
// to take new values
result_val = 1;
if (result_rdy == 1'b1) begin
nextstate = IDLE;
// if not, stay in this state until the outside is ready for the result
end else begin
nextstate = DONE;
end
end
endcase
end
// Sequential part of design. At each clock edge, advance to the
// nextstate (as determined by combinational logic)
always @(posedge clk) begin
if(reset)
state <= IDLE;
else
state <= nextstate;
end
endmodule