Multi-Cycle Processor Implementation in Verilog?

  • Thread starter Thread starter pags920
  • Start date Start date
  • Tags Tags
    Processor
AI Thread Summary
The discussion centers on the challenges of implementing a multi-cycle processor in Verilog for the MIPS instruction set, specifically regarding the execution of an instruction stored in Memory[6]. The user is unable to execute this instruction and seeks assistance from others experienced in MIPS and Verilog. A key point raised is the lack of opcode checking for the last instruction, which is crucial for proper execution. It is suggested that this opcode check should occur between states 3 and 4 of the processor's operation. The thread highlights the importance of correctly managing instruction flow and state transitions in the design.
pags920
Messages
20
Reaction score
0
I am trying to design a multi-cycle processor in Verilog for the MIPS instruction set. However, I cannot get one of my instructions that I stored in memory to execute. This program is a continuation of a lab assignment that was given to my class.

The instruction that I am trying to execute is in Memory[6]. If anyone experienced in MIPS and Verilog can see where the problem is, that would be so helpful.

Code:
module cpu_tb;
wire[31:0] PC, IR, ALUOut, MDR, A, B, reg7;
reg clock;
CPU cpu1 (clock,PC, IR, ALUOut, MDR, A, B, reg7);// Instantiate CPU module  
initial 
begin
clock = 0;
repeat (300)
begin
#10 clock = ~clock; //alternate clock signal
end
end
initial #5000 $finish; //end simulation after 110 nano second
endmodule


