0% found this document useful (0 votes)
1K views

Verilog

The document describes the Verilog code and testbench for a mini-MIPS processor implementation including: 1) Top module instantiates the processor, instruction memory, and data memory modules. 2) Processor module contains controller and datapath modules. 3) Controller module decodes instructions and generates control signals. 4) Datapath module contains register file, ALU, and other logic to execute instructions. 5) Testbenches are provided to test the controller, main decoder, and ALU decoder modules.

Uploaded by

Syurga Fathonah
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1K views

Verilog

The document describes the Verilog code and testbench for a mini-MIPS processor implementation including: 1) Top module instantiates the processor, instruction memory, and data memory modules. 2) Processor module contains controller and datapath modules. 3) Controller module decodes instructions and generates control signals. 4) Datapath module contains register file, ALU, and other logic to execute instructions. 5) Testbenches are provided to test the controller, main decoder, and ALU decoder modules.

Uploaded by

Syurga Fathonah
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 22

THE MINI-MIPS VERILOG CODE AND THE TEST-BENCH Verilog: Top with Data Memory

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: Instruction Memory


module instructmem(input [5:0] a, output [31:0] rd); reg [31:0] RAM[63:0]; initial begin $readmemh("memfile.dat",RAM); end assign rd = RAM[a]; // word aligned 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;

controller CONTROLLER (clk,reset,opcodeD,functD,zeroM,RegWriteW,MemtoRegW, MemWriteM,ALUcontrolE,ALUSrcE,RegDstE,jumpD,PcSrcM); datapath DATAPATH (clk,reset,RegWriteW,MemtoRegW,ALUcontrolE,ALUSrcE, RegDstE,jumpD,PcSrcM,InstrF,ReaddataM,zeroM, PcnextFD,ALUoutM,WriteDataM,opcodeD,functD);

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

flopr registerW (clk,reset, {RegWriteM,MemtoRegM}, {RegWriteW,MemtoRegW}); endmodule

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

CHAPTER 10: RECOMENDATION

Verilog: Main Decoder


module maindec( input [5:0] opcode, output RegWrite, output MemtoReg, output MemWrite, output Beq,Bne, output [1:0]ALUSrc, output [1:0]RegDst, output [1:0]jump, output [2:0]ALUop); reg [13:0] controlunit; assign {RegWrite,RegDst,ALUSrc,Beq,Bne,MemWrite,MemtoReg,jump,ALUop} = controlunit; always @ (*) case (opcode) //Arithmetic Instruction 6'b000000: controlunit <= 14'b10100000000010; //R-type 6'b001000: controlunit <= 14'b10001000000000; //Addi //Data Transfer Instruction 6'b100011: controlunit <= 14'b10001000100000; //lw 6'b101011: controlunit <= 14'b00001001000000; //sw 6'b001111: controlunit <= 14'b10001000000000; //lui //Logical Instruction 6'b001100: controlunit <= 14'b10001000000100; //ANDi 6'b001101: controlunit <= 14'b10001000000101; //ORi //Conditional Branch Instruction 6'b000100: controlunit <= 14'b00000100000001; //BEQ 6'b000101: controlunit <= 14'b00000010000001; //BNE 6'b001010: controlunit <= 14'b10001000000001; //SLTi // Unconditional Jump Instruction 6'b000010: controlunit <= 14'b00000000001000; //J //6'b000000: controlunit <= 9'b100001100; //Jr 6'b000011: controlunit <= 14'b11000000010000; //Jal default: controlunit <= 14'bXXXXXXXXXXXXXX; //??? endcase

Testbench: Main Decoder


module maindec_TB; // Inputs reg [5:0] opcode; // Outputs wire [1:0] jump; wire [1:0] RegDst; wire [1:0] ALUSrc; wire [2:0] ALUop; wire RegWrite; wire Beq; wire Bne; wire MemWrite; wire MemtoReg; // Instantiate the Unit Under Test (UUT) maindec uut ( .opcode (opcode), .jump(jump), .RegDst(RegDst), .ALUSrc(ALUSrc), .ALUop(ALUop), .RegWrite(RegWrite), .Beq(Beq), .Bne(Bne), .MemWrite(MemWrite), .MemtoReg(MemtoReg)); initial begin // Initialize Inputs opcode = 0; end initial #10 opcode = 6'b000000; initial #20 opcode = 6'b001000; initial #30 opcode = 6'b100011; initial #40 opcode = 6'b101011; initial #50 opcode = 6'b001111; initial #60 opcode = 6'b001100; initial #70 opcode = 6'b001101; initial #80 opcode = 6'b000100; initial #90 opcode = 6'b000101; initial #100 opcode = 6'b001010; initial #110 opcode = 6'b000010; initial #120 opcode = 6'b000011; endmodule

