module machine(inc_pc,load_acc,load_pc,rd,wr,load_ir,datactl_ena,
halt,clk1,zero,ena,opcode);
output inc_pc,load_acc,load_pc,rd,wr,load_ir;
output datactl_ena,halt;
input clk1,zero,ena;
input [2:0] opcode;
reg inc_pc,load_acc,load_pc,rd,wr,load_ir;
reg datactl_ena,halt;
reg [2:0] state; //声明输入输出,以及定义寄存器
parameter //用parameter来定义标识符形式的常量
HLT=3'b000,
SKZ=3'b001,
ADD=3'b010,
ANDD=3'b011,
XORR=3'b100,
LDA=3'b101,
STO=3'b110,
JMP=3'b111;
always @(negedge clk1)
begin
if(!ena) //如果接收到复位信号RST,进行复位操作
begin
state<=3'b000;
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
ctl_cycle; //执行任务ctl_cycle
end
//------------task ctl_cycle------------任务开始---------
task ctl_cycle;
begin
casex(state) //case语句
0: //rd与load_ir均为高电平,其余为低电平。指令寄存器寄
Begin //存由ROM送来的高8位指令代码
{inc_pc,load_acc,load_pc,rd}<=4'b0001;
{wr,load_ir,datactl_ena,halt}<=4'b0100;
state<=1;
end
1: //INC_PC从0变为1,故PC增1,ROM送来低8位指令代码,
Begin //指令寄存器寄存该8位代码
{inc_pc,load_acc,load_pc,rd}<=4'b1001;
{wr,load_ir,datactl_ena,halt}<=4'b0100;
state<=2;
end
2: //空操作
Begin
{inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
state<=3;
end
3: //PC增1,指向下一条指令
begin
if(opcode==HLT) //若操作符为HLT,则输出信号HLT为高
begin
{inc_pc,load_acc,load_pc,rd}<=4'b1000;
{wr,load_ir,datactl_ena,halt}<=4'b0001;
end
else //否则其他各控制线输出为零。
begin
{inc_pc,load_acc,load_pc,rd}<=4'b1000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
state<=4;
end
4:
begin
if(opcode==JMP) //若为JMP,将目的地址送给程序计数器
begin
{inc_pc,load_acc,load_pc,rd}<=4'b0010;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode==LDA)
begin //若操作符号为ANDD,ADD,XORR或LDA,读相应地址的数据
{inc_pc,load_acc,load_pc,rd}<=4'b0001;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
if(opcode==STO) //若为STO,输出累加器数据
begin {inc_pc,load_acc,load_pc,rd}<=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0010;
end
else
begin //其他则为空操作
{inc_pc,load_acc,load_pc,rd} <=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
state<=5;
end
5:
begin
if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode==LDA)
begin //若操作符为ANDD,ADD,XORR,算术运算器就进行相应的运算
{inc_pc,load_acc,load_pc,rd} <=4'b0101;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
if (opcode==SKZ&&zero==1) //若为SKZ,线判断累加器的值是否为0,如果为,
begin // PC增1,否则保持原值
{inc_pc,load_acc,load_pc,rd} <=4'b1000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
if(opcode==JMP) //若为JMP,锁存目的地址
begin
{inc_pc,load_acc,load_pc,rd} <=4'b1010;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
if(opcode==STO) //若为STO,将数据写入地址处
begin
{inc_pc,load_acc,load_pc,rd} <=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b1010;
end
else
begin //其他则为空操作
{inc_pc,load_acc,load_pc,rd} <=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
state<=6;
end
6:
begin
if(opcode==STO) //若为STO,将数据写入地址处
begin
{inc_pc,load_acc,load_pc,rd} <=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0010;
end
else
if(opcode==ADD||opcode==ANDD||opcode==XORR||opcode==LDA)
begin //若操作符号为ANDD,ADD,XORR或LDA,读相应地址的数据
{inc_pc,load_acc,load_pc,rd} <=4'b0001;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else //其余为空操作
begin
{inc_pc,load_acc,load_pc,rd} <=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
state<=7;
end
7:
begin
if(opcode==SKZ&&zero==1) //若操作符为SKZ且累加器值为0,
begin //则PC值再增加1,跳过一条指令,否则PC无变化
{inc_pc,load_acc,load_pc,rd} <=4'b1000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
else
begin
{inc_pc,load_acc,load_pc,rd} <=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
end
state<=0;
end
default: //缺省为空操作
begin
{inc_pc,load_acc,load_pc,rd} <=4'b0000;
{wr,load_ir,datactl_ena,halt}<=4'b0000;
state<=0;
end
endcase
end
endtask
//-------------end of task ctl_cycle-----任务结束-----------------
endmodule
|