Results 1 to 5 of 5

Thread: Complete Phase 1 32b Pipeline Processor

  1. #1
    Join Date
    Apr 2007
    Location
    Texas
    Posts
    1,668
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default Complete Phase 1 32b Pipeline Processor

    SCAR Code:
    `timescale 1ns / 1ps
    //////////////////////////////////////////////////////////////////////////////////
    // Company:  World Domination
    // Engineer: Greg Hendrickson
    //
    // Create Date:    23:09:34 11/03/2007
    // Design Name:     Pipelined CPU Stage 1
    // Module Name:    CPU
    // Project Name:    Comp Arch Final Project
    // Target Devices: Desktop
    // Tool versions:
    // Description:
    //
    // Dependencies:
    //
    // Revision:
    // Revision 0.01 - File Created
    // Revision 0.02 - Syntax errors fixed
    // Revision 0.03 - Logical Errors Fixed
    // Revision 0.04 - Rest of code understood
    // Revision 0.05 - Added in and understood forwarding the a and b
    // Revision 0.06 - Could not find any errors in the forwarding code
    // Revision 0.07 - Added in the stalls
    // Revision 0.08 - Fixed minor "no-op" syntax error
    // Revision 0.09 - Found and fixed instruction forwarding error.  Cant do all at end (stall fails)
    // Additional Comments:
    //
    //////////////////////////////////////////////////////////////////////////////////
    module CPU (clock,owbypassBfromMEM,owbypassAfromMEM,,ostall,obypassAfromMEM,obypassBfromMEM,obypassAfromALUinWB,obypassBfromALUinWB,obypassAfromLWinWB,obypassBfromLWinWB);
        // Instruction opcodes
        parameter LW = 6'b100011, SW = 6'b101011, BEQ=6'b000100, noop = 32'b00000_000000, ALUop=6'b0;
        parameter   A_ADD = 6'
    'b011111,//31: add operation
                        A_SUB = 6'
    b010000,//16 subtract
                        A_AND = 6'b001000,//8 and
                        A_NADD = 6'
    b000111,//7 nand
                        A_OR = 6'b000100,//4 or
                        A_NOR = 6'
    b000011,//3 nor
                        A_SEQZ = 6'b000010,//2 seqz  set equals
                        A_SLT = 6'
    b000001;//1 slt operation
                       
                   
        input clock;
        output owbypassBfromMEM,owbypassAfromMEM,ostall,obypassAfromMEM,obypassBfromMEM,obypassAfromALUinWB,obypassBfromALUinWB,obypassAfromLWinWB,obypassBfromLWinWB;
        //output  [31:0]oRegs;
        reg[31:0] PC, Regs[0:31], IMemory[0:23], DMemory[0:23], // separate memories (they were 1023, i made them, 23)
        IFIDIR, IDEXA, IDEXB, IDEXIR, EXMEMIR, EXMEMB,GREGREGIR, // pipeline registers
        EXMEMALUOut, MEMWBValue, MEMWBIR; // pipeline registers
        wire [4:0] IDEXrs, IDEXrt,EXMEMBrs,GREGrd,EXMEMBrt,IFIDrt,EXMEMrs,EXMEMrt ,IFIDrs,EXMEMrd, MEMWBrd, MEMWBrt; // Access register fields
        wire [5:0] EXMEMop, MEMWBop, IDEXop; // Access opcodes
        wire [31:0] Ain, Bin; // the ALU inputs
        wire [31:0] viewRegs [0:31];
        // declare the bypass signals
        wire bypassAfromMEM, bypassAfromALUinWB,bypassBfromMEM, bypassBfromALUinWB,
        bypassAfromLWinWB, bypassBfromLWinWB,stall;
       
        // These assignment define fields from the pipeline registers
        assign IFIDrs = IFIDIR[25:21]; // rs field
        assign IFIDrt = IFIDIR[20:16];
        assign EXMEMrs= EXMEMIR[25:21];
        assign EXMEMrt= EXMEMIR[20:16];
        assign EXMEMBrs= EXMEMB[25:21];
        assign EXMEMBrt= EXMEMB[20:16];
        assign GREGrd = GREGREGIR[15:11];
        assign IDEXrs = IDEXIR[25:21]; // rs field
        assign IDEXrt = IDEXIR[20:16]; // rt field //changed, was 15,11 now 20-16
        assign EXMEMrd = EXMEMIR[15:11]; // rd field
        assign MEMWBrd = MEMWBIR[15:11]; //rd field [changed from 20;16] TO  15;11 //double checked, yes
        assign MEMWBrt = MEMWBIR[25:20]; //rt field--used for loads//the 21 was a 20 grr
        assign EXMEMop = EXMEMIR[31:26]; // the opocde
        assign MEMWBop = MEMWBIR[31:26]; // the opcode
        assign IDEXop = IDEXIR[31:26] ; // the opcode
        // Inputs to the ALU come directly from the ID/EX pipeline registers
       
        //rot in hell  (the code, not you :D )
        //assign Ain = IDEXA;
        //assign Bin = IDEXB;
         
        // The bypass to input A from the MEM stage for an ALU operation
        assign wbypassAfromMEM = (IDEXrs == EXMEMrd) & (IDEXrs!=0) & (EXMEMop==ALUop); // yes, bypass
        // The bypass to input Bfrom the MEM stage for an ALU operation
        assign wbypassBfromMEM = (IDEXrt== EXMEMrd)&(IDEXrt!=0) & (EXMEMop==ALUop); // yes, bypass
        // The bypass to input A from the WB stage for an ALU operation  
       
        // The bypass to input A from the MEM stage for an ALU operation
        assign bypassAfromMEM = (IDEXrs == GREGrd) & (IDEXrs!=0) & (EXMEMop==ALUop); // yes, bypass
        // The bypass to input Bfrom the MEM stage for an ALU operation
        assign bypassBfromMEM = (IDEXrt== GREGrd)&(IDEXrt!=0) & (EXMEMop==ALUop); // yes, bypass
        // The bypass to input A from the WB stage for an ALU operation
        assign bypassAfromALUinWB =0;//( IDEXrs == MEMWBrd) & (IDEXrs!=0) & (MEMWBop==ALUop);
        // The bypass to input B from the WB stage for an ALU operation
        assign bypassBfromALUinWB =0;// (IDEXrt==MEMWBrd) & (IDEXrt!=0) & (MEMWBop==ALUop);
        // The bypass to input A from the WB stage for an LW operation
        assign bypassAfromLWinWB =( IDEXrs ==MEMWBIR[20:16]) & (IDEXrs!=0) & (MEMWBop==LW);
        // The bypass to input B from the WB stage for an LW operation
        assign bypassBfromLWinWB = (IDEXrt==MEMWBIR[20:16]) & (IDEXrt!=0) & (MEMWBop==LW);
        // The A input to the ALU is bypassed from MEM if there is a bypass there,
        // Otherwise from WB if there is a bypass there, and otherwise comes from the IDEX register
        assign Ain = bypassAfromMEM? MEMWBrt :
        (bypassAfromALUinWB || bypassAfromLWinWB)? MEMWBValue :
        wbypassAfromMEM? EXMEMALUOut:IDEXA;
        // The B input to the ALU is bypassed from MEM if there is a bypass there,
        // Otherwise from WB if there is a bypass there, and otherwise comes from the IDEX register
        assign Bin = bypassBfromMEM? MEMWBrt :
        (bypassBfromALUinWB || bypassBfromLWinWB)? MEMWBValue:
        wbypassBfromMEM? EXMEMALUOut:IDEXB;
       
       
        //tie them to somthing i can freaking see
        assign obypassAfromMEM=bypassAfromMEM;
        assign obypassBfromMEM=bypassBfromMEM;
        assign obypassAfromALUinWB=bypassAfromALUinWB;
        assign obypassBfromALUinWB=bypassBfromALUinWB;
        assign obypassAfromLWinWB=bypassAfromLWinWB;
        assign obypassBfromLWinWB=bypassBfromLWinWB;
        assign owbypassBfromMEM=wbypassBfromMEM;
        assign owbypassAfromMEM=wbypassAfromMEM;
       
       
        //assign oRegs=Regs[31];
       
       
        // The signal for detecting a stall based on the use of a result from LW
        assign stall = (((MEMWBIR[31:26]==LW)||(MEMWBIR[31:26]==LW)) && // source instruction is a load
        ((((IDEXop==LW)||(IDEXop==SW)) && (IDEXrs==EXMEMrt)) || // stall for address calc
        //(((IDEXop==LW)||(IDEXop==SW)) && ((IDEXrs==GREGrd) ||(IDEXrt==GREGrd)))| // stall for address calc
       
        ((IDEXop==ALUop) && ((IDEXrs==EXMEMrt)||(IDEXrt==EXMEMrt))))); // ALU use
       
        assign ostall=stall;
        reg [5:0] i; //used to initialize registers
        initial begin
            PC = 0;
            IFIDIR=noop; IDEXIR=noop; EXMEMIR=noop; MEMWBIR=noop; // put no-ops in pipeline registers
            for (i=0;i<=31;i=i+1) Regs[i] = i+0; //initialize registers--just so they aren?t cares
            //Initiialize us up some instructumonenteseses
            IMemory[0] <= 32'b00000_000000;//No op
            IMemory[1] <= {ALUop,5'
    d2,5'd4,5'd31,5'b0,A_ADD};//ALU op, reg 2 , and reg 4, put them in reg 31, no shifting, addthems
            IMemory[2] <= {ALUop,5'
    d3,5'd5,5'd30,5'b0,A_ADD};//ALU op, reg 3 , and reg 5, put them in reg 30, no shifting, addthems
            IMemory[3] <= {ALUop,5'
    d9,5'd12,5'd29,5'b0,A_ADD};//ALU op, reg 9 , and reg 12, put them in reg 29, no shifting, addthems
            IMemory[4] <= {ALUop,5'
    d31,5'd2,5'd28,5'b0,A_ADD};//ALU op, reg 31 , and reg 2, put them in reg 28, no shifting, addthems
            IMemory[5] <= {ALUop,5'
    d28,5'd2,5'd27,5'b0,A_ADD};//ALU op, reg 28 , and reg 2, put them in reg 27, no shifting, addthems
            IMemory[6] <= {ALUop,5'
    d27,5'd27,5'd26,5'b0,A_ADD};//ALU op, reg 27 , and reg 27, put them in reg 26, no shifting, addthems
            IMemory[7] <= {SW, 5'
    d0, 5'd31, 16'd8}; //Storing what in r31 to memory 8(slot 2)
            //  about to try to test the load word stall
            IMemory[8]<= {LW, 5'd0, 5'd25, 16'd12};//loading up from meme (slot 3) into reg 25
            IMemory[9]<= {LW, 5'd0, 5'd24, 16'd8};//loading up from meme (what we just stored) (slot 2) into reg 24
            IMemory[10] <= {ALUop,5'd24,5'd2,5'd23,5'b0,A_ADD};//ALU op, reg 24(stall) , and reg 2, put them in reg 23, no shifting, addthems
            //Demoing a little bit of fancy code
            IMemory[11] <= {ALUop,5'd5,5'd5,5'd5,5'b0,A_ADD};//ALU op, reg 2 , and reg 2, put them in reg 22, no shifting, addthems
            IMemory[12] <= {ALUop,5'd5,5'd5,5'd5,5'b0,A_ADD};//ALU op, reg 22 , and reg 2, put them in reg 22, no shifting, addthems
            IMemory[13] <= {ALUop,5'd5,5'd5,5'd5,5'b0,A_ADD};//ALU op, reg 22 , and reg 2, put them in reg 22, no shifting, addthems
           
           
            for (i=14;i<=31;i=i+1) IMemory[i] = noop; //initialize registers--just so they aren?t cares
            for (i=0;i<=31;i=i+1) DMemory[i] = i+100;
            // Add stimulus here
        end
        always @ (posedge clock) begin
            // Remember that ALL these actions happen every pipestage and with the use of <= they happen in parallel!
            // first instruction in the pipeline is being fetched
           
            if (~stall) begin // the first three pipeline stages stall if there is a load hazard
                    IFIDIR <= IMemory[PC>>2];
                    PC <= PC + 4;
                   
                   
                //end // Fetch & increment PC
               
                // second instruction in pipeline is fetching registers
                    IDEXA <= Regs[IFIDIR[25:21]]; IDEXB <= Regs[IFIDIR[20:16]]; // get two registers
                   
                // third instruction is doing address calculation or ALU operation
                if ((IDEXop==LW) |(IDEXop==SW)) // address calculation
                    EXMEMALUOut <= IDEXA +{{16{IDEXIR[15]}}, IDEXIR[15:0]};
                else if (IDEXop==ALUop) case (IDEXIR[5:0]) //case for the various R-type instructions
                    31: EXMEMALUOut <= Ain + Bin; //add operation
                    16: EXMEMALUOut <= Ain - Bin; //subtract operation
                    8:  EXMEMALUOut <= Ain & Bin; //and operation
                    7:  EXMEMALUOut <= ~(Ain & Bin); //nadd operation
                    4:  EXMEMALUOut <= Ain | Bin; //or operation
                    3:  EXMEMALUOut <= ~(Ain | Bin); //nor operation
                    2:  EXMEMALUOut <= ((Ain - Bin)==0)?1:0; //seqz operation
                    1:  EXMEMALUOut <= Ain < Bin ? 1:0; //slt operation
                    5:  EXMEMALUOut <= Ain * Bin;
                    default: ; //other R-type operations: subtract, SLT, etc.
                endcase
               
                IDEXIR <= IFIDIR; EXMEMIR <= IDEXIR; EXMEMB <= IDEXB;// passing along instructions
           
            end
            else EXMEMIR <= noop; //Freeze first three stages of pipeline; inject a nop into the EX output
               
            //Mem stage of pipeline
            if (EXMEMop==ALUop)
                MEMWBValue <= EXMEMALUOut; //pass along ALU result
            else if (EXMEMop == LW)
                MEMWBValue <= DMemory[EXMEMALUOut>>2];
            else if (EXMEMop == SW)
                DMemory[EXMEMALUOut>>2] <=EXMEMB; //store [from top, it is 15:0)stage3
           
            // the WB stage
            if ((MEMWBop==ALUop) & (MEMWBrd != 0)) // update registers if ALU operation and destination not 0
                Regs[MEMWBrd] <= MEMWBValue; // ALU operation
            else if ((MEMWBop == LW)& (MEMWBrt != 0)) // Update registers if load and destination not 0//was emememop
                Regs[MEMWBIR[20:16]]<=MEMWBValue;
                //Regs[MEMWBrt] <= MEMWBValue;
           
           
            MEMWBIR <= EXMEMIR; GREGREGIR<=MEMWBIR;//pass along
            end
           
           
    endmodule
    and the test bench

    SCAR Code:
    `timescale 1ns / 1ps

    module CPUBench_v;

        // Inputs
        reg clock=1'b0;
       wire obypassAfromMEM=1'
    b0,obypassBfromMEM=1'b0,obypassAfromALUinWB=1'b0,obypassBfromALUinWB=1'b0
        ,obypassAfromLWinWB=1'
    b0,obypassBfromLWinWB=1'b0,ostall=1'b0;

        // Instantiate the Unit Under Test (UUT)
        CPU uut (
            .clock(clock),
            .obypassAfromMEM(obypassAfromMEM),
            .obypassBfromMEM(obypassBfromMEM),
            .obypassAfromALUinWB(obypassAfromALUinWB),
            .obypassBfromALUinWB(obypassBfromALUinWB),
            .obypassAfromLWinWB(obypassAfromLWinWB),
            .obypassBfromLWinWB(obypassBfromLWinWB),
            .owbypassBfromMEM(owbypassBfromMEM),
            .owbypassAfromMEM(owbypassAfromMEM),
            .ostall(ostall)
        );
       
        always
            #10 clock = ~clock;
             
    endmodule

    here is a wave out from my processor. I personaly write some assembly code, and then personally convert into a 32 bit binarry string. I load that into memory and then tick the clock along.



    and a link to the pdf report, which has everything about this.

    The Report
    [IMG]http://farm3.static.flickr.com/2120/2052732965_348f3629d0_o.jpg[/IMG]

  2. #2
    Join Date
    Dec 2006
    Location
    .̿̂̔͋͗̎̆ͥ̍̒ͤ͂̾̌̀̅
    Posts
    3,012
    Mentioned
    1 Post(s)
    Quoted
    3 Post(s)

    Default

    O_o

    Seems a bit complicated

  3. #3
    Join Date
    Dec 2006
    Location
    Banville
    Posts
    3,914
    Mentioned
    12 Post(s)
    Quoted
    98 Post(s)

    Default

    Seems like I need to buy a PIC processor and get up-to-date :P
    The jealous temper of mankind, ever more disposed to censure than
    to praise the work of others, has constantly made the pursuit of new
    methods and systems no less perilous than the search after unknown
    lands and seas.

  4. #4
    Join Date
    Apr 2007
    Location
    Texas
    Posts
    1,668
    Mentioned
    0 Post(s)
    Quoted
    0 Post(s)

    Default

    Quote Originally Posted by R0b0t1 View Post
    Seems like I need to buy a PIC processor and get up-to-date :P
    actually, whats cool about this, is that there is no hardware invvolved.

    i dont evne thin k it would work right unless you had a very special chip to put it on.


    all of this is nothing but code, and nothing but a simulation of it.


    (and its all free, all you need is a computer)
    [IMG]http://farm3.static.flickr.com/2120/2052732965_348f3629d0_o.jpg[/IMG]

  5. #5
    Join Date
    Dec 2006
    Location
    Banville
    Posts
    3,914
    Mentioned
    12 Post(s)
    Quoted
    98 Post(s)

    Default

    Awesome!

    Random quote: "Failure is not an option -- it comes bundled with windows."
    The jealous temper of mankind, ever more disposed to censure than
    to praise the work of others, has constantly made the pursuit of new
    methods and systems no less perilous than the search after unknown
    lands and seas.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. HSL Color Processor
    By Cazax in forum Research & Development Lounge
    Replies: 2
    Last Post: 02-02-2009, 04:36 AM
  2. Verilog 32 Bit Processor
    By LordGregGreg in forum General
    Replies: 13
    Last Post: 11-12-2007, 01:47 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •