Verilog
Verilog
module top( input clk, reset, output [31:0] WriteData,DataAdr, output MemWrite); wire [31:0] Pcnext, Instr, Readdata; // instantiate processor and memories mips mips (clk,reset,Instr,Readdata,Pcnext,DataAdr,WriteData,MemWrite); instructmem instructmem (Pcnext[7:2],Instr); datamem datamem (clk,MemWrite,DataAdr,WriteData,Readdata); endmodule
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// module datamem( input clk, we, input [31:0] a, wd, output [31:0] rd); reg [31:0] RAM[63:0]; assign rd = RAM[a[31:2]]; // word aligned always @(posedge clk) if (we) RAM[a[31:2]] <= wd; endmodule
Verilog: Mips
module mips( input clk,reset, input [31:0] InstrF,ReaddataM, output [31:0] PcnextFD, output [31:0] ALUoutM,WriteDataM, output MemWriteM); wire wire wire wire wire wire wire [5:0] opcodeD,functD; zeroM; RegWriteW,MemtoRegW; [3:0] ALUcontrolE; [1:0] ALUSrcE,RegDstE; [1:0] jumpD; PcSrcM;
endmodule
Verilog: Controller
module controller( input clk,reset, input [5:0] opcodeD,functD, CHAPTER 9: TESTING AND DEBUGGING input zeroM, output RegWriteW, output MemtoRegW, output MemWriteM, output [3:0] ALUcontrolE, output [1:0] ALUSrcE, output [1:0] RegDstE, output [1:0] jumpD, output PcSrcM); wire [2:0] ALUopD; wire [1:0] ALUSrcD,RegDstD; wire [3:0] ALUcontrolD; wire MemWriteD,RegWriteD,MemtoRegD; wire MemWriteE,RegWriteE,MemtoRegE; wire RegWriteM,MemtoRegM; wire BeqD,BeqE,BneD,BneE,BeqM,BneM;
maindec maindec (opcodeD,RegWriteD,MemtoRegD,MemWriteD,BeqD,BneD,ALUSrcD,RegDstD,jumpD,ALUopD); ALUdec ALUdecoder (functD,ALUopD,ALUcontrolD); assign PcSrcM = (BeqM & zeroM) | (BneM & ~zeroM); //pipelined registers flopr registerE (clk,reset, {RegWriteD,MemtoRegD,MemWriteD,BeqD,BneD,ALUcontrolD,ALUSrcD,RegDstD}, {RegWriteE,MemtoRegE,MemWriteE,BeqE,BneE,ALUcontrolE,ALUSrcE,RegDstE}); (clk,reset, {RegWriteE,MemtoRegE,MemWriteE,BeqE,BneE}, {RegWriteM,MemtoRegM,MemWriteM,BeqM,BneM});
flopr register
Testbench: Controller
module controller_TB; // Inputs reg clk; reg reset; reg zeroM; reg [5:0] opcodeD; reg [5:0] functD; // Outputs wire [3:0] ALUcontrolE; wire MemWriteM; wire PcSrcM; wire MemtoRegW; wire RegWriteW; wire [1:0] jumpD; wire [1:0] ALUSrcE; wire [1:0] RegDstE; // Instantiate the Unit Under Test (UUT) controller uut ( .clk(clk), .reset(reset), .zeroM(zeroM), .opcodeD(opcodeD), .functD(functD), .ALUcontrolE(ALUcontrolE), .MemWriteM(MemWriteM), .PcSrcM(PcSrcM), .MemtoRegW(MemtoRegW), .RegWriteW(RegWriteW), .jumpD(jumpD), .ALUSrcE(ALUSrcE), .RegDstE(RegDstE)); initial begin // Initialize Inputs clk = 0; reset = 0; zeroM = 0; opcodeD = 0; functD = 0; end initial #10 opcodeD = 6'b000100; initial #10 functD = 6'bXXXXXX; initial forever # 10 clk =! clk; endmodule
//ADD //SUB
//SLT //???
Verilog: Datapath module datapath( input clk,reset, input RegWriteW, input MemtoRegW, input [3:0] ALUcontrolE, input [1:0] ALUSrcE,RegDstE,jumpD, input PcSrcM, input [31:0] InstrF,ReaddataM, output zeroM, output [31:0]PcnextFD,ALUoutM,WriteDataM, output [5:0] opcodeD,functD);
wire [31:0] InstrD; wire [31:0] SrcAD,SrcAE,SrcBE; wire [31:0] WriteDataD,WriteDataE; wire [31:0] ALUoutE,ALUoutW; wire [4:0] rtE,rdE; wire [4:0] WriteRegE,WriteRegM,WriteRegW; wire [31:0] PcnextbarFD; wire [31:0] PcPlus4F,PcBranchM,PcBranchE; wire [31:0] PcPlus4D,PcPlus4E; wire [31:0] SignExD,SignImmE,SignImmshE; wire [31:0] ResultW,ReaddataW; wire zeroE; wire [31:0] MuxResultD,BranchF;
mux4 muxjumpD
//Decode stage assign opcodeD = InstrD[31:26]; assign functD = InstrD[5:0]; flopr r1D (clk,reset,PcPlus4F,PcPlus4D); flopr r2D (clk,reset,InstrF,InstrD[31:0]); Signext se (InstrD[15:0],SignExD);
//Execute stage flopr flopr flopr flopr flopr flopr r1E (clk, reset, SrcAD,SrcAE); r2E (clk, reset, WriteDataD, WriteDataE); r3E (clk, reset, InstrD[20:16],rtE); r4E (clk, reset, InstrD[15:11],rdE); r5E (clk, reset, SignExD,SignImmE); r6E (clk, reset, PcPlus4D,PcPlus4E);
// Memory stage flopr r1M (clk,reset,zeroE,zeroM); flopr r2M (clk,reset,ALUoutE,ALUoutM); flopr r3M (clk,reset,WriteDataE,WriteDataM); flopr r4M (clk,reset,WriteRegE,WriteRegM); flopr r5M (clk,reset,PcBranchE,PcBranchM);
//WriteBack stage flopr r1W (clk, reset, ALUoutM, ALUoutW); flopr r2W (clk, reset, ReaddataM,ReaddataW); flopr r3W (clk, reset, WriteRegM, WriteRegW); endmodule
Verilog: ALU
module alu (SrcA, SrcB, ALUcontrol, Result, zero); input [3:0] ALUcontrol; input [31:0] SrcA,SrcB; output zero; output reg [31:0] Result; always@(ALUcontrol,SrcA,SrcB) case(ALUcontrol) 4'b0000: Result <= SrcA&SrcB; //and 4'b0001: Result <= SrcA|SrcB; //or 4'b0010: Result <= SrcA+SrcB; //add 4'b1001: Result <= ~ (SrcA|SrcB); //nor 4'b1010: Result <= SrcA-SrcB; //sub 4'b1011: Result <= SrcA<SrcB ? 1:0; //slt 4'b0100: Result <= (SrcA<<SrcB); //sll 4'b0101: Result <= (SrcA>>SrcB); //srl default: Result <=0; //error endcase endmodule
Testbench: ALU
module alu_TB; // Inputs reg [31:0] SrcA; reg [31:0] SrcB; reg [3:0] ALUcontrol; // Outputs wire [31:0] Result; wire zero; // Instantiate the Unit Under Test (UUT) alu uut ( .SrcA(SrcA), .SrcB(SrcB), .ALUcontrol(ALUcontrol), .Result(Result), .zero(zero)); initial begin // Initialize Inputs SrcA = 10; SrcB = 5; ALUcontrol = 0; // Wait 100 ns for global reset to finish #100; end initial #0 ALUcontrol = 4'b0000; initial #10 ALUcontrol = 4'b0001; initial #20 ALUcontrol = 4'b0010; initial #30 ALUcontrol = 4'b1001; initial #40 ALUcontrol = 4'b1010; initial #50 ALUcontrol = 4'b1011; initial #60 ALUcontrol = 4'b0100; initial #70 ALUcontrol = 4'b0101; endmodule
// asynchronous reset always @ (posedge clk, posedge reset) if (reset) q <= 0; else q <= d; endmodule
Verilog: Adder
module adder( input [31:0] a,b, output [31:0] y); assign y = a + b; endmodule
Testbench: Adder
module adder_TB; // Inputs reg [31:0] a; reg [31:0] b; // Outputs wire [31:0] y; // Instantiate the Unit Under Test (UUT) adder uut ( .a(a), .b(b), .y(y)); initial begin // Initialize Inputs a = 50; b = 10; // Wait 50 ns for global reset to finish #50; end endmodule
Testbench: Top
module testbench_TB; // Inputs reg clk; reg reset; // Outputs wire [31:0] WriteData; wire [31:0] DataAdr; wire MemWrite; // Instantiate the Unit Under Test (UUT) top dut (clk,reset,WriteData,DataAdr,MemWrite); initial begin // Initialize Inputs reset <= 1; #20; reset <= 0; end // Generate clock to sequence test always begin clk <= 1; # 5; clk <= 0; # 5; end endmodule