计组实验十老师:包健一、源代码测试模块代码:module Top(inputinclk,inputmem_clk,inputrst,outputreg[7:0] LED,input [3:0] SW);wireclk;MyButtonmb(.clk_100MHz(mem_clk),.BTN(inclk),.BTN_Out(clk));wire [31:0] ALU_F;wire [31:0] M_R_Data;wire ZF;wire OF;wire [31:0]PC;My_I_CPUmy_i_cpu(.clk(clk),.mem_clk(mem_clk),.rst(rst),.ALU_F(ALU_F),.M_R_Data(M_R_Data),.ZFF(ZF),.OF(OF),.PC_out(PC));always@(*)begincase(SW)4'd0:LED=ALU_F[7:0];4'd1:LED=ALU_F[15:8];4'd2:LED=ALU_F[23:16];4'd3:LED=ALU_F[31:24];4'd4:LED=M_R_Data[7:0];4'd5:LED=M_R_Data[15:8];4'd6:LED=M_R_Data[23:16];4'd7:LED=M_R_Data[31:24];4'd8:LED={ZF,6'd0,OF};4'd12:LED=PC[7:0];4'd13:LED=PC[15:8];4'd14:LED=PC[23:16];4'd15:LED=PC[31:24];default:LED=8'b0000_0000;endcaseendendmodule顶层模块代码:moduleMy_I_CPU(inputclk,inputmem_clk,inputrst,output [31:0] ALU_F,output [31:0] M_R_Data,output ZFF,output OF,output [31:0]PC_out);//wire clk_n = ~clk;wire[31:0] codes;wire [31:0]PC_new;reg [31:0]PC;Inst_Fetch1 inst_fetch(.PC(PC),.rst(rst),.clk(clk),.Inst_codes(codes),.PC_new(PC_new));wire[5:0] OP;wire[5:0] func;wire ZF;assign ZFF=ZF;assignPC_out=PC;wire [1:0]w_r_s;wireimm_s;wirert_imm_s;wire [1:0]wr_data_s;wire[2:0] ALU_OP; wireWrite_Reg;wireMem_Write;wire [1:0]PC_s;wire [15:0] imm;wire [31:0] imm_data ; wire [25:0] address;assign OP = codes[31:26]; assignfunc = codes[5:0]; assignimm = codes[15:0]; assign address=codes[25:0];OP_Decoderop_decoder( .OP(OP),//input.func(func),.ZF(ZF),//input.w_r_s(w_r_s),.imm_s(imm_s),.rt_imm_s(rt_imm_s),.wr_data_s(wr_data_s),.ALU_OP(ALU_OP),.Write_Reg(Write_Reg),.Mem_Write(Mem_Write), .PC_s(PC_s));wire[4:0] rs;wire[4:0] rt;wire[4:0] rd;assignrs = codes[25:21]; assignrt = codes[20:16]; assignrd = codes[15:11];wire[4:0] W_Addr;wire [31:0]W_Data;wire [31:0]ALU_B;assign W_Addr=(w_r_s[1])?5'b11111:((w_r_s[0])?rt:rd);assign W_Data=(wr_data_s[1])?PC_new:((wr_data_s[0])?M_R_Data:ALU_F); assign imm_data = (imm_s)?{{16{imm[15]}},imm}:{{16{1'b0}},imm}; assign ALU_B =(rt_imm_s)?imm_data:R_Data_B;always@(*)begincase(PC_s)2'b00:PC=PC_new;2'b01:PC=R_Data_A;2'b10:PC=PC_new+(imm_data<<2);2'b11:PC={PC_new[31:28],address,2'b00};default:PC=PC_new;endcaseendwire [31:0]R_Data_A;wire [31:0]R_Data_B;RegisterHeapregister(.R_Addr_A(rs),.R_Addr_B(rt),.W_Addr(W_Addr),.Write_Reg(Write_Reg),.Reset(rst),.Clk(clk),.W_Data(W_Data),.R_Data_A(R_Data_A),.R_Data_B(R_Data_B));wire [31:0]ALU_A;assign ALU_A = R_Data_A;ALU alu(.ALU_OP(ALU_OP),.A(ALU_A),.B(ALU_B),.F(ALU_F),.ZF(ZF),.OF(OF));Data_Memdata_mem (.clka(mem_clk), // input clka.wea(Mem_Write), // input [0 : 0] wea.addra(ALU_F[5:0]), // input [5 : 0] addra.dina(R_Data_B), // input [31 : 0] dina.douta(M_R_Data) // output [31 : 0] douta);Endmodule二、仿真波形三、电路图四、引脚配置:NET "LED[7]" LOC = "T11";NET "LED[6]" LOC = "R11";NET "LED[5]" LOC = "N11";NET "LED[4]" LOC = "M11";NET "LED[3]" LOC = "V15";NET "LED[2]" LOC = "U15";NET "LED[1]" LOC = "V16";NET "LED[0]" LOC = "U16";//LEDNET "inclk" LOC = "C9";NET "mem_clk" LOC = "V10";//100mHZNET "SW[3]" LOC = "M8";// 右边4个开关NET "SW[2]" LOC = "V9";NET "SW[1]" LOC = "T9";NET "SW[0]" LOC = "T10";NET "rst" LOC = "D9";五、思考与探索1,经过汇编器汇编即可产生程序的机器码。
以执行beq $t2,$zero,Loop2这条指令为例,offect字段值为0001H,此时PC为0000_0020,PC加上offect*4得0000_0024H,正好为Loop2的地址,所以计算的目标地址和转移目标地址一致。
2,这条指令与jal的区别在于增加了一个判断条件,可以将地址为rs值的正负进行判断,即根据指令的OP字段由译码及控制电路产生控制信号,该控制信号用于控制对R_Data_A正负的判断,若R_Data_A为负,则bltzal这条指令的后续执行与jal 相同。
由此便实现了该条指令。
3,其实编写实验八的过程也就是将前面所有的实验进行一次应用和巩固的过程。
当然了,在这个实验中同样涉及到了IP核的应用。