尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

简单流水CPU(只考虑数据冲突)

简单流水CPU(只考虑数据冲突) 一、CPU设计框图二、各模块代码1. 流水段寄存器IF/IDtimescale 1ns / 1ps module if_id( input clk, input resetn, input enable, input [31:0] PC, input [31:0] IR, output [31:0] IF_ID_PC, output [31:0] IF_ID_IR ); reg [31:0] IF_ID_1PC,IF_ID_1IR; always (posedge clk or negedge resetn) begin if (!resetn) begin // initial IF_ID_1PC 32h0; IF_ID_1IR 32h0; end else if(!enable)begin end else begin // refresh IF_ID_1PC PC; IF_ID_1IR IR; end end assign IF_ID_PCIF_ID_1PC; assign IF_ID_IRIF_ID_1IR; endmoduleID/EXtimescale 1ns / 1ps module id_ex( input clk, input resetn, input enable, input [31:0] IF_ID_PC, input [31:0] IF_ID_IR, input [31:0] rdata1, input [31:0] rdata2, input [31:0] offset, input RegDst, input MemtoReg, input ALUSrc2, input [1:0] ALUop, input we, input ram_wen, output [31:0] ID_EX_PC, output [31:0] ID_EX_IR, output [31:0] ID_EX_rdata1, output [31:0] ID_EX_rdata2, output [31:0] ID_EX_offset, output [1:0] ID_EX_ALUop, output ID_EX_ALUSrc2, output ID_EX_RegDst, output ID_EX_MemtoReg, output ID_EX_we, output ID_EX_ram_wen, output [4:0] ID_EX_rd1, output [4:0] ID_EX_rd2 ); reg [31:0] ID_EX_1PC; reg [31:0] ID_EX_1IR; reg [31:0] ID_EX_1rdata1; reg [31:0] ID_EX_1rdata2; reg [31:0] ID_EX_1offset; reg [1:0] ID_EX_1ALUop; reg ID_EX_1ALUSrc2; reg ID_EX_1RegDst; reg ID_EX_1MemtoReg; reg ID_EX_1we; reg ID_EX_1ram_wen; reg [4:0] ID_EX_1rd1; reg [4:0] ID_EX_1rd2; always (posedge clk or negedge resetn) begin if (!resetn) begin // initial ID_EX_1PC 32h0; ID_EX_1IR 32h0; ID_EX_1rdata1 32h0; ID_EX_1rdata2 32h0; ID_EX_1offset 32h0; ID_EX_1ALUop2b0; ID_EX_1RegDst 1b0; ID_EX_1MemtoReg 1b0; ID_EX_1ALUSrc2 1b0; ID_EX_1we 1b0; ID_EX_1ram_wen 1b0; ID_EX_1rd15b0; ID_EX_1rd25b0; end else if(!enable)begin ID_EX_1PC 32h0; ID_EX_1IR 32h0; ID_EX_1rdata1 32h0; ID_EX_1rdata2 32h0; ID_EX_1offset 32h0; ID_EX_1ALUop2b0; ID_EX_1RegDst 1b0; ID_EX_1MemtoReg 1b0; ID_EX_1ALUSrc2 1b0; ID_EX_1we 1b0; ID_EX_1ram_wen 1b0; ID_EX_1rd15b0; ID_EX_1rd25b0; end else begin // refresh ID_EX_1PC IF_ID_PC; ID_EX_1IR IF_ID_IR; ID_EX_1ALUop ALUop; ID_EX_1ALUSrc2 ALUSrc2; ID_EX_1MemtoReg MemtoReg; ID_EX_1offset offset; ID_EX_1ram_wen ram_wen; ID_EX_1rd1 IF_ID_IR[15:11]; ID_EX_1rd2 IF_ID_IR[20:16]; ID_EX_1rdata1 rdata1; ID_EX_1rdata2 rdata2; ID_EX_1RegDst RegDst; ID_EX_1we we; end end assign ID_EX_ALUopID_EX_1ALUop; assign ID_EX_ALUSrc2ID_EX_1ALUSrc2; assign ID_EX_IRID_EX_1IR; assign ID_EX_MemtoRegID_EX_1MemtoReg; assign ID_EX_offsetID_EX_1offset; assign ID_EX_PCID_EX_1PC; assign ID_EX_ram_wenID_EX_1ram_wen; assign ID_EX_rd1ID_EX_1rd1; assign ID_EX_rd2ID_EX_1rd2; assign ID_EX_rdata1ID_EX_1rdata1; assign ID_EX_rdata2ID_EX_1rdata2; assign ID_EX_RegDstID_EX_1RegDst; assign ID_EX_weID_EX_1we; endmoduleEX/MEMtimescale 1ns / 1ps module ex_mem( input clk, input resetn, input enable, input [31:0] ID_EX_PC, input [31:0] ID_EX_IR, input [31:0] F, input [31:0] ID_EX_rdata2, input ID_EX_MemtoReg, input ID_EX_ram_wen, input ID_EX_we, input [4:0] r_waddr, output [31:0] EX_MEM_PC, output [31:0] EX_MEM_IR, output [31:0] EX_MEM_rdata2, output [31:0] EX_MEM_ALUResult, output [4:0] EX_MEM_rd, output EX_MEM_MemtoReg, output EX_MEM_ram_wen, output EX_MEM_we ); reg [31:0] EX_MEM_1PC; reg [31:0] EX_MEM_1IR; reg [31:0] EX_MEM_1rdata2; reg [31:0] EX_MEM_1ALUResult; reg [4:0] EX_MEM_1rd; reg EX_MEM_1MemtoReg; reg EX_MEM_1ram_wen; reg EX_MEM_1we; always (posedge clk or negedge resetn) begin if (!resetn) begin //initial EX_MEM_1PC 32h0; EX_MEM_1IR 32h0; EX_MEM_1ALUResult 32h0; EX_MEM_1rdata2 32h0; EX_MEM_1MemtoReg 1b0; EX_MEM_1we 1b0; EX_MEM_1ram_wen 1b0; EX_MEM_1rd5b0; end else if(!enable)begin end else begin EX_MEM_1PC ID_EX_PC; EX_MEM_1IR ID_EX_IR; EX_MEM_1ALUResult F; EX_MEM_1MemtoReg ID_EX_MemtoReg; EX_MEM_1ram_wen ID_EX_ram_wen; EX_MEM_1rd r_waddr; EX_MEM_1rdata2 ID_EX_rdata2; EX_MEM_1we ID_EX_we; end end assign EX_MEM_PCEX_MEM_1PC; assign EX_MEM_IREX_MEM_1IR; assign EX_MEM_ALUResultEX_MEM_1ALUResult; assign EX_MEM_MemtoRegEX_MEM_1MemtoReg; assign EX_MEM_ram_wenEX_MEM_1ram_wen; assign EX_MEM_rdEX_MEM_1rd; assign EX_MEM_rdata2EX_MEM_1rdata2; assign EX_MEM_weEX_MEM_1we; endmoduleMEM/WBtimescale 1ns / 1ps module mem_wb( input clk, input resetn, input enable, input [31:0] EX_MEM_PC, input [31:0] EX_MEM_IR, input [31:0] EX_MEM_ALUResult, input [31:0] ram_rdata, input [4:0] EX_MEM_rd, input EX_MEM_we, input EX_MEM_MemtoReg, output [31:0] MEM_WB_PC, output [31:0] MEM_WB_IR, output [31:0] MEM_WB_ALUResult, output [31:0] MEM_WB_rdata, output [4:0] MEM_WB_rd, output MEM_WB_MemtoReg, output MEM_WB_we ); reg [31:0] MEM_WB_1PC; reg [31:0] MEM_WB_1IR; reg [31:0] MEM_WB_1rdata, MEM_WB_1ALUResult; reg MEM_WB_1MemtoReg, MEM_WB_1we; reg [4:0] MEM_WB_1rd; always (posedge clk or negedge resetn) begin if (!resetn) begin //initial MEM_WB_1PC 32h0; MEM_WB_1IR 32h0; MEM_WB_1rdata 32h0; MEM_WB_1ALUResult 32h0; MEM_WB_1MemtoReg 1b0; MEM_WB_1we 1b0; MEM_WB_1rd5b0; end else if(!enable)begin end else begin MEM_WB_1PC EX_MEM_PC; MEM_WB_1IR EX_MEM_IR; MEM_WB_1ALUResult EX_MEM_ALUResult; MEM_WB_1rd EX_MEM_rd; MEM_WB_1we EX_MEM_we; MEM_WB_1MemtoReg EX_MEM_MemtoReg; MEM_WB_1rdata ram_rdata; end end assign MEM_WB_ALUResultMEM_WB_1ALUResult; assign MEM_WB_IRMEM_WB_1IR; assign MEM_WB_MemtoRegMEM_WB_1MemtoReg; assign MEM_WB_PCMEM_WB_1PC; assign MEM_WB_rdMEM_WB_1rd; assign MEM_WB_rdataMEM_WB_1rdata; assign MEM_WB_weMEM_WB_1we; endmodule2. 其他模块见单周期非流水CPU设计三、 CPU设计timescale 1ns / 1ps define OP 6b000000 define SW 6b101011 define LW 6b100011 define BNE 6b000101 define J 6b000010 module cpu ( input clk, input resetn, output [31:0] debug_wb_pc, output debug_wb_rf_wen, output [4:0] debug_wb_rf_addr, output [31:0] debug_wb_rf_wdata ); (* MARK_DEBUGtrue *) wire ram_wen, we, RegDst, Zero, MemtoReg, ALUSrc1, ALUSrc2; (* MARK_DEBUGtrue *) wire [1:0] ALUop; (* MARK_DEBUGtrue *) wire [4:0] Card, r_waddr; (* MARK_DEBUGtrue *) wire [31:0] r_wdata, A, B, A0, B0, PC, NPC, rdata1, rdata2, F, ram_rdata, IR, offset; // registers needed for pipeline wire [31:0] IF_ID_PC, ID_EX_PC, EX_MEM_PC, MEM_WB_PC, IF_ID_IR, ID_EX_IR, EX_MEM_IR, MEM_WB_IR, ID_EX_rdata1, ID_EX_rdata2, ID_EX_offset, EX_MEM_ALUResult, EX_MEM_rdata2, MEM_WB_rdata, MEM_WB_ALUResult; wire ID_EX_RegDst, ID_EX_MemtoReg, ID_EX_ALUSrc2, ID_EX_we, ID_EX_ram_wen, EX_MEM_MemtoReg, EX_MEM_we, EX_MEM_ram_wen, MEM_WB_MemtoReg, MEM_WB_we; wire [1:0] ID_EX_ALUop; wire [4:0] ID_EX_rd1, ID_EX_rd2, EX_MEM_rd, MEM_WB_rd; wire nop,enable_PC,enable_if_id, enable_id_ex, enable_ex_mem, enable_mem_wb; reg stall; assign enable_PC1,enable_if_id1,enable_id_ex1,enable_ex_mem1,enable_mem_wb1; //PC pc pc ( .clk(clk), .resetn(resetn), .enable(~stall), .NPC(NPC), .PC(PC) ); //ADD ADD ADD ( .A (PC), .B (32h00000004), .out(NPC) ); //instruction memory instr_mem instr_mem ( .addr(PC), .data(IR) ); //control unit Control CU ( .type(IF_ID_IR[31:26]), .RegDst(RegDst), .MemtoReg(MemtoReg), .ALUSrc2(ALUSrc2), .ALUop(ALUop), .we(we), .ram_wen(ram_wen) ); //register file register register ( .clk(clk), .raddr1(IF_ID_IR[25:21]), .rdata1(rdata1), .raddr2(IF_ID_IR[20:16]), .rdata2(rdata2), .we(MEM_WB_we), .waddr(MEM_WB_rd), .wdata(r_wdata) ); //sign_extend(offset) sign_extend sign_extend ( .in (IF_ID_IR[15:0]), .out(offset) ); //mux2_1 mux2_1 ALUsrc1 ( .d0(ID_EX_rdata1), .d1({27b0, ID_EX_offset[10:6]}), .select(ALUSrc1), .out(A0) ); //mux2_1 mux2_1 ALUsrc2 ( .d0(ID_EX_rdata2), .d1(ID_EX_offset), .select(ID_EX_ALUSrc2), .out(B0) ); //ALU control Card ALU_control ALU_control ( .op(ID_EX_offset[5:0]), .select(ID_EX_ALUop), .ALUSrc1(ALUSrc1), .Card(Card) ); //LW-rt or rd mux2_1 dstReg dstReg ( .d0(ID_EX_rd1), .d1(ID_EX_rd2), .select(ID_EX_RegDst), .out(r_waddr) ); //ALU alu alu ( .A(A), .B(B), .Cin(1b0), .Card(Card), .F(F), .Cout(Cout), .Zero(Zero) ); //data memory data_mem data_mem ( .clk(clk), .we(EX_MEM_ram_wen), .addr(EX_MEM_ALUResult), .w_data(EX_MEM_rdata2), .data(ram_rdata) ); //mux2_1 mux2_1 memtoreg ( .d0(MEM_WB_ALUResult), .d1(MEM_WB_rdata), .select(MEM_WB_MemtoReg), .out(r_wdata) ); // pipeline control logic // IF/ID if_id if_id( .clk(clk), .resetn(resetn), .enable(enable_if_id~stall), .PC(PC), .IR(IR), .IF_ID_PC(IF_ID_PC), .IF_ID_IR(IF_ID_IR) ); // ID/EX id_ex id_ex( .clk(clk), .resetn(resetn), .enable(enable_id_ex ~stall), .IF_ID_PC(IF_ID_PC), .IF_ID_IR(IF_ID_IR), .rdata1(rdata1), .rdata2(rdata2), .offset(offset), .RegDst(RegDst), .MemtoReg(MemtoReg), .ALUSrc2(ALUSrc2), .ALUop(ALUop), .we(we nop), .ram_wen(ram_wen), .ID_EX_PC(ID_EX_PC), .ID_EX_IR(ID_EX_IR), .ID_EX_rdata1(ID_EX_rdata1), .ID_EX_rdata2(ID_EX_rdata2), .ID_EX_offset(ID_EX_offset), .ID_EX_ALUop(ID_EX_ALUop), .ID_EX_ALUSrc2(ID_EX_ALUSrc2), .ID_EX_RegDst(ID_EX_RegDst), .ID_EX_MemtoReg(ID_EX_MemtoReg), .ID_EX_we(ID_EX_we), .ID_EX_ram_wen(ID_EX_ram_wen), .ID_EX_rd1(ID_EX_rd1), .ID_EX_rd2(ID_EX_rd2) ); // EX/MEM ex_mem ex_mem( .clk(clk), .resetn(resetn), .enable(enable_ex_mem), .ID_EX_PC(ID_EX_PC), .ID_EX_IR(ID_EX_IR), .F(F), .ID_EX_rdata2(ID_EX_rdata2), .ID_EX_MemtoReg(ID_EX_MemtoReg), .ID_EX_ram_wen(ID_EX_ram_wen), .ID_EX_we(ID_EX_we~Zero), .r_waddr(r_waddr), .EX_MEM_PC(EX_MEM_PC), .EX_MEM_IR(EX_MEM_IR), .EX_MEM_rdata2(EX_MEM_rdata2), .EX_MEM_ALUResult(EX_MEM_ALUResult), .EX_MEM_rd(EX_MEM_rd), .EX_MEM_MemtoReg(EX_MEM_MemtoReg), .EX_MEM_ram_wen(EX_MEM_ram_wen), .EX_MEM_we(EX_MEM_we) ); // MEM/WB mem_wb mem_wb( .clk(clk), .resetn(resetn), .enable(enable_mem_wb), .EX_MEM_PC(EX_MEM_PC), .EX_MEM_IR(EX_MEM_IR), .EX_MEM_ALUResult(EX_MEM_ALUResult), .ram_rdata(ram_rdata), .EX_MEM_rd(EX_MEM_rd), .EX_MEM_we(EX_MEM_we), .EX_MEM_MemtoReg(EX_MEM_MemtoReg), .MEM_WB_PC(MEM_WB_PC), .MEM_WB_IR(MEM_WB_IR), .MEM_WB_ALUResult(MEM_WB_ALUResult), .MEM_WB_rdata(MEM_WB_rdata), .MEM_WB_rd(MEM_WB_rd), .MEM_WB_MemtoReg(MEM_WB_MemtoReg), .MEM_WB_we(MEM_WB_we) ); // data bypassing assign A(EX_MEM_IR[31:26]OP EX_MEM_IR[15:11]ID_EX_IR[25:21] EX_MEM_we)?EX_MEM_ALUResult: (MEM_WB_IR[31:26]OP MEM_WB_IR[15:11]ID_EX_IR[25:21] MEM_WB_we)?MEM_WB_ALUResult: (MEM_WB_IR[31:26]LW MEM_WB_IR[20:16]ID_EX_IR[25:21])?MEM_WB_rdata: A0; assign B(EX_MEM_IR[31:26]OP EX_MEM_IR[15:11]ID_EX_IR[20:16] EX_MEM_we)?EX_MEM_ALUResult: (MEM_WB_IR[31:26]OP MEM_WB_IR[15:11]ID_EX_IR[20:16] MEM_WB_we)?MEM_WB_ALUResult: (MEM_WB_IR[31:26]LW MEM_WB_IR[20:16]ID_EX_IR[20:16])?MEM_WB_rdata: B0; //bubble load //wire stall; //assign stall(ID_EX_IR[31:26]LW (ID_EX_IR[20:16]IF_ID_IR[25:21] |ID_EX_IR[20:16]IF_ID_IR[20:16]))?1:0; always (negedge clk or negedge resetn)begin if(!resetn) stall0; else if(ID_EX_IR[31:26]LW (ID_EX_IR[20:16]IF_ID_IR[25:21] |ID_EX_IR[20:16]IF_ID_IR[20:16])) stall1; else stall0; end assign nop(IF_ID_IR32h0)?0:1; // debug wire [31:0] writeback_instruction_address; assign writeback_instruction_address MEM_WB_we?MEM_WB_PC:EX_MEM_PC; assign debug_wb_pc writeback_instruction_address; assign debug_wb_rf_wen MEM_WB_we; assign debug_wb_rf_addr MEM_WB_rd; assign debug_wb_rf_wdata r_wdata; endmodule四、 CPU_TOP////////////////////////////////////////////////////////////////////////////////// // Copyright HIT team // CPU Automated testing environment ////////////////////////////////////////////////////////////////////////////////// timescale 1ns / 1ps define TRACE_FILE_PATH ...\\lab_1.data\\base_cpu_trace //define TRACE_FILE_PATH ...\\lab_1.data\\additional_cpu_trace1 //define TRACE_FILE_PATH ...\\lab_1.data\\additional_cpu_trace2 define TEST_COUNT 40 module cpu_top( input clk , input reset , output [15 :0] leds ); // Initialize trace file registers reg [71:0] trace_data [TEST_COUNT - 1 :0]; initial begin $readmemh(TRACE_FILE_PATH , trace_data); end // Instantiate the cpu wire [31:0] debug_wb_pc; wire debug_wb_rf_wen; wire [4 :0] debug_wb_rf_addr; wire [31:0] debug_wb_rf_wdata; cpu U_cpu( .clk (clk ), .resetn (reset ), .debug_wb_pc (debug_wb_pc ), .debug_wb_rf_wen (debug_wb_rf_wen ), .debug_wb_rf_addr (debug_wb_rf_addr ), .debug_wb_rf_wdata (debug_wb_rf_wdata ) ); // Compare the cpu data to the reference data reg test_err; reg test_pass; reg [31:0] test_counter; reg [15 :0] leds_reg; wire [31:0] ref_wb_pc trace_data[test_counter][71:40]; wire [4 :0] ref_wb_rf_addr trace_data[test_counter][36:32]; wire [31:0] ref_wb_rf_wdata trace_data[test_counter][31: 0]; assign leds leds_reg; always (posedge clk) begin if (!reset) begin leds_reg 16hffff; test_err 1b0; test_pass 1b0; test_counter 0; end else if (debug_wb_pc 32h000000a0 !test_err) begin $display( ----PASS!!!); $display(Test end!); $display(); test_pass 1b1; leds_reg 16h0000; #5; $finish; end else if (debug_wb_rf_wen |debug_wb_rf_addr !test_pass) begin if (debug_wb_pc ! ref_wb_pc || debug_wb_rf_addr ! ref_wb_rf_addr || debug_wb_rf_wdata ! ref_wb_rf_wdata) begin $display(--------------------------------------------------------------); $display(Error!!!); $display( Reference : PC 0x%8h, write back reg number %2d, write back data 0x%8h, ref_wb_pc, ref_wb_rf_addr, ref_wb_rf_wdata); $display( Error : PC 0x%8h, write back reg number %2d, write back data 0x%8h, debug_wb_pc, debug_wb_rf_addr, debug_wb_rf_wdata); $display(--------------------------------------------------------------); $display(); test_err 1b1; #5; $finish; end else begin test_counter test_counter 1; end end end endmodule五、 测试文件timescale 1ns / 1ps module cpu_tb(); //-----Clock and reset signal simulation----- //signals reg clk; reg resetn; //wire [31:0] debug_wb_pc; //wire debug_wb_rf_wen; //wire [4 :0] debug_wb_rf_addr; //wire [31:0] debug_wb_rf_wdata; //cpu U_cpu( // .clk (clk ), // .resetn (resetn ), // .debug_wb_pc (debug_wb_pc ), // .debug_wb_rf_wen (debug_wb_rf_wen ), // .debug_wb_rf_addr (debug_wb_rf_addr ), // .debug_wb_rf_wdata (debug_wb_rf_wdata ) // ); //simulation initial begin clk 1b0; resetn 1b0; #10; resetn 1b1; #2000; end always #5 clk ~clk; cpu_top U_cpu_top( .clk (clk ), .reset (resetn ) ); //-----monitor test----- initial begin $timeformat(-9,0, ns,10); while(!resetn) #5; $display(); $display(Test begin!); #10000; end endmodule
返回列表