西工大计组实验_verilog实现单周期CPU_2022

说明:

后面做题的时候有对前面的代码进行更正,  所以会出现拼接在一起过不去的情况.

如果有及时联系我, 我会进行修改. 


预习

大小比较器

module comparer #(parameter width=8) (gt,lt,eq,a,b);

output reg gt,lt,eq;

input [width-1:0] a,b;

always@(a,b)

begin
gt=0;
eq=0;
lt=0;

if(a[31]>=1&&b[31]<1)
lt=1;
else if(a[31]<1&&b[31]>=1)
gt=1;
else if(a[31]<1&&b[31]<1)
	if(a>b) gt=1;
	else if(a==b) eq=1;
	else lt=1;
else
	if(a<b) lt=1;
	else if(a==b) eq=1;
	else gt=1;
end

endmodule

D触发

module d_ff  #(parameter WIDTH = 8) (q, d, reset, clock);


output reg [WIDTH-1 : 0] q;

input [WIDTH-1 : 0] d;

input reset, clock;
always@(posedge clock or negedge reset)
begin

if(reset==0)q=0;
else
q<=d;
end
endmodule

 实验一

pc模块

module pc(pc,clock,reset,npc);



output reg[31:0] pc;

input clock;

input reset;

input [31:0] npc;

always@(posedge clock, negedge reset)

begin 

if(clock) pc[31:0]<=npc[31:0];

if (!reset) pc[31:0]<=32'h0000_3000;

end

endmodule

 im模块

module im(instruction,pc);

output [31:0] instruction;

input [31:0] pc;

reg [31:0] ins_memory[1023:0]; 

assign instruction[31:0]=ins_memory[pc[11:0]>>2];

endmodule

gpr模块

module gpr(a,b,clock,reg_write,num_write,rs,rt,data_write);



output [31:0] a;  

output [31:0] b;

input clock;

input reg_write;

input [4:0] rs; //read reg1

input [4:0] rt; //read reg2

input [4:0] num_write; //write reg

input [31:0] data_write; //write data



reg [31:0] gp_registers[31:0];  //32* reg

always@(posedge clock)

begin

if(reg_write)

gp_registers[num_write]=data_write;


end

