Skip to content

Commit

Permalink
cpu54
Browse files Browse the repository at this point in the history
  • Loading branch information
mahiru23 committed Feb 24, 2022
0 parents commit 131ff66
Show file tree
Hide file tree
Showing 1,086 changed files with 179,290 additions and 0 deletions.
Binary file added 1953072-肖鹏飞-54条指令单周期CPU.pdf
Binary file not shown.
109 changes: 109 additions & 0 deletions CP0.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
module CP0(
input clk,
input rst,
input mfc0,//读cp0寄存器
input mtc0,//写cp0寄存器
input [31:0]pc,
input [4:0]Rd,//写cp0寄存器地址
input [31:0]wdata,//写cp0寄存器值
input exception,
input eret,//eret异常返回
input [4:0]cause,//中断序号,5'b01000(syscall) 5'b01001(break) 5'b01101(teq)
input intr,//外部中断,没用
output [31:0]rdata,//读到的cp0寄存器值
output [31:0]status,
output reg timer_int,//定时产生外部中断,没用
output reg [31:0]exc_addr
);

reg [31:0] reg_cp0[0:31];
/*status:12号寄存器,cause:13号寄存器,epc:14号寄存器*/
/*cause[6:2]为异常类型号,5'b01000(syscall) 5'b01001(break) 5'b01101(teq)*/

assign rdata = mfc0 ? reg_cp0[Rd] : 0;
assign status = reg_cp0[12];


always @(posedge clk or posedge rst)
begin
if(rst==1'b1)
begin
reg_cp0[12]=32'h0000000f;
reg_cp0[13]=32'h00000000;
reg_cp0[14]=32'h00000000;
exc_addr=32'h00400000;
end
else if(mtc0==1'b1)
begin
reg_cp0[Rd]=wdata;
exc_addr=32'h00400004;//异常地址入口为0x4
end
else if(exception==1'b1)
begin
if(eret==1'b1)
begin
reg_cp0[12]=reg_cp0[12]>>5;//关闭异常,右移5位,开中断
exc_addr=reg_cp0[14];
end
else if(cause==5'b01000)//syscall
begin
if(reg_cp0[12][1]==1'b1)
begin
exc_addr=32'h00400004;//异常地址入口为0x4
reg_cp0[12]=(reg_cp0[12]<<5);
reg_cp0[13][6:2]=5'b01000;
reg_cp0[14]=pc;
end
else
begin
exc_addr=pc+4;
end
end
else if(cause==5'b01001)//break
begin
if(reg_cp0[12][2]==1'b1)
begin
exc_addr=32'h00400004;//异常地址入口为0x4
reg_cp0[12]=reg_cp0[12]<<5;
reg_cp0[13][6:2]=5'b01001;
reg_cp0[14]=pc;
end
else
begin
exc_addr=pc+4;
end
end
else if(cause==5'b01101)//teq
begin
if(reg_cp0[12][3]==1'b1)
begin
exc_addr=32'h00400004;//异常地址入口为0x4
reg_cp0[12]=reg_cp0[12]<<5;
reg_cp0[13][6:2]=5'b01101;
reg_cp0[14]=pc;
end
else
begin
exc_addr=pc+4;
end
end
else
begin
//其他指令,未实现


end


end
else
begin

end


end



endmodule
Binary file added CPU54.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added CPU54控制信号表.xlsx
Binary file not shown.
Binary file added CPU54部件对应表.xlsx
Binary file not shown.
76 changes: 76 additions & 0 deletions DIV.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
module DIV(
input [31:0]dividend,
input [31:0]divisor,
input start,
input clock,
input reset,
output [31:0]q,
output [31:0]r,
output reg busy,
output reg over
);

wire ready;
reg [4:0]count;
reg [31:0]reg_q;
reg [31:0]reg_r;
reg [31:0]reg_b;
reg busy2,r_sign;

wire [31:0] dividend_yuan= dividend[31]?(~(dividend-1)):dividend;
wire [31:0] divisor_yuan= divisor[31]?(~(divisor-1)):divisor;
wire dividend_sign= dividend[31];
wire divisor_sign= divisor[31];
wire [31:0] rr = r_sign ? reg_r + reg_b : reg_r;
wire [31:0] qq = reg_q;


assign ready = ~busy & busy2;

wire [32:0] sub_add = r_sign ? ({reg_r,qq[31]}+{1'b0,reg_b}) : ({reg_r,qq[31]}-{1'b0,reg_b}) ;

assign r= dividend_sign?((~rr)+1):rr;
assign q= (dividend_sign+divisor_sign)?((~qq)+1):qq;


always @(posedge clock or posedge reset)
begin
if(reset==1)
begin
count<=5'b0;
busy<=0;
busy2<=0;
over<=0;
end
else
begin
busy2<=busy;
if(over==1)
begin
over<=0;
end
else if(start)
begin
reg_r<=32'b0;
r_sign<=0;
reg_q<=dividend_yuan;
reg_b<=divisor_yuan;
count<=5'b0;
busy<=1'b1;
over<=0;
end
else if(busy)
begin
reg_r<=sub_add[31:0];
r_sign<=sub_add[32];
reg_q<={reg_q[30:0],~sub_add[32]};
count<=count+5'b1;
if(count==5'b11111)
begin
busy<=0;
over<=1;
end
end
end
end
endmodule
64 changes: 64 additions & 0 deletions DIVU.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module DIVU(
input [31:0]dividend,
input [31:0]divisor,
input start,
input clock,
input reset,
output [31:0]q,
output [31:0]r,
output reg busy,
output reg over
);
wire ready;
reg [4:0]count;
reg [31:0]reg_q;
reg [31:0]reg_r;
reg [31:0]reg_b;
reg busy2,r_sign;
assign ready = ~busy & busy2;

wire [32:0] sub_add = r_sign ? ({reg_r,q[31]}+{1'b0,reg_b}) : ({reg_r,q[31]}-{1'b0,reg_b}) ;
assign r = r_sign ? reg_r + reg_b : reg_r;
assign q = reg_q;

always @(posedge clock or posedge reset)
begin
if(reset==1)
begin
count<=5'b0;
busy<=0;
busy2<=0;
over<=0;
end
else
begin
busy2<=busy;
if(over==1)
begin
over<=0;
end
else if(start)
begin
reg_r<=32'b0;
r_sign<=0;
reg_q<=dividend;
reg_b<=divisor;
count<=5'b0;
busy<=1'b1;
over<=0;
end
else if(busy)
begin
reg_r<=sub_add[31:0];
r_sign<=sub_add[32];
reg_q<={reg_q[30:0],~sub_add[32]};
count<=count+5'b1;
if(count==5'b11111)
begin
busy<=0;
over<=1;
end
end
end
end
endmodule
Loading

0 comments on commit 131ff66

Please sign in to comment.