📄 cu.v
字号:
//**************************************************
//** Revision : 0.2
//** File name : CU.v
//** Module name : CU
//** Discription : This is the Taocore's Control Unit
//** Simulator : Quartus II 5.1 web edition
//** Synthesizer : Quartus II 5.1 web edition
//** Author : IamFree
//** Last modified: @ 2006///
//** Created date: 2006/03/13
//**************************************************
module CU(
//inputs
opcode,
flags,
sel_flags,
sys_clk,
sys_rst,
//outputs
alu_func,
LD_acc,
LD_arl,
LD_pcl,
LD_ir,
LD_spl,
LD_sph,
LD_arh,
LD_pch,
LD_psw,
LD_gr6,
SEL_arh,
SEL_gr_addr,
SEL_psw,
SEL_alu,
SEL_sp,
SEL_databus,
SEL_pc,
SEL_address,
//data bus control
rom_cs,
ram_cs,
mem_wr,
mem_rd,
data_out_enable
);
//Parameter define
//Opcode define
parameter ADDI=5'b00001;
parameter SUBI=5'b00010;
parameter ANDI=5'b00011;
parameter ORI =5'b00100;
parameter XORI=5'b00101;
parameter ADDR=5'b01001;
parameter SUBR=5'b01010;
parameter ANDR=5'b01011;
parameter ORR =5'b01100;
parameter XORR=5'b01101;
parameter JZ =5'b10000;
parameter JP =5'b10001;
parameter JC =5'b10010;
parameter JMP =5'b10011;
parameter SHL =5'b00110;
parameter SHR =5'b00111;
parameter NOTA=5'b01000;
parameter LDV =5'b01110;
parameter STV =5'b01111;
parameter STR =5'b10100;
parameter STSPH=5'b10101;
parameter STSPL=5'b10110;
parameter LDI =5'b10111;
parameter LDA =5'b11000;
parameter STA =5'b11001;
parameter LDR =5'b11010;
parameter CALL=5'b11011;
parameter RET =5'b11100;
parameter PUSH=5'b11101;
parameter POP =5'b11110;
parameter NOP =5'b00000;
//CU parameter define(ALL these parameters are
//relate to the datapath,don't edit them seperately!
parameter flag_acc_sel=1'b1;
parameter flag_psw_sel=1'b0;
parameter SEL_ALU_MEM =2'b00;
parameter SEL_ALU_GR6 =2'b01;
parameter SEL_ALU_FLAGS=2'b10;
parameter SEL_ARH_RRR =1'b0;
parameter SEL_ARH_DATA=1'b1;
parameter SEL_GR_ADDR_RRR=1'b0;
parameter SEL_GR_ADDR_BX =1'b1;
parameter SEL_PSW_ALU =1'b0;
parameter SEL_PSW_DATA=1'b1;
parameter SEL_SP_S1 =2'b00;
parameter SEL_SP_A1 =2'b01;
parameter SEL_SP_DATA=2'b10;
parameter SEL_DATABUS_ALU=2'b10;
parameter SEL_DATABUS_PCH=2'b01;
parameter SEL_DATABUS_PCL=2'b00;
parameter SEL_PC_AR=1'b1;
parameter SEL_PC_A1=1'b0;
parameter SEL_ADDRESS_PC=2'b00;
parameter SEL_ADDRESS_AR=2'b01;
parameter SEL_ADDRESS_SP=2'b10;
parameter ENABLE =1'b0; //For WR,RD,ROM_CS,RAM_CS
parameter DISABLE=1'b1;
parameter LDEN =1'b1; //For register's Load enable singal
parameter LDDIS =1'b0;
parameter OUTEN =1'b1; //For data_out_enable
parameter OUTDIS =1'b0;
//ALU opcode define
/* Defined but never used
parameter ALU_ADD=5'b00001;
parameter ALU_SUB=5'b00010;
parameter ALU_AND=5'b00011;
parameter ALU_OR =5'b00100;
parameter ALU_XOR=5'b00101;
*/
parameter ALU_SHL=5'b00110;
parameter ALU_SHR=5'b00111;
parameter ALU_NOT=5'b01000;
parameter ALU_TA =5'b01001;
parameter ALU_TB =5'b01010;
parameter ALU_NOP=5'b00000; //A invalid statement of ALU
//Port define
//outputs
output rom_cs;
output ram_cs;
output mem_wr;
output mem_rd;
output [4:0] alu_func;
output LD_acc;
output LD_arl;
output LD_pcl;
output LD_ir;
output LD_spl;
output LD_sph;
output LD_arh;
output LD_pch;
output LD_psw;
output LD_gr6;
//Selection signals
output SEL_gr_addr;
output SEL_psw;
output SEL_arh;
output [1:0] SEL_alu;
output [1:0] SEL_sp;
output [1:0] SEL_databus;
output SEL_pc;
output [1:0] SEL_address;
//data bus control
output data_out_enable;
//inputs
input [4:0] opcode;
input [2:0] flags;
input [1:0] sel_flags;
input sys_clk;
input sys_rst;
//Port type
reg rom_cs;
reg ram_cs;
reg mem_wr;
reg mem_rd;
reg [4:0] alu_func;
reg LD_acc;
reg LD_arl;
reg LD_pcl;
reg LD_ir;
reg LD_spl;
reg LD_sph;
reg LD_arh;
reg LD_pch;
reg LD_psw;
reg LD_gr6;
reg SEL_arh;
reg SEL_gr_addr;
reg SEL_psw;
reg [1:0] SEL_alu;
reg [1:0] SEL_sp;
reg [1:0] SEL_databus;
reg SEL_pc;
reg [1:0] SEL_address;
reg data_out_enable;
//Variable define
reg [2:0] Op_state;
//Statement const define
parameter FETCH=3'b000;
parameter S1=3'b001;
parameter S2=3'b010;
parameter S3=3'b011;
parameter S4=3'b100;
parameter S5=3'b101;
parameter S6=3'b110;
//parameter OP_RST=3'b111;
//Body
//Statement conter(SC)
//v.1
reg SC_clr_n; //SC同步清零端
reg SC_inc; //SC递增使能端
always @(posedge sys_clk or negedge sys_rst)
begin
if(!sys_rst) //指令同步/系统异步清零
Op_state<=FETCH;
else if(!SC_clr_n)
Op_state<=FETCH;
else if(SC_inc)
Op_state<=Op_state+3'b001;
end
//指令译码器
always @(Op_state or opcode or flags or sel_flags)
begin
//防止生成不可预知的锁存器
rom_cs=DISABLE;
ram_cs=DISABLE;
mem_wr=DISABLE;
mem_rd=DISABLE;
alu_func=ALU_NOP;
LD_acc=LDDIS;
LD_ir =LDDIS;
LD_spl=LDDIS;
LD_sph=LDDIS;
LD_arl=LDDIS;
LD_arh=LDDIS;
LD_pcl=LDDIS;
LD_pch=LDDIS;
LD_psw=LDDIS;
LD_gr6=LDDIS;
SEL_arh=SEL_ARH_RRR;
SEL_gr_addr=SEL_GR_ADDR_RRR;
SEL_psw=SEL_PSW_ALU;
SEL_alu=SEL_ALU_MEM;
SEL_sp=SEL_SP_S1;
SEL_databus=SEL_DATABUS_ALU;
SEL_pc=SEL_PC_A1;
SEL_address=SEL_ADDRESS_PC;
data_out_enable=OUTDIS;
SC_clr_n=1'b1;
SC_inc=1'b0;
//根据状态计数器和指令进行指令译码
if(Op_state==FETCH)
begin
SEL_pc=SEL_PC_A1; //PC<-PC+1
LD_pch=LDEN;LD_pcl=LDEN;
//IR<-DATA
LD_ir=LDEN;
//MEM type
ram_cs=DISABLE;
rom_cs=ENABLE;
mem_rd=ENABLE;
mem_wr=DISABLE;
SEL_address=SEL_ADDRESS_PC;
data_out_enable=OUTDIS;
//将所有与FETCH无关控制信号置为合适的初始值
LD_acc=LDDIS; //ACC
LD_arl=LDDIS; //AR
LD_arh=LDDIS;
LD_spl=LDDIS; //SP
LD_sph=LDDIS;
LD_psw=LDDIS; //PSW
LD_gr6=LDDIS; //GR6
alu_func=ALU_NOP; //At this time ALU is free
SEL_gr_addr=SEL_GR_ADDR_RRR;
SEL_psw =SEL_PSW_ALU;
SEL_alu =SEL_ALU_MEM;
SEL_sp =SEL_SP_S1;
SEL_databus=SEL_DATABUS_ALU;
SEL_pc =SEL_PC_A1;
SEL_arh =SEL_ARH_RRR;
//Goto next statemet
SC_clr_n=1'b1;
SC_inc=1'b1;
end
else
begin
case(opcode)//synthesis parallel_case
ADDI,
SUBI, //DDDebugging...(ADDI SUBI debugged,)
ANDI,
ORI ,
XORI :
begin
case(Op_state)//synthesis parallel_case
S1 :
begin
//MEM type
rom_cs=ENABLE;
mem_rd=ENABLE;
//ACC<-ACC opcode MEM(code)
alu_func={2'b00,opcode[2:0]};
SEL_databus=SEL_DATABUS_ALU;
SEL_address=SEL_ADDRESS_PC; //<-Where is the data come from
SEL_alu=SEL_ALU_MEM; //<-Where are the results going
LD_acc=LDEN;
SEL_psw=SEL_PSW_ALU; //PSW<-ALU_flags
LD_psw=LDEN;
SC_inc=1'b1; //Goto next state
end
S2 :
begin
//PC<-PC+1
SEL_pc=SEL_PC_A1;
LD_pch=LDEN;LD_pcl=LDEN;
SC_clr_n=1'b0; //End of these opcode
end
default:SC_clr_n=1'b0; //Program may out of control from here,
//As the error already happened,nothing we should do but let it go!
endcase
end
ADDR ,
SUBR ,
ANDR , //DDDebugging...(ADDR debugged,)
ORR ,
XORR:
case(Op_state)
S1 :
begin
//ACC<-ACC opcode reg[rrr] (NOTE: rrr can't be PSW or ACC)
SEL_gr_addr=SEL_GR_ADDR_RRR; //Where is the data come from
SEL_alu=SEL_ALU_GR6;
alu_func={2'b00,opcode[2:0]}; //What the alu should do
SEL_databus=SEL_DATABUS_ALU; //Where is the result going
LD_acc=LDEN;
SEL_psw=SEL_PSW_ALU;
LD_psw=LDEN;
SC_inc=1'b1; //End of these opcode
end
S2 :
SC_clr_n=1'b0;
default:SC_clr_n=1'b0;
endcase
SHL ,
SHR , //Debugged
NOTA :
begin
//ALU<-ALU sl or sr or not
case(opcode)//synthesis parallel_case
//Use the data source defined by the opcode
SHL: alu_func=ALU_SHL; //What the alu should do
SHR: alu_func=ALU_SHR;
NOTA:alu_func=ALU_NOT;
default:alu_func=ALU_NOP;
endcase
//Where the results going
SEL_databus=SEL_DATABUS_ALU;
LD_acc=LDEN;
SEL_psw=SEL_PSW_ALU;
LD_psw=LDEN;
SC_clr_n=1'b0; //End of these opcode
end
JZ , //DDDebugging...(JMP debugged,)
JP ,
JC ,
JMP :
begin
if((opcode==JZ && flags[1]==1'b1)||(opcode==JC && flags[0]==1'b1)||
(opcode==JP && flags[2]==1'b1)||(opcode==JMP))
begin
case(Op_state) //synthesis parallel_case
S1 :
begin
SEL_arh=SEL_ARH_RRR; //ARH<-RRR
LD_arh=LDEN;
//ARL<-MEM(code)
SEL_address=SEL_ADDRESS_PC;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -