Multi-Cycle Processor Implementation in Verilog?

  • Thread starter pags920
  • Start date
  • Tags
    Processor
In summary: PC to 30 and start the control in state 2 to start fetch instructions from Memory[3] (byte 30) initial ... // set the PC to 31 and start the control in state 3 to start fetch instructions from Memory[4] (byte 31) initial ... // set the PC to 0 and terminate the control In summary, the problem is that the instruction that I am trying to execute is not in memory[6] as expected.
  • #1
pags920
21
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
  • #2
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.
 

Related to Multi-Cycle Processor Implementation in Verilog?

What is a multi-cycle processor?

A multi-cycle processor is a type of computer processor that executes instructions over multiple clock cycles. This allows for more complex and longer instructions to be processed, increasing the overall performance of the processor.

Why use Verilog for multi-cycle processor implementation?

Verilog is a hardware description language that is commonly used for designing and testing electronic systems, such as processors. It is specifically designed for modeling and simulating digital circuits, making it a suitable choice for implementing multi-cycle processors.

What are the benefits of using a multi-cycle processor?

Multi-cycle processors offer several advantages, including increased processing speed, improved efficiency, and the ability to handle more complex instructions. They are also more flexible and can support a wider range of applications.

What are the key components of a multi-cycle processor implemented in Verilog?

The key components of a multi-cycle processor implemented in Verilog include an instruction decoder, control unit, arithmetic and logic unit (ALU), registers, and data and instruction memory. These components work together to process instructions and perform calculations.

What are the steps involved in implementing a multi-cycle processor in Verilog?

The steps for implementing a multi-cycle processor in Verilog include designing the processor architecture, writing the Verilog code for each component, simulating and testing the design, and finally, synthesizing the design for implementation on hardware. Debugging and optimization may also be necessary during the implementation process.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
7
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
1K
  • General Engineering
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
1K
  • Atomic and Condensed Matter
Replies
3
Views
913
  • Engineering and Comp Sci Homework Help
Replies
1
Views
2K
  • Electrical Engineering
Replies
6
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
3K
  • Programming and Computer Science
Replies
4
Views
3K
Back
Top