计算机组成原理---实验代码:CPU部分

1.regfile.v

module regfile  (rna, rnb, d, wn,we, clk, clrn, qa, qb);
input    [4:0]  rna,rnb,wn;
input    [31:0]  d;
input    we, clk, clrn;
output  [31:0]  qa,qb;
reg     [31:0]  register  [1:31];  //  31  x  32-bit  regs


//  2  read ports
assign qa  =   (rna ==  0) ? 0 : register[rna]; 
assign qb  =   (rnb ==  0) ? 0 : register[rnb];
 


//  1  write port
always @(posedge clk or negedge clrn)
begin 
if  (clrn==0)  
begin
	integer i;
	for(i=1;i<32;i=i+1)
	register[i] <= 0;
end 
else  if((wn!=0)&&we)
register[wn]  <= d;
end
endmodule

2.sccmop_dataflow.v

module  sccomp_dataflow(clock, resetn, inst, pc, aluout, memout,mem_clk);
input  clock, resetn,mem_clk;
output   [31:0]  inst,pc, aluout,memout;
wire [31:0]   data;
wire   wmem;
sccpu_dataflow s (clock, resetn, inst,memout,pc, wmem, aluout, data);
scinstmem imem (pc,inst);
scdatamem dmem (clock, memout, data, aluout, wmem, mem_clk, mem_clk);
endmodule

3.sccpu_dataflow.v

module  sccpu_dataflow(clock, resetn, inst,mem,pc, wmem,alu,data);
input     [31:0]   inst,mem;
input         clock,resetn;
output   [31:0]  pc,alu,data;
 