Verilog: ALU Decoder


module ALUdec( input [5:0] functD, input [2:0] ALUopD, output reg [3:0] ALUcontrolD); always @ (*) case (ALUopD) 3'b000: ALUcontrolD <= 4'b0010; //Add 3'b001: ALUcontrolD<= 4'b1010; //Sub default: case (functD) //R-TYPE //Arithmetic Instruction 6'b100000: ALUcontrolD <= 4'b0010; 6'b100010: ALUcontrolD <= 4'b1010; //Logical Instruction 6'b100100: ALUcontrolD <= 4'b0000; 6'b100101: ALUcontrolD <= 4'b0001; 6'b100111: ALUcontrolD <= 4'b1001; 6'b000000: ALUcontrolD <= 4'b0100; 6'b000010: ALUcontrolD <= 4'b0101; //Conditional Branch Instruction 6'b101010: ALUcontrolD <= 4'b1011; default: ALUcontrolD <= 4'bXXXX; endcase endcase endmodule

//ADD //SUB

//AND //OR //NOR //SLL //SRL

//SLT //???

Testbench: ALU Decoder


module ALUdec_TB; // Inputs reg [5:0] funct; reg [2:0] ALUop; // Outputs wire [3:0] ALUcontrol; // Instantiate the Unit Under Test (UUT) ALUdec uut ( .funct(funct), .ALUop(ALUop), .ALUcontrol(ALUcontrol)); initial begin // Initialize Inputs funct = 0; ALUop = 0; end initial #0 ALUop = 3'b000; initial #0 funct=6'bxxxxxx; initial #10 ALUop = 3'b001; initial #10 funct=6'bxxxxxx; initial #20 ALUop = 3'b010; initial #20 funct = 6'b100000; initial #30 ALUop = 3'b010; initial #30 funct = 6'b100010; initial #40 ALUop = 3'b010; initial #40 funct = 6'b100100; initial #50 ALUop = 3'b010; initial #50 funct = 6'b100101; initial #60 ALUop = 3'b010; initial #60 funct = 6'b100111; initial #70 ALUop = 3'b010; initial #70 funct = 6'b000000; initial #80 ALUop = 3'b010; initial #80 funct = 6'b000010; initial #90 ALUop = 3'b010; initial #90 funct = 6'b101010; endmodule

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;

//Multiplexers mux2 muxPCSrcM (PcPlus4F,PcBranchM,PcSrcM,BranchF); mux4 muxjump (BranchF,{PcPlus4F[31:28],InstrD[25:0],2'b00},{PcPlus4F[31:28],InstrD[25:0],2'b00}, SrcAD,jumpD,PcnextbarFD); (ResultW,ResultW,ResultW,PcPlus4D,jumpD,MuxResultD);

mux4 muxjumpD

