说明:
后面做题的时候有对前面的代码进行更正, 所以会出现拼接在一起过不去的情况.
如果有及时联系我, 我会进行修改.
预习
大小比较器
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