-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlab6part2.v
345 lines (302 loc) · 10.3 KB
/
lab6part2.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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
module main (
input wire CLOCK_50, //On Board 50 MHz
input wire [9:0] SW, // On board Switches
input wire [3:0] KEY, // On board push buttons
output wire [6:0] HEX0, // HEX displays
output wire [6:0] HEX1,
output wire [6:0] HEX2,
output wire [6:0] HEX3,
output wire [6:0] HEX4,
output wire [6:0] HEX5,
output wire [9:0] LEDR, // LEDs
output wire [7:0] x, // VGA pixel coordinates
output wire [6:0] y,
output wire [2:0] colour, // VGA pixel colour (0-7)
output wire plot, // Pixel drawn when this is pulsed
output wire vga_resetn // VGA resets to black when this is pulsed (NOT CURRENTLY AVAILABLE)
);
wire resetn;
wire go;
wire [7:0] data_result;
assign go = ~KEY[1];
assign resetn = KEY[0];
wrapper u0(
.clk(CLOCK_50),
.resetn(resetn),
.go(go),
.data_in(SW[7:0]),
.data_result(data_result)
);
assign LEDR[7:0] = data_result;
hex_decoder H0(
.hex_digit(data_result[3:0]),
.segments(HEX0)
);
hex_decoder H1(
.hex_digit(data_result[7:4]),
.segments(HEX1)
);
endmodule
module wrapper(
input clk,
input resetn,
input go,
input [7:0] data_in,
output [7:0] data_result
);
// lots of wires to connect our datapath and control
wire ld_a, ld_b, ld_c, ld_x, ld_r;
wire ld_alu_out;
wire [1:0] alu_select_a, alu_select_b;
wire alu_op;
control C0(
.clk(clk),
.resetn(resetn),
.go(go),
.ld_alu_out(ld_alu_out),
.ld_x(ld_x),
.ld_a(ld_a),
.ld_b(ld_b),
.ld_c(ld_c),
.ld_r(ld_r),
.alu_select_a(alu_select_a),
.alu_select_b(alu_select_b),
.alu_op(alu_op)
);
datapath D0(
.clk(clk),
.resetn(resetn),
.ld_alu_out(ld_alu_out),
.ld_x(ld_x),
.ld_a(ld_a),
.ld_b(ld_b),
.ld_c(ld_c),
.ld_r(ld_r),
.alu_select_a(alu_select_a),
.alu_select_b(alu_select_b),
.alu_op(alu_op),
.data_in(data_in),
.data_result(data_result)
);
endmodule
module control(
input clk,
input resetn,
input go,
output reg ld_a, ld_b, ld_c, ld_x, ld_r,
output reg ld_alu_out,
output reg [1:0] alu_select_a, alu_select_b,
output reg alu_op
);
reg [5:0] current_state, next_state;
localparam S_LOAD_A = 5'd0,
S_LOAD_A_WAIT = 5'd1,
S_LOAD_B = 5'd2,
S_LOAD_B_WAIT = 5'd3,
S_LOAD_C = 5'd4,
S_LOAD_C_WAIT = 5'd5,
S_LOAD_X = 5'd6,
S_LOAD_X_WAIT = 5'd7,
S_CYCLE_0 = 5'd8,
S_CYCLE_1 = 5'd9,
S_CYCLE_2 = 5'd10,
S_CYCLE_3 = 5'd11,
S_CYCLE_4 = 5'd12;
// Next state logic aka our state table
always@(*)
begin: state_table
case (current_state)
S_LOAD_A: next_state = go ? S_LOAD_A_WAIT : S_LOAD_A; // Loop in current state until value is input
S_LOAD_A_WAIT: next_state = go ? S_LOAD_A_WAIT : S_LOAD_B; // Loop in current state until go signal goes low
S_LOAD_B: next_state = go ? S_LOAD_B_WAIT : S_LOAD_B; // Loop in current state until value is input
S_LOAD_B_WAIT: next_state = go ? S_LOAD_B_WAIT : S_LOAD_C; // Loop in current state until go signal goes low
S_LOAD_C: next_state = go ? S_LOAD_C_WAIT : S_LOAD_C; // Loop in current state until value is input
S_LOAD_C_WAIT: next_state = go ? S_LOAD_C_WAIT : S_LOAD_X; // Loop in current state until go signal goes low
S_LOAD_X: next_state = go ? S_LOAD_X_WAIT : S_LOAD_X; // Loop in current state until value is input
S_LOAD_X_WAIT: next_state = go ? S_LOAD_X_WAIT : S_CYCLE_0; // Loop in current state until go signal goes low
S_CYCLE_0: next_state = S_CYCLE_1;
S_CYCLE_1: next_state = S_CYCLE_2;
S_CYCLE_2: next_state = S_CYCLE_3;
S_CYCLE_3: next_state = S_CYCLE_4;
S_CYCLE_4: next_state = S_LOAD_A; //start over after
default: next_state = S_LOAD_A;
endcase
end // state_table
// Output logic aka all of our datapath control signals
always @(*)
begin: enable_signals
// By default make all our signals 0
ld_alu_out = 1'b0;
ld_a = 1'b0;
ld_b = 1'b0;
ld_c = 1'b0;
ld_x = 1'b0;
ld_r = 1'b0;
alu_select_a = 2'b0;
alu_select_b = 2'b0;
alu_op = 1'b0;
case (current_state)
S_LOAD_A: begin
ld_a = 1'b1;
end
S_LOAD_B: begin
ld_b = 1'b1;
end
S_LOAD_C: begin
ld_c = 1'b1;
end
S_LOAD_X: begin
ld_x = 1'b1;
end
S_CYCLE_0: begin // Do A <- A * x
ld_alu_out = 1'b1; ld_a = 1'b1; // store result back into A
alu_select_a = 2'b00; // Select register A
alu_select_b = 2'b11; // Select register x
alu_op = 1'b1; // Do multiply operation
end
S_CYCLE_1: begin // Do A <- A * x
ld_alu_out = 1'b1; ld_a = 1'b1; // store result back into A
alu_select_a = 2'b00; // Select register A
alu_select_b = 2'b11; // Select register x
alu_op = 1'b1; // Do multiply operation
end
S_CYCLE_2: begin // Do B <- B * x
ld_alu_out = 1'b1; ld_b = 1'b1; // store result back into B
alu_select_a = 2'b01; // Select register B
alu_select_b = 2'b11; // Select register x
alu_op = 1'b1; // Do multiply operation
end
S_CYCLE_3: begin // Do A <- A + B
ld_alu_out = 1'b1; ld_a = 1'b1; //store result into A
alu_select_a = 2'b00; //Select register A
alu_select_b = 2'b01; //Select register B
alu_op = 1'b0; // Do Add operation
end
S_CYCLE_4: begin // Do R <- A + C
ld_r = 1'b1; // store result in result register
alu_select_a = 2'b00; // Select register A
alu_select_b = 2'b10; // Select register C
alu_op = 1'b0; // Do Add operation
end
// default: // don't need default since we already made sure all of our outputs were assigned a value at the start of the always block
endcase
end // enable_signals
// current_state registers
always@(posedge clk)
begin: state_FFs
if(!resetn)
current_state <= S_LOAD_A;
else
current_state <= next_state;
end // state_FFS
endmodule
module datapath(
input clk,
input resetn,
input [7:0] data_in,
input ld_alu_out,
input ld_x, ld_a, ld_b, ld_c,
input ld_r,
input alu_op,
input [1:0] alu_select_a, alu_select_b,
output reg [7:0] data_result
);
// input registers
reg [7:0] a, b, c, x;
// output of the alu
reg [7:0] alu_out;
// alu input muxes
reg [7:0] alu_a, alu_b;
// Registers a, b, c, x with respective input logic
always@(posedge clk) begin
if(!resetn) begin
a <= 8'b0;
b <= 8'b0;
c <= 8'b0;
x <= 8'b0;
end
else begin
if(ld_a)
a <= ld_alu_out ? alu_out : data_in; // load alu_out if load_alu_out signal is high, otherwise load from data_in
if(ld_b)
b <= ld_alu_out ? alu_out : data_in; // load alu_out if load_alu_out signal is high, otherwise load from data_in
if(ld_x)
x <= data_in;
if(ld_c)
c <= data_in;
end
end
// Output result register
always@(posedge clk) begin
if(!resetn) begin
data_result <= 8'b0;
end
else
if(ld_r)
data_result <= alu_out;
end
// The ALU input multiplexers
always @(*)
begin
case (alu_select_a)
2'd0:
alu_a = a;
2'd1:
alu_a = b;
2'd2:
alu_a = c;
2'd3:
alu_a = x;
default: alu_a = 8'b0;
endcase
case (alu_select_b)
2'd0:
alu_b = a;
2'd1:
alu_b = b;
2'd2:
alu_b = c;
2'd3:
alu_b = x;
default: alu_b = 8'b0;
endcase
end
// The ALU
always @(*)
begin : ALU
// alu
case (alu_op)
0: begin
alu_out = alu_a + alu_b; //performs addition
end
1: begin
alu_out = alu_a * alu_b; //performs multiplication
end
default: alu_out = 8'b0;
endcase
end
endmodule
module hex_decoder(hex_digit, segments);
input [3:0] hex_digit;
output reg [6:0] segments;
always @(*)
case (hex_digit)
4'h0: segments = 7'b100_0000;
4'h1: segments = 7'b111_1001;
4'h2: segments = 7'b010_0100;
4'h3: segments = 7'b011_0000;
4'h4: segments = 7'b001_1001;
4'h5: segments = 7'b001_0010;
4'h6: segments = 7'b000_0010;
4'h7: segments = 7'b111_1000;
4'h8: segments = 7'b000_0000;
4'h9: segments = 7'b001_1000;
4'hA: segments = 7'b000_1000;
4'hB: segments = 7'b000_0011;
4'hC: segments = 7'b100_0110;
4'hD: segments = 7'b010_0001;
4'hE: segments = 7'b000_0110;
4'hF: segments = 7'b000_1110;
default: segments = 7'h7f;
endcase
endmodule