mux4 muxALUSrcE (WriteDataE,SignImmE,{InstrD[16:0],16'b00},32'b00,ALUSrcE,SrcBE); mux4 muxRegDstE (rtE,rdE,5'b11111,4'b0000,RegDstE,WriteRegE); mux2 muxMemtoRegW (ALUoutW,ReaddataW,MemtoRegW,ResultW);

//register file (operates in Decode and WriteBack) registerfile rf (clk,RegWriteW,InstrD[25:21],InstrD[20:16],WriteRegW,MuxResultD,SrcAD,WriteDataD);

//Fetch stage Logic flopr PcReg (clk,reset,PcnextbarFD,PcnextFD); adder PcAdd1 (PcnextFD,32'b100,PcPlus4F);

//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);

adder pcadd2 (SignImmshE,PcPlus4E,PcBranchE); Sl2 shift2E (SignImmE,SignImmshE); alu ALU (SrcAE,SrcBE,ALUcontrolE,ALUoutE,zeroE);

// 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

Verilog: Resettable Flip-Flop


module flopr #(parameter width = 8) (input clk,reset, input [width-1:0] d, output reg [width-1:0] q); //Resettable register

// asynchronous reset always @ (posedge clk, posedge reset) if (reset) q <= 0; else q <= d; endmodule

Testbench: Resettable Flip-Flop


module flopr_TB; // Inputs reg clk; reg reset; reg [7:0] d; // Outputs wire [7:0] q; // Instantiate the Unit Under Test (UUT) flopr uut ( .clk(clk), .reset(reset), .d(d), .q(q)); initial begin // Initialize Inputs clk = 0; reset = 0; d = 0; // Wait 100 ns for global reset to finish #100; // Add stimulus here clk = 1; d = 10; end

Verilog: Multiplexer 2 inputs


module mux2 #(parameter width = 8) (input [width-1:0] d0,d1, input s, output [width-1:0] y); assign y = s ? d1:d0; endmodule 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;

Testbench: Multiplexer 2 inputs


module mux2_TB; // Inputs reg [7:0] d0; reg [7:0] d1; reg s; // Outputs wire [7:0] y; // Instantiate the Unit Under Test (UUT) mux2 uut ( .d0(d0), .d1(d1), .s(s), .y(y)); initial begin // Initialize Inputs d0 = 1; d1 = 2; s = 1; end endmodule

Verilog: Multiplexer 4 inputs


module mux4 #(parameter width = 8) (input [width-1:0] d0,d1,d2,d3, input [1:0] s, output [width-1:0] y); assign y = s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0); endmodule

Testbench: Multiplexer 4 inputs


module mux4_TB; // Inputs reg [7:0] d0; reg [7:0] d1; reg [7:0] d2; reg [7:0] d3; reg [1:0] s; // Outputs wire [7:0] y; // Instantiate the Unit Under Test (UUT) mux4 uut ( .d0(d0), .d1(d1), .d2(d2), .d3(d3), .s(s), .y(y)); initial begin // Initialize Inputs d0 = 0; d1 = 1; d2 = 0; d3 = 4; s = 3; end endmodule

Verilog: Register File


module registerfile( input clk, input we3, input [4:0] ra1,ra2,wa3, input [31:0] wd3, output [31:0] rd1,rd2); reg [31:0] rf[31:0]; // three port register file // read two ports combinationally // write third port on rising edge of clock // register 0 hardwired to 0 always @ (posedge clk) if (we3) rf[wa3] <= wd3; assign rd1 = (ra1 != 0) ? rf[ra1] : 0; assign rd2 = (ra2 != 0) ? rf[ra2] : 0; endmodule

Verilog: Register File


module registerfile_TB; // Inputs reg clk; reg we3; reg [4:0] ra1; reg [4:0] ra2; reg [4:0] wa3; reg [31:0] wd3; // Outputs wire [31:0] rd1; wire [31:0] rd2; // Instantiate the Unit Under Test (UUT) registerfile uut ( .clk(clk), .we3(we3), .ra1(ra1), .ra2(ra2), .wa3(wa3), .wd3(wd3), .rd1(rd1), .rd2(rd2) ); initial begin // Initialize Inputs clk = 0; we3 = 1; ra1 = 0; ra2 = 17; wa3 = 17; wd3 = 32; // Wait 100 ns for global reset to finish #100; // Add stimulus here end initial forever #10 clk =!clk; 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

Verilog: Shift Left 16-bits


module Sl16( input [31:0] a, output [31:0] y); assign y = a << 16;
endmodule

Testbench: Shift Left 16-bits


module Sl16_TB; // Inputs reg [31:0] a; // Outputs wire [31:0] y; // Instantiate the Unit Under Test (UUT) Sl16 uut ( .a(a), .y(y)); initial begin // Initialize Inputs a = 20; // Wait 100 ns for global reset to finish #100; end endmodule

Verilog: Shift Left 2-bits


module Sl2( input [31:0] a, output [31:0] y); assign y = a << 2; endmodule

Testbench: Shift Left 2-bits


module Sl2_TB; // Inputs reg [31:0] a; // Outputs wire [31:0] y; // Instantiate the Unit Under Test (UUT) Sl2 uut ( .a(a), .y(y)); initial begin // Initialize Inputs a = 10; // Wait 100 ns for global reset to finish #100; end endmodule

Verilog: Sign Extended


module Signext( input [15:0] a, output [31:0] y); assign y = {{16{a[15]}},a}; endmodule

Testbench: Sign Extended


module Signext_TB; // Inputs reg [15:0] a; // Outputs wire [31:0] y; // Instantiate the Unit Under Test (UUT) Signext uut ( .a(a), .y(y)); initial begin // Initialize Inputs a = 0; // Wait 100 ns for global reset to finish #100; // Add stimulus here a = 10; 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

You might also like