assign a=(rs==5'b0)?32'b0:gp_registers[rs];

assign b=(rt==5'b0)?32'b0:gp_registers[rt];

endmodule

 alu模块

module alu(c,a,b);



output [31:0] c;

input [31:0] a;

input [31:0] b;

assign c=a+b;

endmodule

 单周期cpu--addu

说明: 本模块未使用ctrl.v, 实际代码规范性上不符合考核要求, 已在实验二进行修改.

s_cycle_cpu.v 

module s_cycle_cpu(clock,reset);

input clock;
input reset;

wire clock;

wire [31:0] pc;
wire [31:0] npc;

wire [31:0] instruction;

wire [31:0] a;
wire [31:0] b;


wire [4:0] rt;
wire [4:0] rs;
wire [4:0] num_write;
wire [31:0] data_write;
wire reg_write;



assign reg_write=1;
assign rt=instruction[20:16];
assign rs=instruction[25:21];
assign num_write=instruction[15:11];



pc PC(.pc(pc),.clock(clock),.reset(reset),.npc(npc));
im IM(.instruction(instruction),.pc(pc));
gpr GPR(.a(a),.b(b),.clock(clock),.reg_write(reg_write),.num_write(num_write),.rs(rs),.rt(rt),.data_write(data_write));
alu ALU2(.c(data_write),.a(a),.b(b));
alu ALU1(.c(npc),.a(32'h0000_0004),.b(pc));


endmodule

alu.v 

module alu(c,a,b);



output [31:0] c;

input [31:0] a;

input [31:0] b;

assign c=a+b;

endmodule

gpr.v

module gpr(a,b,clock,reg_write,num_write,rs,rt,data_write);



output [31:0] a;  

output [31:0] b;

input clock;

input reg_write;

input [4:0] rs; //read reg1

input [4:0] rt; //read reg2

input [4:0] num_write; //write reg

input [31:0] data_write; //write data



reg [31:0] gp_registers[31:0];  //32* reg

always@(posedge clock)

begin

if(reg_write)

gp_registers[num_write]<=data_write;


end

assign a=(rs==5'b0)?32'b0:gp_registers[rs];

assign b=(rt==5'b0)?32'b0:gp_registers[rt];

endmodule

im.v

module im(instruction,pc);

output [31:0] instruction;

input [31:0] pc;

reg [31:0] ins_memory[1023:0]; 

assign instruction[31:0]=ins_memory[pc[11:0]>>2];

endmodule

pc.v

module pc(pc,clock,reset,npc);


output reg[31:0] pc;

input clock;

input reset;

input [31:0] npc;

always@(posedge clock, negedge reset)

begin 

if(!reset)pc<=32'h00003000;
else
pc<=npc;

end

endmodule

 单周期cpu--R型指令

说明: 本模块未使用ctrl.v, 实际代码规范性上不符合考核要求, 已在实验二进行修改.

add.v

module add(npc,adder,pc);

output [31:0] npc;
input [31:0] adder;
input [31:0] pc;

assign npc=pc+adder;

endmodule

s_cycle_cpu.v 

module s_cycle_cpu(clock,reset);

input clock;
input reset;

wire clock;

wire [31:0] pc;
wire [31:0] npc;

wire [31:0] instruction;

wire [31:0] a;
wire [31:0] b;


wire [4:0] rt;
wire [4:0] rs;
wire [4:0] num_write;
wire [31:0] data_write;
wire [3:0] ins;
wire reg_write;

assign ins=instruction[3:0];

assign reg_write=1;
assign rt=instruction[20:16];
assign rs=instruction[25:21];
assign num_write=instruction[15:11];



pc PC(.pc(pc),.clock(clock),.reset(reset),.npc(npc));
im IM(.instruction(instruction),.pc(pc));
gpr GPR(.a(a),.b(b),.clock(clock),.reg_write(reg_write),.num_write(num_write),.rs(rs),.rt(rt),.data_write(data_write));
alu ALU(.c(data_write),.a(a),.b(b),.ins(ins));
add ADD(.npc(npc),.adder(32'h0000_0004),.pc(pc));


endmodule

alu.v

module alu(c,a,b,ins);



output reg[31:0] c;

input [31:0] a;

input [31:0] b;

input [3:0] ins;

always@(*)
begin
case(ins)
4'b0001:c<=a+b;
4'b0011:c<=a-b;
4'b0000:c<=a+b;
4'b0100:c<=a&b;
4'b0101:c<=a|b;
4'b1010:
begin
if(a[31]>=1&&b[31]<1)
	c<=1;
else if(a[31]<1&&b[31]>=1)
	c<=0;
else c<=(a<b);
end
endcase
end

endmodule

gpr.v

module gpr(a,b,clock,reg_write,num_write,rs,rt,data_write);



output [31:0] a;  

output [31:0] b;

input clock;

input reg_write;

input [4:0] rs; //read reg1

input [4:0] rt; //read reg2

input [4:0] num_write; //write reg

input [31:0] data_write; //write data



reg [31:0] gp_registers[31:0];  //32* reg

always@(posedge clock)

begin

if(reg_write)

gp_registers[num_write]<=data_write;


end

assign a=(rs==5'b0)?32'b0:gp_registers[rs];

assign b=(rt==5'b0)?32'b0:gp_registers[rt];

endmodule

 im.v

module im(instruction,pc);

output [31:0] instruction;

input [31:0] pc;

reg [31:0] ins_memory[1023:0]; 

assign instruction[31:0]=ins_memory[pc[11:0]>>2];

endmodule

 pc.v

module pc(pc,clock,reset,npc);



output reg[31:0] pc;

input clock;

input reset;

input [31:0] npc;

always@(posedge clock, negedge reset)

begin 

if(!reset)pc<=32'h00003000;
else
pc<=npc;

end

endmodule

 实验二

 add.v

module add(npc,adder,pc);

output [31:0] npc;
input [31:0] adder;
input [31:0] pc;

assign npc=pc+adder;

endmodule

s_cycle_cpu.v

module s_cycle_cpu(clock,reset);

input clock;
input reset;

wire clock;

wire [31:0] pc;
wire [31:0] npc;

wire [31:0] instruction;

wire [31:0] a;
wire [31:0] b;
wire [31:0] alu_b;


wire [4:0] rt;
wire [4:0] rs;
wire [4:0] rd;
wire [31:0] data_write;
wire reg_write;
wire s_num_write;
wire [4:0] num_write;

assign s_num_write=instruction[29];


assign reg_write=1;
assign rt=instruction[20:16];
assign rs=instruction[25:21];
assign rd=instruction[15:11];

wire s_ext;
wire [15:0]imm16;
wire [31:0]imm32;
assign s_ext=instruction[28];
assign imm16=instruction[15:0];
wire [5:0] aluop;

assign aluop=(instruction[31:26]==6'b000000)?instruction[5:0]:instruction[31:26];

wire s_b;
assign s_b=instruction[29];

pc PC(.pc(pc),
	  .clock(clock),
	  .reset(reset),
	  .npc(npc));
im IM(.instruction(instruction),
	  .pc(pc));
gpr GPR(.a(a),
		.b(b),
		.clock(clock),
		.reg_write(reg_write),
		.num_write(num_write),
		.rs(rs),
		.rt(rt),
		.data_write(data_write));
alu ALU(.c(data_write),
		.a(a),
		.b(alu_b),
		.ins(aluop),
		.imm(imm16));
add ADD(.npc(npc),
		.adder(32'h0000_0004),
		.pc(pc));

mux MUX1(.mux_a(rd),
		 .mux_b(rt),
		 .mux_op(s_num_write),
		 .mux_out(num_write));
		 
mux MUX2(.mux_a(b),
		 .mux_b(imm32),
		 .mux_op(s_b),
		 .mux_out(alu_b));
		 
ext EXT(.ext_in(imm16),
		.s_ext(s_ext),
		.ext_out(imm32));
		
endmodule

alu.v 

module alu(c,a,b,ins,imm);



output reg[31:0] c;

input [31:0] a;

input [31:0] b;
input [15:0] imm;

input [5:0] ins;

always@(*)
begin
case(ins)
6'b100001:c<=a+b;
6'b100011:c<=a-b;
6'b100000:c<=a+b;
6'b100100:c<=a&b;
6'b100101:c<=a|b;
6'b101010:
begin
if(a[31]>=1&&b[31]<1)
	c<=1;
else if(a[31]<1&&b[31]>=1)
	c<=0;
else c<=(a<b);
end

6'b001000:c<=a+b;
6'b001001:c<=a+b;
6'b001100:c<=a&b;
6'b001101:c<=a|b;
6'b001111:c<={imm,{16{1'b0}}};

endcase
end

endmodule

ext.v

module ext(ext_in,s_ext,ext_out);

input [15:0] ext_in;
input s_ext;
output [31:0] ext_out;

assign ext_out=(!s_ext)?{{16{ext_in[15]}},ext_in}:{{16{1'b0}},ext_in};

endmodule

gpr.v

module gpr(a,b,clock,reg_write,num_write,rs,rt,data_write);



output [31:0] a;  

output [31:0] b;

input clock;

input reg_write;

input [4:0] rs; //read reg1

input [4:0] rt; //read reg2

input [4:0] num_write; //write reg

input [31:0] data_write; //write data



reg [31:0] gp_registers[31:0];  //32* reg

always@(posedge clock)

begin

if(reg_write)

gp_registers[num_write]<=data_write;


end

assign a=(rs==5'b0)?32'b0:gp_registers[rs];

assign b=(rt==5'b0)?32'b0:gp_registers[rt];

endmodule

im.v

module im(instruction,pc);

output [31:0] instruction;

input [31:0] pc;

reg [31:0] ins_memory[1023:0]; 

assign instruction[31:0]=ins_memory[pc[11:0]>>2];

endmodule

mux.v

module mux(mux_a,mux_b,mux_op,mux_out);

input [31:0]mux_a;
input [31:0]mux_b;
input mux_op;
output[31:0]mux_out;

assign mux_out=mux_op?mux_b:mux_a;

endmodule

pc.v

module pc(pc,clock,reset,npc);



output reg[31:0] pc;

input clock;

input reset;

input [31:0] npc;

always@(posedge clock, negedge reset)

begin 

if(!reset)pc<=32'h00003000;
else
pc<=npc;

end

endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值