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
|