-
Notifications
You must be signed in to change notification settings - Fork 0
/
control.v.bak
150 lines (127 loc) · 3.5 KB
/
control.v.bak
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
/*组合逻辑控制单元,根据时钟生成为控制信号和内部信号*/
/*
输入:
din:指令,8位,来自IR;
clk:时钟信号,1位,上升沿有效;
rst:复位信号,1位,与cpustate共同组成reset信号;
cpustate:当前CPU的状态(IN,CHECK,RUN),2位;
z:零标志,1位,零标志寄存器的输出,如果指令中涉及到z,可加上,否则可去掉;
输出:
clr:清零控制信号
自行设计的各个控制信号
*/
//省略号中是自行设计的控制信号,需要自行补充,没用到z的话去掉z
module control(din,clk,rst,z,cpustate, ......,clr);
input [7:0]din;
input clk;
input rst,z;
input [1:0] cpustate;
//补充输出端口说明
//parameter's define
wire reset;
//在下方加上自行定义的状态
wire fetch1,fetch2,fetch3,nop1;
//加上自行设计的指令,这里是译码器的输出,所以nop指令经译码器输出后为inop。
//类似地,add指令指令经译码器输出后为iadd;inac指令经译码器输出后为iinac,......
reg inop;
//时钟节拍,8个为一个指令周期,t0-t2分别对应fetch1-fetch3,t3-t7分别对应各指令的执行周期,当然不是所有指令都需要5个节拍的。例如add指令只需要2个节拍:t3和t4
reg t0,t1,t2,t3,t4,t5,t6,t7; //时钟节拍,8个为一个周期
// 内部信号:clr清零,inc自增
wire clr;
wire inc;
assign reset = rst&(cpustate == 2'b11);
// assign signals for the cunter
//clr信号是每条指令执行完毕后必做的清零,下面clr赋值语句要修改,需要“或”各指令的最后一个周期
assign clr=nop1;
assign inc=~clr;
//generate the control signal using state information
//...
//取公过程
assign fetch1=t0;
assign fetch2=t1;
assign fetch3=t2;
//什么都不做的译码
assign nop1=inop&&t3;//inop表示nop指令,nop1是nop指令的执行周期的第一个状态也是最后一个状态,因为只需要1个节拍t3完成
//以下写出各条指令状态的表达式
//以下给出了pcbus的逻辑表达式,写出其他控制信号的逻辑表达式
assign pcbus=fetch1||fetch3;
always@(posedge clk or negedge reset)
begin
if(!reset)
begin//各指令清零,以下已为nop指令清零,请补充其他指令,为其他指令清零
inop<=0;
end
else
begin
case(din[7:4]) //译码处理过程
4'd0: begin //op为0000,是nop指令,因此这里inop的值是1,而其他指令应该清零,请补充为其他指令清零的语句
inop<=1;
end
4'd1: begin
//op为0001,应该是add指令,因此iadd指令为1,其他指令都应该是0。
//后续各分支类似,只有一条指令为1,其他指令为0,以下分支都给出nop指令的赋值,需要补充其他指令
inop<=0;
end
4'd2: begin
inop<=0;
end
4'd3: begin
inop<=0;
end
4'd4: begin
inop<=0;
end
4'd5: begin
inop<=0;
end
4'd6: begin
inop<=0;
end
4'd7: begin
inop<=0;
end
//如果还有分支,可以继续写,如果没有分支了,写上defuault语句
endcase
end
end
always @(posedge clk or negedge reset)
begin
if(!reset) //reset清零
begin
t0<=1;
t1<=0;
t2<=0;
t3<=0;
t4<=0;
t5<=0;
t6<=0;
t7<=0;
end
else
begin
if(inc) //运行
begin
t7<=t6;
t6<=t5;
t5<=t4;
t4<=t3;
t3<=t2;
t2<=t1;
t1<=t0;
t0<=0;
end
else if(clr) //清零
begin
t0<=1;
t1<=0;
t2<=0;
t3<=0;
t4<=0;
t5<=0;
t6<=0;
t7<=0;
end
end
end
/*—————结束—————*/
endmodule