output wmem;
wire  [31:0] p4 , bpc, npc, adr, ra, alua, alub, res, alu_mem;
wire  [3:0] aluc;
wire  [4:0] reg_dest, wn;
wire  [1:0] pcsource;
wire  zero, wmem, wreg, regrt, m2reg, shift, aluimm, jal, sext;
wire  [31:0]  sa  =  {
    
    27'b0,inst[10:6]};
wire  [31:0]  offset  =  {
    
    imm[13:0],inst[15:0],2'b00};
sccu_dataflow cu  (inst[31:26] , inst[5:0] , zero, wmem,wreg,regrt,m2reg, aluc, shift, aluimm,pcsource, jal, sext);
wire   e  =  sext  &  inst[15];
wire   [15:0]       imm =  {
    
    16{
    
    e}};
wire  [31:0]       immediate  =  {
    
    imm,inst[15:0]};
dff32  ip  (npc,clock,resetn,pc);
cla32  pcplus4   (pc,32'h4,1'b0,p4);
cla32  br_adr     (p4,offset,1'b0, adr);
wire  [31:0]        jpc =  {
    
    p4[31:28],inst[25:0],2'b00};
mux2x32  alu_b  (data, immediate,aluimm, alub) ;
mux2x32  alu_a  (ra,sa,shift,alua);
mux2x32  result   (alu,mem,m2reg,alu_mem);
mux2x32  link (alu_mem,p4,jal,res);
mux2x5  reg_wn   (inst[15:11], inst[20: 16] , regrt, reg_dest);
assign wn = reg_dest   |   {
    
    5{
    
    jal}};                                 //ja1:  r31  <-- p4;
mux4x32  nextpc  (p4,adr,ra, jpc,pcsource,npc);
regfile  rf   (inst[25:21] ,inst[20:16] ,res,wn,wreg,clock,resetn,ra,data);
alu  al_unit   (alua,alub,aluc,alu, zero); 
endmodule

4.sccu_dataflow.v

module sccu_dataflow (op,func,z,wmem,wreg,regrt,m2reg,aluc,shift,aluimm,pcsource,jal,sext);
	input [5:0] op,func;
	input z;
	output wreg,regrt,jal,m2reg,shift,aluimm,sext,wmem;
	output [3:0] aluc;
	output [1:0] pcsource;
	
	wire r_type = ~|op;
	
	wire i_add = r_type&func[5]&~func[4]&~func[3]&~func[2]&~func[1]&~func[0];
	wire i_sub = r_type&func[5]&~func[4]&~func[3]&~func[2]&func[1]&~func[0];
	wire i_and = r_type&func[5]&~func[4]&~func[3]&func[2]&~func[1]&~func[0];
	wire i_or = r_type&func[5]&~func[4]&~func[3]&func[2]&~func[1]&func[0];
	wire i_xor = r_type&func[5]&~func[4]&~func[3]&func[2]&func[1]&~func[0];
	wire i_sll = r_type&~func[5]&~func[4]&~func[3]&~func[2]&~func[1]&~func[0];
	wire i_srl = r_type&~func[5]&~func[4]&~func[3]&~func[2]&func[1]&~func[0];
	wire i_sra = r_type&~func[5]&~func[4]&~func[3]&~func[2]&func[1]&func[0];
	wire i_jr = r_type&~func[5]&~func[4]&func[3]&~func[2]&~func[1]&~func[0];
	wire i_addi = ~op[5]&~op[4]&op[3]&~op[2]&~op[1]&~op[0];
	wire i_andi = ~op[5]&~op[4]&op[3]&op[2]&~op[1]&~op[0];
	wire i_ori = ~op[5]&~op[4]&op[3]&op[2]&~op[1]&op[0];
	wire i_xori = ~op[5]&~op[4]&op[3]&op[2]&op[1]&~op[0];
	wire i_lw = op[5]&~op[4]&~op[3]&~op[2]&op[1]&op[0];
	wire i_sw = op[5]&~op[4]&op[3]&~op[2]&op[1]&op[0];
	wire i_beq = ~op[5]&~op[4]&~op[3]&op[2]&~op[1]&~op[0];
	wire i_bne = ~op[5]&~op[4]&~op[3]&op[2]&~op[1]&op[0];
	wire i_lui = ~op[5]&~op[4]&op[3]&op[2]&op[1]&op[0];
	wire i_j = ~op[5]&~op[4]&~op[3]&~op[2]&op[1]&~op[0];
	wire i_jal = ~op[5]&~op[4]&~op[3]&~op[2]&op[1]&op[0];
	
	assign wreg = i_add|i_sub|i_and|i_or|i_xor|i_sll|i_srl|i_sra|i_addi|i_andi|i_ori|i_xori|i_lw|i_lui|i_jal;
	assign regrt= i_addi|i_andi|i_ori|i_xori|i_lw|i_lui;
	assign jal= i_jal;
	assign m2reg= i_lw;
	assign shift=i_sll|i_srl|i_sra;
	assign aluimm=i_addi|i_andi|i_ori|i_xori|i_lw|i_lui|i_sw;
	assign sext =i_addi|i_lw|i_sw|i_beq|i_bne;
	assign aluc[3]=i_sra;
	assign aluc[2]=i_sub|i_or|i_srl|i_sra|i_ori|i_lui;
	assign aluc[1]=i_xor|i_sll|i_sra|i_xori|i_beq|i_bne|i_lui;
	assign aluc[0]=i_and|i_or|i_sll|i_srl|i_sra|i_andi|i_ori;
	assign wmem = i_sw;
	assign pcsource[1]=i_jr|i_j|i_jal;
	assign pcsource[0]=i_beq&z|i_bne&~z|i_j|i_jal;
endmodule	

5.scdatamem.v

/*module scdatamem (clk,dataout,datain,addr,we,inclk,outclk);
input	[31:0]	datain;
input	[31:0]	addr ;
input		clk, we, inclk, outclk;
output	[31:0]	dataout;
wire    write_enable = we & ~clk;
lpm_ram_dp ram(.data(datain),
	           .address (addr[6:2]),
			.we(write_enable),
			.outclock(outclk),
			.q(dataout));
defparam ram.lpm_width = 32;
defparam ram.lpm_widthad = 5;
defparam ram.lpm_indata = "registered";
defparam ram.lpm_outdata = "registered";
defparam ram.lpm_file = "scdatamem.mif";
defparam ram.lpm_address_control = "registered";
//defparam ram.lpm_rdaddress_control = "registered";
//defparam ram.lpm_wraddress_control = "registered";
endmodule*/

module scdatamem (clk,dataout,datain,addr,we,inclk,outclk);
input	[31:0]	datain;
input	[31:0]	addr ;
input		clk, we, inclk, outclk;
output	[31:0]	dataout;
reg [31:0] ram	[0:31];
assign	dataout	=ram[addr[6:2]];
always @ (posedge clk) begin
	if (we) ram[addr[6:2]] = datain;
end
integer i;
initial begin
	for (i = 0;i < 32;i = i + 1)
		ram[i] = 0;
	ram[5'h14] = 32'h000000a3;
	ram[5'h15] = 32'h00000027;
	ram[5'h16] = 32'h00000079;
	ram[5'h17] = 32'h00000115;
end
endmodule

6.scinstmem.v

/*module scinstmem (a,inst);

	input [31:0] a;
	output [31:0] inst;
	lpm_rom lpm_rom_component (.address (a[6:2]),
				   .q (inst));
	defparam lpm_rom_component.lpm_width = 32,
                 lpm_rom_component.lpm_widthad = 5,
                 lpm_rom_component.lpm_numwords = "unused",
		         lpm_rom_component.lpm_file = "scinstmem.mif",
                 lpm_rom_component.lpm_indata = "unused", 
                 lpm_rom_component.lpm_outdata = "unregistered",
                 lpm_rom_component.lpm_address_control ="unregistered";
            
endmodule*/


module scinstmem (a,inst); 
	input [31:0] a; 
	output [31:0] inst; 
	wire [31:0] rom [0:31];
 	assign  rom[5'h00] = 32'h3c010000; // (00) main: lui r1,0
	assign  rom[5'h01] = 32'h34240050; // (04)      ori r4,r1,80
	assign  rom[5'h02] = 32'h20050004; // (08)      addi r5,r0, 4
	assign  rom[5'h03] = 32'h0c000018; // (0c)call: jal sum
	assign  rom[5'h04] = 32'hac820000; // (10)      sw r2,0(r4)
	assign	rom[5'h05] = 32'h8c890000;	//	(14)		lw	r9,	0(r4)
	assign	rom[5'h06] = 32'h01244022;	//	(18)		sub	r8,	r9.	r4
	assign	rom[5'h07] = 32'h20050003;	//	(lc)		addi	r5,	r0.	3
	assign	rom[5'h08] = 32'h20a5ffff;	//	(20)	loop2:	addi	r5,	r5,	-1
	assign	rom[5'h09] = 32'h34a8ffff;	//	(24)		ori	r8,	r5,	0xffff
	assign	rom[5'h0A] = 32'h39085555;	//	(28)		xori	r8.	r8,	0x5555
	assign	rom[5'h0B] = 32'h2009ffff;	//	(2c)		addi	r9,	rO,	-1
	assign	rom[5'h0C] = 32'h312affff;	//	(30)		andi	rlO,	r9,	0xffff
	assign	rom[5'h0D] = 32'h01493025;	//	(34)		or	r6.	rlO,	r9
	assign	rom[5'h0E] = 32'h01494026;	//	(38)		xor	r8,	rlO,	r9
	assign	rom[5'h0F] = 32'h01463824;	//	(3c)		and	r7,	rlO,	r6
	assign	rom[5'h10] = 32'h10a00001;	//	(40)		beq	r5,	r0,	shift
	assign	rom[5'h11] = 32'h08000008;	//	(44)		j	loop2	
	assign	rom[5'h12] = 32'h2005ffff;	//	(48)	shift:	addi	r5.	r0,	-1
	assign	rom[5'h13] = 32'h000543c0;	//	(4c)		sll	r8.	r5.	15
	assign	rom[5'h14] = 32'h00084400;	//	(50)		sll	r8,	r8,	16
	assign	rom[5'h15] = 32'h00084403;	//	(54)		sra	r8,	r8,	16
	assign	rom[5'h16] = 32'h000843c2;	//	(58)		srl	r8.	r8.	15
	assign	rom[5'h17] = 32'h08000017;	//	(5c)	finish:	j	finish	
	assign	rom[5'h18] = 32'h00004020;	//	(60)	sum:	add	r8,	r0,	r0
	assign	rom[5'h19] = 32'h8c890000;	//	(64)	loop:	lw	r9,	(r4)
	assign	rom[5'h1A] = 32'h20840004;	//	(68)		addi	r4,	r4,	4
	assign	rom[5'h1B] = 32'h01094020;	//	(6c)		add	r8,	r8,	r9
	assign	rom[5'h1C] = 32'h20a5ffff;	//	(70)		addi	r5,	r5,	-1
	assign	rom[5'h1D] = 32'h14a0fffb;	//	(74)		bne	rS,	r0,	loop
	assign	rom[5'h1E] = 32'h00081000;	//	(78)		sll	r2f	r8f	0
	assign	rom[5'h1F] = 32'h03e00008;	//	(7c)		jr	r31		
	assign inst = rom[a[6:2]];

endmodule

7.shift.v

module shift (d,sa,right,arith,sh);
input  [31:0]  d;
input  [4:0]     sa;
input  right,arith;
output [31:0] sh;
reg  [31:0] sh;
always  @*  begin
	if   (!right)  begin                        //shift left
		sh = d << sa;
	end else  if   (!arith)  begin              //shift right logical
		sh =  d  >>  sa;
	end else begin                              //shift right arithmetic
		sh =  $signed(d)  >>>  sa;
	end
end
endmodule

猜你喜欢

转载自blog.csdn.net/qq_44528283/article/details/112557349