control_unit.v
来自「这是我同学在上海交大实习的时候做的一个单片机的verilog代码实现」· Verilog 代码 · 共 334 行
V
334 行
module Control_Unit (
Load_R0, Load_R1,
Load_R2, Load_R3,
Load_PC, Inc_PC,
Sel_Bus_1_Mux, Sel_Bus_2_Mux,
Load_IR, Load_Add_R, Load_Reg_Y, Load_Reg_Z,
Load_Carrier,
write, instruction, zero, Carrier_flag, clk, rst);
parameter word_size = 16, op_size = 4, state_size = 4;
parameter address_size = 8;
parameter src_size = 2, dest_size = 2, Sel1_size = 3, Sel2_size = 2;
// State Codes
parameter S_idle = 0, S_fet1 = 1, S_fet2 = 2, S_dec = 3;
parameter S_ex1 = 4, S_rd1 = 5;
parameter S_wr1 = 6, S_br1 = 7, S_halt = 8, S_brz = 11;
parameter S_lw = 9, S_rw =10, S_cmp = 12;
// Opcodes
parameter NOP = 0, ADD = 1, SUB = 2, ID_WR = 3, DCC = 4;
parameter RD = 5, WR = 6, BR = 7, BRZ = 8, ADDC = 9, ID_RD = 10;
parameter shift = 11, ACC = 12, BRC = 13, compare = 14, LD = 15;
// Source and Destination Codes
parameter R0 = 0, R1 = 1, R2 = 2, R3 = 3;
output Load_R0, Load_R1, Load_R2, Load_R3;
output Load_PC, Inc_PC;
output [Sel1_size-1:0] Sel_Bus_1_Mux;
output Load_IR, Load_Add_R;
output Load_Reg_Y, Load_Reg_Z, Load_Carrier;
output [Sel2_size-1: 0] Sel_Bus_2_Mux;
output write;
input [word_size-1: 0] instruction;
input zero, Carrier_flag;
input clk, rst;
reg [state_size-1: 0] state, next_state;
reg Load_R0, Load_R1, Load_R2, Load_R3, Load_PC, Inc_PC;
reg Load_IR, Load_Add_R, Load_Reg_Y;
reg Sel_ALU, Sel_Bus_1, Sel_Mem;
reg Sel_R0, Sel_R1, Sel_R2, Sel_R3, Sel_PC, Sel_Ins;
reg Load_Reg_Z, Load_Carrier, write;
reg err_flag;
wire [op_size-1:0] opcode = instruction [15:12];
wire [src_size-1: 0] src = instruction [11:10];
wire [dest_size-1:0] dest = instruction [9:8];
wire [7:0] address = instruction [7:0];
// Mux selectors
assign Sel_Bus_1_Mux[Sel1_size-1:0] = Sel_R0 ? 0:
Sel_R1 ? 1:
Sel_R2 ? 2:
Sel_R3 ? 3:
Sel_PC ? 4:
Sel_Ins ? 5 : 3'bx; // 3-bits, sized number
assign Sel_Bus_2_Mux[Sel2_size-1:0] = Sel_ALU ? 0:
Sel_Bus_1 ? 1:
Sel_Mem ? 2: 2'bx;
always @ (posedge clk or negedge rst)
begin: State_transitions
if (rst == 0)
state <= S_idle;
else
state <= next_state;
end
always @ (state or opcode or zero)
begin: Output_and_next_state
Sel_R0 = 0; Sel_R1 = 0; Sel_R2 = 0; Sel_R3 = 0; Sel_PC = 0; Sel_Ins = 0;
Load_R0 = 0; Load_R1 = 0; Load_R2 = 0; Load_R3 = 0; Load_PC = 0;
Load_IR = 0; Load_Add_R = 0; Load_Reg_Y = 0; Load_Reg_Z = 0; Load_Carrier = 0;
Inc_PC = 0;
Sel_Bus_1 = 0;
Sel_ALU = 0;
Sel_Mem = 0;
write = 0;
err_flag = 0; // Used for de-bug in simulation
next_state = state;
case (state)//״̬
S_idle: next_state = S_fet1;
S_fet1: begin
next_state = S_fet2;
Sel_PC = 1;
Sel_Bus_1 = 1;
Load_Add_R = 1;
end
S_fet2: begin
next_state = S_dec;
Sel_Mem = 1;
Load_IR = 1;
Inc_PC = 1;
end
S_dec: case (opcode)
NOP: next_state = S_fet1;
ADD, SUB, ADDC,LD, shift:
begin
next_state = S_ex1;
Sel_Bus_1 = 1;
Load_Reg_Y = 1;
case (src)
R0: Sel_R0 = 1;
R1: Sel_R1 = 1;
R2: Sel_R2 = 1;
R3: Sel_R3 = 1;
default : err_flag = 1;
endcase
end
compare:
begin
next_state = S_cmp;
Sel_Bus_1 = 1;
Load_Reg_Y = 1;
case (src)
R0: Sel_R0 = 1;
R1: Sel_R1 = 1;
R2: Sel_R2 = 1;
R3: Sel_R3 = 1;
default : err_flag = 1;
endcase
end
ACC,DCC:
begin
next_state=S_fet1;
case (dest)
R0: begin Sel_R0 = 1; Load_R0 = 1; end
R1: begin Sel_R1 = 1; Load_R1 = 1; end
R2: begin Sel_R2 = 1; Load_R2 = 1; end
R3: begin Sel_R3 = 1; Load_R3 = 1; end
default : err_flag = 1;
endcase
Sel_ALU =1;
end
/* NOT: begin
next_state = S_fet1;
Load_Reg_Z = 1;
Sel_Bus_1 = 1;
Sel_ALU = 1;
case (src)
R0: Sel_R0 = 1;
R1: Sel_R1 = 1;
R2: Sel_R2 = 1;
R3: Sel_R3 = 1;
default : err_flag = 1;
endcase
case (dest)
R0: Load_R0 = 1;
R1: Load_R1 = 1;
R2: Load_R2 = 1;
R3: Load_R3 = 1;
default: err_flag = 1;
endcase
end NOT */
RD: begin
next_state = S_rd1;
Sel_Ins = 1; Sel_Bus_1 = 1; Load_Add_R = 1;
end // RD
WR: begin
next_state = S_wr1;
Sel_Ins = 1; Sel_Bus_1 = 1; Load_Add_R = 1;
end // WR
ID_RD:
begin
next_state=S_lw;
case (src)
R0: Sel_R0 = 1;
R1: Sel_R1 = 1;
R2: Sel_R2 = 1;
R3: Sel_R3 = 1;
default : err_flag = 1;
endcase
Sel_Bus_1=1;
Load_Add_R=1;
end
ID_WR:
begin
next_state=S_rw;
case (dest)
R0: Sel_R0 = 1;
R1: Sel_R1 = 1;
R2: Sel_R2 = 1;
R3: Sel_R3 = 1;
default : err_flag = 1;
endcase
Sel_Bus_1=1;
Load_Add_R=1;
end
BR: begin
next_state = S_br1;
Sel_Ins = 1; Sel_Bus_1 = 1; Load_Add_R = 1;
end // BR
BRZ:begin
next_state=S_brz;
case (dest)
R0: Sel_R0 = 1;
R1: Sel_R1 = 1;
R2: Sel_R2 = 1;
R3: Sel_R3 = 1;
default : err_flag = 1;
endcase
Load_Reg_Z= 1;
end
BRC:
begin
if(Carrier_flag==1)
begin
next_state = S_br1;
Sel_Ins = 1;
Sel_Bus_1 = 1;
Load_Add_R = 1;
end
else
next_state= S_fet1;
end
default : next_state = S_halt;
endcase // (opcode)
S_ex1: begin
next_state = S_fet1;
Load_Reg_Z = 1;
Sel_ALU = 1;
Load_Carrier = 1;
case (dest)
R0: begin Sel_R0 = 1; Load_R0 = 1; end
R1: begin Sel_R1 = 1; Load_R1 = 1; end
R2: begin Sel_R2 = 1; Load_R2 = 1; end
R3: begin Sel_R3 = 1; Load_R3 = 1; end
default : err_flag = 1;
endcase
end
S_rd1: begin
next_state = S_fet1;
Sel_Mem = 1;
case (dest)
R0:Load_R0 = 1;
R1:Load_R1 = 1;
R2:Load_R2 = 1;
R3:Load_R3 = 1;
default:err_flag = 1;
endcase
end
S_wr1: begin
next_state = S_fet1;
write = 1;
case (src)
R0:Sel_R0 = 1;
R1:Sel_R1 = 1;
R2:Sel_R2 = 1;
R3:Sel_R3 = 1;
default:err_flag = 1;
endcase
end
S_brz: begin
if (zero == 1)
begin
next_state = S_br1;
Sel_Ins = 1; Sel_Bus_1 = 1; Load_Add_R = 1;
end // BRZ
else
begin
next_state = S_fet1;
end
end
S_br1: begin
next_state = S_fet1;
Sel_Mem = 1;
Load_PC = 1;
end
S_lw: begin
next_state=S_fet1;
Sel_Mem=1;
case (dest)
R0: Load_R0 = 1;
R1: Load_R1 = 1;
R2: Load_R2 = 1;
R3: Load_R3 = 1;
default : err_flag = 1;
endcase
end
S_rw: begin
next_state=S_fet1;
case (src)
R0: Sel_R0 = 1;
R1: Sel_R1 = 1;
R2: Sel_R2 = 1;
R3: Sel_R3 = 1;
default : err_flag = 1;
endcase
write=1;
end
S_cmp: begin
next_state=S_fet1;
Load_Carrier = 1;
case (dest)
R0: Sel_R0 = 1;
R1: Sel_R1 = 1;
R2: Sel_R2 = 1;
R3: Sel_R3 = 1;
default : err_flag = 1;
endcase
end
// S_br2: begin next_state = S_fet1; Sel_Mem = 1; Load_PC = 1; end
S_halt: next_state = S_halt;
default: next_state = S_idle;
endcase
end
endmodule
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?