212 lines
4.1 KiB
Verilog
212 lines
4.1 KiB
Verilog
module Controller(L_R0,L_R1,L_R2,L_R3,L_PC,Inc_PC,
|
|
Sel_Bus1,L_IR,L_ADD_R,L_R_Y,L_R_Z,Sel_Bus2,write,
|
|
zero,instruction,nclk,rst);
|
|
|
|
|
|
//狀態
|
|
parameter S_idle=0,S_fet1=1,S_fet2=2,S_dec=3,
|
|
S_ex1=4,S_rd1=5,S_rd2=6,S_wr1=7,S_wr2=8,
|
|
S_br1=9,S_br2=10,S_halt=11;
|
|
//指令
|
|
parameter NOP=0,ADD=1,SUB=2,AND=3,NOT=4,
|
|
RD=5,WR=6,BR=7,BRZ=8;
|
|
|
|
|
|
output reg L_R0,L_R1,L_R2,L_R3,L_PC,Inc_PC,
|
|
L_IR,L_ADD_R,L_R_Y,L_R_Z,write;
|
|
output reg[2:0]Sel_Bus1;
|
|
output reg [1:0]Sel_Bus2;
|
|
|
|
input zero,nclk,rst;
|
|
input [7:0]instruction;
|
|
|
|
reg [15:0]Con_out;
|
|
reg [3:0]PS,NS;
|
|
reg err_flag;
|
|
|
|
wire [1:0]src=instruction[3:2];
|
|
wire [1:0]dest=instruction[1:0];
|
|
wire [3:0]opcode=instruction[7:4];
|
|
|
|
always@(posedge nclk)
|
|
begin
|
|
if(rst==1)PS<=0;
|
|
else PS<=NS;
|
|
end
|
|
|
|
always@(PS,opcode,src,dest,zero)
|
|
begin
|
|
L_R0=0;
|
|
L_R1=0;
|
|
L_R2=0;
|
|
L_R3=0;
|
|
L_PC=0;
|
|
Inc_PC=0;
|
|
Sel_Bus1=0;
|
|
L_IR=0;
|
|
L_ADD_R=0;
|
|
L_R_Y=0;
|
|
L_R_Z=0;
|
|
Sel_Bus2=0;
|
|
write=0;
|
|
err_flag=0;
|
|
case(PS)
|
|
S_idle: NS=S_fet1;
|
|
|
|
S_fet1: begin
|
|
NS=S_fet2;
|
|
Sel_Bus1=3'b100;//Sel_PC
|
|
Sel_Bus2=2'b01;//Sel_Bus1
|
|
L_ADD_R=1;
|
|
end
|
|
|
|
S_fet2: begin
|
|
NS=S_dec;
|
|
Sel_Bus2=2'b10;//Sel_Mem
|
|
L_IR=1;
|
|
Inc_PC=1;
|
|
end
|
|
|
|
S_dec: begin
|
|
case(opcode)
|
|
NOP:NS=S_fet1;
|
|
ADD,SUB,AND:begin
|
|
NS=S_ex1;
|
|
Sel_Bus2=2'b01;//Sel_Bus1
|
|
L_R_Y=1;
|
|
case(src)
|
|
0: Sel_Bus1=3'b000;//R0
|
|
1: Sel_Bus1=3'b001;//R1
|
|
2: Sel_Bus1=3'b010;//R2
|
|
3: Sel_Bus1=3'b011;//R3
|
|
default err_flag=1;
|
|
endcase
|
|
end//ADD,SUB,AND
|
|
|
|
NOT:begin
|
|
NS=S_fet1;
|
|
L_R_Z=1;
|
|
Sel_Bus2=2'b00;//Sel_ALU
|
|
case(src)
|
|
0: Sel_Bus1=3'b000;//R0
|
|
1: Sel_Bus1=3'b001;//R1
|
|
2: Sel_Bus1=3'b010;//R2
|
|
3: Sel_Bus1=3'b011;//R3
|
|
default err_flag=1;
|
|
endcase
|
|
case(dest)
|
|
0: L_R0=1;
|
|
1: L_R1=1;
|
|
2: L_R2=1;
|
|
3: L_R3=1;
|
|
default err_flag=1;
|
|
endcase
|
|
end//NOT
|
|
|
|
RD: begin
|
|
NS=S_rd1;
|
|
Sel_Bus1=3'b100;//Sel_PC
|
|
Sel_Bus2=3'b001;//Sel_Bus1
|
|
L_ADD_R=1;
|
|
end//RD
|
|
|
|
WR: begin
|
|
NS=S_wr1;
|
|
Sel_Bus1=3'b100;//Sel_PC
|
|
Sel_Bus2=3'b001;//Sel_Bus1
|
|
L_ADD_R=1;
|
|
end//WR
|
|
|
|
BR: begin
|
|
NS=S_br1;
|
|
Sel_Bus1=3'b100;//Sel_PC
|
|
Sel_Bus2=3'b001;//Sel_Bus1
|
|
L_ADD_R=1;
|
|
end//BR
|
|
|
|
BRZ:begin
|
|
if(zero==1)begin
|
|
NS=S_br1;
|
|
Sel_Bus1=3'b100;//Sel_PC
|
|
Sel_Bus2=3'b001;//Sel_Bus1
|
|
L_ADD_R=1;
|
|
end
|
|
else begin
|
|
NS=S_fet1;
|
|
Inc_PC=1;
|
|
end
|
|
end//BRZ
|
|
|
|
default NS=S_halt;
|
|
|
|
endcase//opcode
|
|
end
|
|
|
|
S_ex1: begin
|
|
NS=S_fet1;
|
|
L_R_Z=1;
|
|
Sel_Bus2=2'b00;//Sel_ALU
|
|
case(dest)
|
|
0: begin Sel_Bus1=3'b000;L_R0=1;end
|
|
1: begin Sel_Bus1=3'b001;L_R1=1;end
|
|
2: begin Sel_Bus1=3'b010;L_R2=1;end
|
|
3: begin Sel_Bus1=3'b011;L_R3=1;end
|
|
default err_flag=1;
|
|
endcase
|
|
end
|
|
|
|
S_rd1: begin
|
|
NS=S_rd2;
|
|
Inc_PC=1;
|
|
Sel_Bus2=2'b10;//Sel_Mem
|
|
L_ADD_R=1;
|
|
end
|
|
|
|
S_wr1: begin
|
|
NS=S_wr2;
|
|
Inc_PC=1;
|
|
Sel_Bus2=2'b10;//Sel_Mem
|
|
L_ADD_R=1;
|
|
end
|
|
|
|
S_rd2: begin
|
|
NS=S_fet1;
|
|
Sel_Bus2=2'b10;//Sel_Mem
|
|
case(dest)
|
|
0: L_R0=1;
|
|
1: L_R1=1;
|
|
2: L_R2=1;
|
|
3: L_R3=1;
|
|
default err_flag=1;
|
|
endcase
|
|
end
|
|
|
|
S_wr2: begin
|
|
NS=S_fet1;
|
|
write=1;
|
|
case(src)
|
|
0: Sel_Bus1=3'b000;//R0
|
|
1: Sel_Bus1=3'b001;//R1
|
|
2: Sel_Bus1=3'b010;//R2
|
|
3: Sel_Bus1=3'b011;//R3
|
|
default err_flag=1;
|
|
endcase
|
|
end
|
|
|
|
S_br1: begin
|
|
NS=S_br2;
|
|
Sel_Bus2=2'b10;//Sel_Mem
|
|
L_ADD_R=1;
|
|
end
|
|
|
|
S_br2: begin
|
|
NS=S_fet1;
|
|
Sel_Bus2=2'b10;//Sel_Mem
|
|
L_PC=1;
|
|
end
|
|
S_halt: NS=S_halt;
|
|
default NS=S_idle;
|
|
endcase
|
|
end
|
|
endmodule
|