forked from deoregaurav92/SystemVerilog_Coding_Practice
-
Notifications
You must be signed in to change notification settings - Fork 0
/
control.sv
161 lines (155 loc) · 5.29 KB
/
control.sv
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
///////////////////////////////////////////////////////////////////////////
// (c) Copyright 2013 Cadence Design Systems, Inc. All Rights Reserved.
//
// File name : control.sv
// Title : Control Module
// Project : SystemVerilog Training
// Created : 2013-4-8
// Description : Defines the Control module
// Notes :
//
///////////////////////////////////////////////////////////////////////////
// import SystemVerilog package for opcode_t and state_t
import typedefs::*;
module control (
output logic load_ac ,
output logic mem_rd ,
output logic mem_wr ,
output logic inc_pc ,
output logic load_pc ,
output logic load_ir ,
output logic halt ,
input opcode_t opcode , // opcode type name must be opcode_t
input zero , // '1' when CPU accumulator is zero and '0' otherwise
input clk ,
input rst_);
// SystemVerilog: time units and time precision specification
timeunit 1ns;
timeprecision 100ps;
state_t ps, ns;
//Present state logic of Mealy machine
always_ff @(posedge clk or negedge rst_)
if (!rst_)
ps <= INST_ADDER;
else
ps <= ps.next();
//Next state logic of Mealy machine
always_comb begin
unique case (ps)
INST_ADDER: begin
ns = state_t '(3'b001);
mem_rd = 1'b0;
load_ir = 1'b0;
halt = 1'b0;
inc_pc = 1'b0;
load_ac = 1'b0;
load_pc = 1'b0;
mem_wr = 1'b0;
end
3'b001 : begin
ns = state_t '(3'b010);
mem_rd = 1'b1;
load_ir = 1'b0;
halt = 1'b0;
inc_pc = 1'b0;
load_ac = 1'b0;
load_pc = 1'b0;
mem_wr = 1'b0;
end
3'b010 : begin
ns = state_t '(3'b011);
mem_rd = 1'b1;
load_ir = 1'b1;
halt = 1'b0;
inc_pc = 1'b0;
load_ac = 1'b0;
load_pc = 1'b0;
mem_wr = 1'b0;
end
3'b011 : begin
ns = state_t '(3'b100);
mem_rd = 1'b1;
load_ir = 1'b1;
halt = 1'b0;
inc_pc = 1'b0;
load_ac = 1'b0;
load_pc = 1'b0;
mem_wr = 1'b0;
end
3'b100 : begin
ns = state_t '(3'b101);
mem_rd = 1'b0;
load_ir = 1'b0;
if (opcode == HLT)
halt = 1'b1;
else
halt = 1'b0;
inc_pc = 1'b1;
load_ac = 1'b0;
load_pc = 1'b0;
mem_wr = 1'b0;
end
3'b101 : begin
ns = state_t '(3'b110);
if (opcode inside {ADD, AND, XOR, LDA})
mem_rd = 1'b1;
else
mem_rd = 1'b0;
load_ir = 1'b0;
halt = 1'b0;
inc_pc = 1'b0;
load_ac = 1'b0;
load_pc = 1'b0;
mem_wr = 1'b0;
end
3'b110 : begin
ns = state_t '(3'b111);
if (opcode inside {ADD, AND, XOR, LDA})
mem_rd = 1'b1;
else
mem_rd = 1'b0;
load_ir = 1'b0;
halt = 1'b0;
if (opcode == SKZ && zero == 1'b1)
inc_pc = 1'b1;
else
inc_pc = 1'b0;
if (opcode inside {ADD, AND, XOR, LDA})
load_ac = 1'b1;
else
load_ac = 1'b0;
if (opcode == JMP)
load_pc = 1'b1;
else
load_pc = 1'b0;
mem_wr = 1'b0;
end
3'b111 : begin
ns = state_t '(3'b000);
if (opcode inside {ADD, AND, XOR, LDA})
mem_rd = 1'b1;
else
mem_rd = 1'b0;
load_ir = 1'b0;
halt = 1'b0;
if (opcode == JMP)
inc_pc = 1'b1;
else
inc_pc = 1'b0;
if (opcode inside {ADD, AND, XOR, LDA})
load_ac = 1'b1;
else
load_ac = 1'b0;
if (opcode == JMP)
load_pc = 1'b1;
else
load_pc = 1'b0;
if (opcode == STO)
mem_wr = 1'b1;
else
mem_wr = 1'b0;
end
default : ns = state_t '(3'b000);
endcase
end
endmodule