OpenFPGA/openfpga_flow/benchmarks/micro_benchmark/RISC_posedge_clk/Controller.v

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