module CPU (clock,PC, IR, ALUOut, MDR, A, B, reg7);
        parameter BNE = 6'b000001; //opcode for BNE
        parameter J = 6'b000010; //opcode for J
        parameter JAL = 6'b000011; //opcode for JAL
        parameter BEQ = 6'b000100; //opcode for BEQ
        parameter ADDI = 6'b001000; //opcode for ADDI 
        parameter SLTI = 6'b001010; //opcode for SLTI
        parameter ANDI = 6'b001100; //opcode for ANDI
        parameter ORI = 6'b001101; //opcode for ORI
        parameter SINC = 6'b011111; //opcode for SINC
        parameter LW = 6'b100011; //opcode for LW 
        parameter SB = 6'b101000; //opcode for SB
        parameter SW = 6'b101011; //opcode for SW 
        parameter LI = 6'b111111; //opcode for LI 

        input clock;  //the clock is an external input
        //Make these datapath registers available outside the module in order to do the testing
        output PC, IR, ALUOut, MDR, A, B;
        reg[31:0] PC, IR, ALUOut, MDR, A, B;
        output [31:0] reg7; //output reg 7 for testing
        
        // The architecturally visible registers and scratch registers for implementation
        reg [31:0] Regs[0:31], Memory [0:1023];
        assign reg7 = Regs[7]; //output reg 7
        
        reg [2:0] state; // processor state
        wire [5:0] opcode; //use to get opcode easily
        wire [31:0] SignExtend, PCOffset; //used to get sign extended offset field
        assign opcode = IR[31:26]; //opcode is upper 6 bits
                //sign extension of lower 16-bits of instruction
        assign SignExtend = {{16{IR[15]}},IR[15:0]};
        assign PCOffset = SignExtend << 2; //PC offset is shifted
        assign ZeroExtend = {{16{IR[1'b0]}}, IR[15:0]};
        assign BranchAddr = {{14{IR[15]}}, IR[15:0], 2'b0};
        assign JumpAddr = {{PC+{IR[31:28]}}, IR[25:0], 2'b0};
        //Load a test program and data into memory
        initial 
        begin
                Memory[2] = 32'h8c070078; //lw instruction
                Memory[3] = 32'hac0700f8; //sw instruction
                Memory[4] = 32'b111111_01000_00000_0000000000000001; //li instruction
                Memory[5] = 32'b000001_01000_01000_0000000000000001; //bne instruction
                Memory[6] = 32'b000000_01000_01000_00000_00000_010100; //add
                Memory[30] = 9;

        end
        // set the PC to 8 and start the control in state 1 to start fetch instructions from Memory[2] (byte 8)
        initial 
        begin 
                PC = 8; 
                state = 1; 
        end
        always @(posedge clock) begin
        //make R0 0 
        //short-cut way to make sure R0 is always 0
        Regs[0] = 0; 
        case (state) //action depends on the state
        1: begin     //first step: fetch the instruction, increment PC, go to next state        
                IR <= Memory[PC>>2]; //changed
                PC <= PC + 4;        //changed
                state = 2; //next state
                end
        2: begin     //second step: Instruction decode, register fetch, also compute branch address
                A = Regs[IR[25:21]];
                B = Regs[IR[20:16]];
                state= 3;
                ALUOut <= PC + PCOffset;         // compute PC-relative branch target
                end
        3: begin     //third step:  Load/Store execution, ALU execution, Branch completion
                state = 4; // default next state
                if ((opcode==LW) |(opcode==SW)) ALUOut <= A + SignExtend; //compute effective address
                else if (opcode==6'b0) case (IR[5:0]) //case for the various R-type instructions
                                        0: ALUOut = B << IR[10:6]; //sll operation
				                              	2: ALUOut = B >> IR[10:6]; //srl operation
				                               	8: PC = A; //jr operation
				                               	20: ALUOut = A + B; //add operation 
				                              	22: ALUOut = A - B; //sub operation 
			                              		24: ALUOut = A & B; //and operation
			                              		25: ALUOut = A | B; //or operation
			                               		27: ALUOut = ~(A | B); //nor operation
			                              		28: ALUOut = (A < B) ? 1:0; //slt operation
                                        default: ALUOut = A; //other R-type operations
                                        endcase
                else if (opcode==6'b111111) begin Regs[IR[25:21]]<= SignExtend; state = 1; end //ALU operation for LI instruction
                else if (opcode==6'b001000) begin Regs[IR[20:16]]<= SignExtend; ALUOut = A + SignExtend; state = 4; end //ALU operation for ADDI instruction
                else if (opcode==6'b001100) begin Regs[IR[20:16]]<= ZeroExtend; ALUOut = A & ZeroExtend; state = 4; end //ALU operation for ANDI instruction
                else if (opcode==6'b001101) begin Regs[IR[20:16]]<= ZeroExtend; ALUOut = A | ZeroExtend; state = 4; end //ALU operation for ORI instruction
                else if (opcode==6'b001010) begin Regs[IR[20:16]]<= SignExtend; ALUOut = (A < SignExtend) ? 1:0; state = 4; end //ALU operation for SLTI instruction
                else if (opcode==6'b000001) if(A!=B) begin PC = ALUOut; state = 1; end //ALU instruction for BNE instruction
                else if (opcode==6'b000100) if(A==B) begin PC = ALUOut; state = 1; end //ALU instruction for BEQ instruction
                else state = 1;
                else ; // other opcodes or exception for undefined instruction would go here
                end
        4: begin
                if (opcode==6'b0) begin //ALU Operation
                        Regs[IR[15:11]] <= ALUOut; // write the result
                        state = 1;
                end //R-type finishes
                else if (opcode == LW) begin // load instruction
                        MDR <= Memory[ALUOut>>2]; // read the memory
                        state = 5; // next state
                end
                else if (opcode == SW) begin
                        Memory[ALUOut>>2] <= B; // write the memory
                        state = 1; // return to state 1
                end //store finishes
                else if (opcode == LI) begin //load immediate
                        Regs[IR[25:21]] <= ALUOut; //write to IR
                        state = 1; //return to state 1
                end
                else if (opcode == ADDI) begin //add immediate
                        Regs[IR[20:16]] <= ALUOut;  //write to IR
                        state = 1; //return to state 1
                end
            		else if (opcode == ANDI) begin //and immediate
	                  		Regs[IR[20:16]] <= ALUOut; //write to IR
                  			state = 1; //return to state 1
	             	end
                else if (opcode == BEQ) begin //branch if equal
                        if (ALUOut != 0)
                        state = 1; //return to state 1
                        else
                        PC <= IR[15:0] + SignExtend; //write to program counter, branch address
                        state = 1; //return to state 1
                end
                else if (opcode == ORI) begin //or immediate
                        Regs[IR[20:16]] <= A | ZeroExtend; //write to IR
                        state = 1; //return to state 1
                end
                else if (opcode == SLTI) begin //set if less than immediate
                        Regs[IR[20:16]] <= ALUOut; //write to IR
                        state = 1; //return to state 1
                end
                else if (opcode == SB) begin //store byte
                        Memory[A + {SignExtend[7:0]}] <= B; //write to memory
                        state = 1; //reurn to state 1
                end
                else if (opcode == J) begin //jump
                        PC <= JumpAddr; //write to program counter, jump address
                        state = 1; //return to state 1
                end
                else if (opcode == JAL) begin //jump and link
                        IR[31] <= PC + 8; //write to the last bit in IR
                        PC <= JumpAddr; // write to program counter, jump address
                        state = 1;
                end
                else if (opcode == SINC) begin //sinc
                        MDR <= Memory[ALUOut>>2]; //write to memory
                        Regs[IR[20:16]] <= A + SignExtend; //write to IR
                        state = 5; //proceed to state 5
                end                        
                else if (opcode == BNE) begin //branch if not equal
                        if (ALUOut == 0)
                        state = 1; //return to state 1
                        else
                        PC <= IR[15:0] + SignExtend; //write to program counter, branch address
                        state = 1; //return to state 1
                end
        end
        5: begin     //LW is the only instruction still in execution
                Regs[IR[20:16]] = MDR;                 // write the MDR to the register
                state = 1;
                end //complete a LW instruction
        endcase
           end
endmodule
 
Engineering news on Phys.org
Okay, I was told that I am not checking for the opcode in my last instruction anywhere in program. However, it wasn't explicitly clear as to where I would check it at. I know that it has to be checked somewhere between states 3 and 4.
 
Thread 'I need a concave mirror with a focal length length of 150 feet'
I need to cut down a 3 year old dead tree from top down so tree causes no damage with small pieces falling. I need a mirror with a focal length of 150 ft. 12" diameter to 36" diameter will work good but I can't think of any easy way to build it. Nothing like this for sale on Ebay. I have a 30" Fresnel lens that I use to burn stumps it works great. Tree service wants $2000.
Hi all, i have some questions about the tesla turbine: is a tesla turbine more efficient than a steam engine or a stirling engine ? about the discs of the tesla turbine warping because of the high speed rotations; does running the engine on a lower speed solve that or will the discs warp anyway after time ? what is the difference in efficiency between the tesla turbine running at high speed and running it at a lower speed ( as fast as possible but low enough to not warp de discs) and: i...

Similar threads

Back
Top