//最简单计算机核设计 2010-4-16(可下载到开发板验证)
//可以用QuartusII编译下载
//仅限学习;
//参考书:advanced Digital Design with the Verilog HDL 作者:Michael D.ciletti
//基本输入时钟CLK
//仅限于学习
//复位控制:rst低电位有效
//***************指令集****************
//指令 操作码 源寄存器 目的寄存器 操作
// NOP 0000 xxxxx xxxxxx 空操作
//ADD 0001 src dest dest<=src+dest
//SUB 0010 src dest dest<=dest-src
//AND 0011 src dest dest<=src&&dest
//NOT 0100 src dest dest<=~src
//RD 0101 xxxxx dest dest<= memory[Add_R]
//WR 0110 src xxxxx memory[Add_R]<=src
//BR 0111 xxxxx xxxxx PC<=memory[Add_R]
//BRZ 1000 xxxxx xxxxx PC<=memory[Add_R]
//HALT 1111 xxxxx xxxxx 挂起至RST
//**************************************

状态转移图

RTL级验证 Processing_Unit Control_Unit Memory_Unit组成

Processing_Unit RTL级验证

Control_Unit RTL级验证
//*******************代码开始**********************************
module RISC_CPU (clk,rst);//dingcengmokuai
parameter word_size =8;
parameter Sel1_size =3;
parameter Sel2_size =2;
wire [Sel1_size-1:0] Sel_bus_1_Mux;
wire [Sel2_size-1:0] Sel_bus_2_Mux;
input clk,rst;
wire zero;
wire [word_size-1:0] instruction,address,Bus_1,mem_word;
wire Load_R0,Load_R1,Load_R2,Load_R3,Load_PC,Inc_PC,Load_IR;
wire Load_Add_R,Load_Reg_Y,Load_Reg_Z;
wire write;
Processing_Unit M0_Processor(instruction,zero,address,Bus_1,mem_word,Load_R0,
Load_R1,Load_R2,Load_R3,Load_PC,Inc_PC,Sel_bus_1_Mux,Load_IR,
Load_Add_R,Load_Reg_Y,Load_Reg_Z,Sel_bus_2_Mux,clk,rst);
Control_Unit M1_Controller(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,write,
instruction,zero,clk,rst);
Memory_Unit M2_Sram(.data_out(mem_word),.data_in(Bus_1),.address(address),.clk(clk),.write(write));
endmodule
module Processing_Unit (instruction,Zflag,address,Bus_1,mem_word,Load_R0,
Load_R1,Load_R2,Load_R3,Load_PC,Inc_PC,Sel_bus_1_Mux,Load_IR,
Load_Add_R,Load_Reg_Y,Load_Reg_Z,Sel_bus_2_Mux,clk,rst);
parameter word_size =8;
parameter Sel1_size =3;
parameter Sel2_size =2;
parameter op_size =4;
output[word_size-1:0] instruction,address,Bus_1;
output Zflag;
input[word_size-1:0] mem_word;
input Load_R0,Load_R1,Load_R2,Load_R3,Load_PC,Inc_PC;
input [Sel1_size-1:0] Sel_bus_1_Mux;
input [Sel2_size-1:0] Sel_bus_2_Mux;
input Load_IR,Load_Add_R,Load_Reg_Y,Load_Reg_Z;
input clk,rst;
wire Load_R0,Load_R1,Load_R2,Load_R3;
wire [word_size-1:0] Bus_2;
wire [word_size-1:0] R0_out,R1_out,R2_out,R3_out;
wire [word_size-1:0] PC_count,Y_value,alu_out;
wire alu_zero_flag;
wire [op_size-1:0] opcode=instruction[word_size-1:word_size-op_size];
Register_Unit R0(R0_out,Bus2,Load_R0,clk,rst);
Register_Unit R1(R1_out,Bus2,Load_R1,clk,rst);
Register_Unit R2(R2_out,Bus2,Load_R2,clk,rst);
Register_Unit R3(R3_out,Bus2,Load_R3,clk,rst);
Register_Unit Reg_Y(Y_value,Bus2,Load_Reg_Y,clk,rst);
D_flop Reg_Z(Zflag,alu_zero,Load_Reg_Z,clk,rst);
Adress_Register Add_R(address,Bus_2,Load_Add_R,clk,rst);
Instruction_Register IR(instruction,Bus_2,Load_IR,clk,rst);
Program_Counter PC(PC_count,Bus_2,Load_PC,Inc_PC,clk,rst);
Multiplexer_5ch Mux_1(Bus_1,R0_out,R1_out,R2_out,R3_out,PC_count,Sel_bus_1_Mux);
Multiplexer_3ch Mux_2(Bus_2,alu_out,Bus_1,mem_word,Sel_bus_2_Mux);
Alu_RISC ALU(alu_zero_flag,alu_out,Y_value,Bus_1,opcode);
endmodule
module Register_Unit(data_out,data_in,load,clk,rst);
parameter word_size =8;
output [word_size-1:0] data_out;
input [word_size-1:0] data_in;
input load;
input clk,rst;
reg [word_size-1:0] data_out;
always @(posedge clk or negedge rst)
begin
if(rst==0) data_out<=0;
else if(load) data_out<=data_in;
end
endmodule
module D_flop(data_out,data_in,load,clk,rst);
output data_out;
input data_in;
input load;
input clk,rst;
reg data_out;
always @(posedge clk or negedge rst)
begin
if(rst==0) data_out<=0;
else if(load==1) data_out<=data_in;
end
endmodule
module Adress_Register(data_out,data_in,load,clk,rst);
parameter word_size =8;
output [word_size-1:0] data_out;
input [word_size-1:0] data_in;
input load;
input clk,rst;
reg [word_size-1:0] data_out;
always @(posedge clk or negedge rst)
begin
if(rst==0) data_out<=0;
else if(load) data_out<=data_in;
end
endmodule
module Instruction_Register (data_out,data_in,load,clk,rst);
parameter word_size =8;
output [word_size-1:0] data_out;
input [word_size-1:0] data_in;
input load;
input clk,rst;
reg [word_size-1:0] data_out;
always @(posedge clk or negedge rst)
begin
if(rst==0) data_out<=0;
else if(load) data_out<=data_in;
end
endmodule
module Program_Counter (count,data_in,Load_PC,Inc_PC,clk,rst);
parameter word_size =8;
output [word_size-1:0] count;
input [word_size-1:0] data_in;
input Load_PC,Inc_PC;
input clk,rst;
reg [word_size-1:0] count;
always @(posedge clk or negedge rst)
begin
if(rst==0) count<=0;
else if(Load_PC==1)count<=data_in;
else if (Inc_PC)
count<=count+1;
end
endmodule
module Multiplexer_5ch (mux_out,data_a,data_b,data_c,data_d,data_e,sel);
parameter word_size =8;
output [word_size-1:0] mux_out;
input [word_size-1:0] data_a,data_b,data_c,data_d,data_e;
input [2:0]sel;
assign mux_out=(sel==0) ? data_a:(sel==1)
?data_b:(sel==2)
?data_c:(sel==3)
?data_d:(sel==4)?
data_e:3'bx;
endmodule
module Multiplexer_3ch (mux_out,data_a,data_b,data_c,sel);
parameter word_size =8;
output [word_size-1:0] mux_out;
input [word_size-1:0] data_a,data_b,data_c;
input [1:0]sel;
assign mux_out=(sel==0) ? data_a:(sel==1)
?data_b:(sel==2)
?data_c:3'bx;
endmodule
module Alu_RISC (alu_zero_flag,alu_out,data_1,data_2,sel);
parameter word_size =8;
parameter op_size =4;
parameter NOP =4'b0000;
parameter ADD =4'b0001;
parameter SUB =4'b0010;
parameter AND =4'b0011;
parameter NOT =4'b0100;
parameter RD =4'b0101;
parameter WR =4'b0110;
parameter BR =4'b0111;
parameter BRZ =4'b1000;
output alu_zero_flag;
output [word_size-1:0] alu_out;
input [word_size-1:0] data_1,data_2;
input [op_size-1:0] sel;
reg alu_out;
assign alu_zero_flag=~|alu_out;
always@(sel or data_1 or data_2)
case (sel)
NOP: alu_out=0;
ADD: alu_out=data_1+data_2;
SUB: alu_out=data_2-data_1;
AND: alu_out=data_1&data_2;
NOT: alu_out=~data_2;
default : alu_out=0;
endcase
endmodule
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,write,instruction,zero,clk,rst);
parameter word_size =8,op_size=4,state_size=4;
parameter src_size=2,dest_size=2,Sel1_Size=3,Sel2_Size=2;
parameter S_idle=0,S_fet1=1,S_fet2=2,S_dec=3;
parameter S_ex1=4,S_rd1=5,S_rd2=6;
parameter 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;
parameter RD=5,WR=6,BR=7,BRZ=8;
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;
output [Sel2_Size-1:0] Sel_Bus_2_Mux;
output write;
input [word_size-1:0] instruction;
input zero;
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;
reg Load_Reg_Z,write;
reg err_flag;
wire [op_size-1:0] opcode=instruction [word_size-1:word_size-op_size];
wire [src_size-1:0] src=instruction [src_size+dest_size-1:dest_size];
wire [dest_size-1:0] dest=instruction [dest_size-1:0];
assign Sel_Bus_1_Mux[Sel1_Size-1:0]=Sel_R0 ?0:Sel_R1 ? 1:Sel_R2 ? 2:Sel_R3 ? 3:Sel_PC ? 4:3'bx;
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
if(rst==0) state<=S_idle;
else state <=next_state;
end
always@(state or opcode or src or dest or zero)
begin
Sel_R0=0;Sel_R1=0;Sel_R2=0;Sel_R3=0;Sel_PC=0;
Load_R0=0;Load_R1=0;Load_R2=0;Load_R3=0;Load_PC=0;Inc_PC=0;
Load_IR=0;Load_Add_R=0;Load_Reg_Y=0;Load_Reg_Z=0;
Inc_PC=0;
Sel_ALU=0;
Sel_Bus_1=0;
Sel_Mem=0;
write=0;
err_flag=0;
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,AND: 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 //ADD SUB AND-src case
end //add sub and
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 //not-src case
case (dest)
R0: Load_R0=1;
R1: Load_R1=1;
R2: Load_R2=1;
R3: Load_R3=1;
default: err_flag=1;
endcase //not-dest case
end //not
RD:
begin
next_state =S_rd1;
Sel_PC=1;
Sel_Bus_1=1;
Load_Add_R=1;
end //RD
WR:
begin
next_state =S_wr1;
Sel_PC=1;
Sel_Bus_1=1;
Load_Add_R=1;
end//WR
BR: begin
next_state=S_br1;
Sel_PC=1;Sel_Bus_1=1;Load_Add_R=1;
end //BR
BRZ:
if(zero==1)begin
next_state=S_br1;
Sel_PC=1;Sel_Bus_1=1;Load_Add_R=1;
end
else begin
next_state=S_fet1;
Inc_PC =1;
end
default : next_state=S_halt;
endcase//opcode
S_ex1: begin
next_state=S_fet1;
Load_Reg_Z=1;
Sel_ALU=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 //S_EX1--DEST--CASE
end
S_rd1: begin
next_state=S_rd2;
Sel_Mem=1;
Load_Add_R=1;
Inc_PC=1;
end
S_wr1: begin
next_state=S_wr2;
Sel_Mem=1;
Load_Add_R=1;
Inc_PC=1;
end
S_rd2: begin
next_state=S_fet1;
Sel_Mem=1;
case (dest)
R0:begin Load_R0=1;end
R1:begin Load_R1=1;end
R2:begin Load_R2=1;end
R3:begin Load_R3=1;end
default : err_flag =1;
endcase //S_rd2--DEST--CASE
end
S_wr2: begin
next_state=S_fet1;
write=1;
case (src)
R0:begin Sel_R0=1;end
R1:begin Sel_R1=1;end
R2:begin Sel_R2=1;end
R3:begin Sel_R3=1;end
default : err_flag =1;
endcase //S_wr2--DEST--CASE
end
S_br1: begin next_state=S_br2;
Sel_Mem=1;
Load_Add_R=1;
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
module Memory_Unit (data_out,data_in,address,clk,write);
parameter word_size=8;
parameter memory_size=256;
output[word_size-1:0] data_out;
input [word_size-1:0] data_in;
input [word_size-1:0] address;
input clk,write;
reg [word_size-1:0] memory [memory_size-1:0];
assign data_out=memory[address]<=data_in;
endmodule
本站相关资讯链接
找不到想要的,那就在这里Google一下!
(责任编辑:admin)