OpenCores
URL https://opencores.org/ocsvn/erp/erp/trunk

Subversion Repositories erp

[/] [erp/] [web_uploads/] [ERPverilogcore.txt] - Rev 6

Compare with Previous | Blame | View Log

// Educational (8 Bit) RISC Processor
// Just like a barebone 8 Bit CPU
//
//
// Designed By:
// Asif Nawaz, Shahzad Jehangir & Ishaq Muhammad - 25 July 2004
// asifnawaz@ieee.org, shahzad_j_k@yahoo.com,ishaq_tehk@yahoo.com
//
// The design originally started out as a CPLD design but due to certain limitations the core was redesigned for FPGA

// Below given 8 Bit processor core is fully synthesizable and successfully tested on Xess Spartan 2 FPGA development board



/************************************/
                /*CPU Instructions*/

`define         Multiply                        4'b0000
`define         Move                            4'b0001
`define         Add                             4'b0010
`define         Sub                             4'b0011
`define         AND                             4'b0100
`define         NAND                            4'b0101
`define         OR                              4'b0110
`define         NOR                             4'b0111
`define         Load                            4'b1000
`define         Ror                             4'b1010
`define         Rol                             4'b1011
`define         Not                             4'b1100
`define         Jump                            4'b1111
`define         Shl                             4'b1101
`define         Shr                             4'b1110
/*************************************/





/************************************/
                /*Alu Instructions*/

`define         AluMultiply                     4'b0000
`define         AluAdd                  4'b0010
`define         AluSub                  4'b0011
`define         AluAND                  4'b0100
`define         AluNAND                 4'b0101
`define         AluOR                           4'b0110
`define         AluNOR                  4'b0111
`define         AluRor                  4'b1010
`define         AluRol                          4'b1011
`define         AluNot                  4'b1100
`define         AluShl                          4'b1101
`define         AluShr                          4'b1110
/*************************************/
                          
//Top level module proc which include the code for control unit and instantiate all other sub modules.

            //Externally generated inputs
module proc (Resetp, Holdp, Clockp,

                        //Input&output ports just for simulation purpose
                        led1h, led2h, Clock, PCount, pcoutput, Count, R0, R1, R2, R3, A, G);
 
//Port Decleration

        input Clockp;           //Externally generated clock signal
        input Resetp;           //Externally generated active high Reset signal
        input Holdp;            //Externally generated active low Hold signal


//The below given ports are only for simulation purpose

        output [6:0] led1h, led2h;      //input for the seven segment LED display
        output [7:0] PCount;            //8-bit output from the program counter
        output [15:0] pcoutput;         //16-bit instruction fetched from RAM
        output [1:0] Count;             //2-bit output from the machine cycle counter

        output [7:0] R0, R1, R2, R3, A, G;      //8-bit registers
        output Clock;                           //output clock signal for simulation    


//Variables of type reg declaration
                                                         
reg [7:0] BusWires;             //Used to store value for bus BusWires
reg [7:0] Exe;                  //Used to store the value to be displayed on 7 segment display
reg [7:0] Data;                 //Used to store the decoded data from 16-bit instruction
reg [7:0] Jmp;                  //Used to store the jump address
reg [1 : 0] Rx, Ry;             //Used to store the 2-bit value Rx & Ry, which act as input for 2to4 decoder
reg [3 : 0] F;                  //Used to store the 4-bit operand of the  16-bit instruction
reg [3:0] AddSub;               //Store 4-bit value which identify operation to be performed by ALU
reg [0:3] Rin, Rout;            //Store 4-bit value which identify one of the 4 registers to be activated for a given operation
reg  Done;                      //Store 1-bit value which identify the successful execution of an instruction
reg  Ain, Gin;                  //Store two 1-bit values and are used to save data in the A and G register
reg  Extern, Gout;              //Store two 1-bit values and are used in bus BusWires implementation
reg  Jset;                      //Store 1-bit value and is used for the jump instruction

//Variables of type wire declaration

wire [7:0] Sum;         //8-bit signal hold the output result from ALU
wire catch;             //1-bit enable signal for decoding of 16-bit instruction
wire JZ;                //1-bit signal used for jump instruction        
wire [1:0] Count;       //2-bit output signal from machine cycle counter
wire [3:0] I;           //4-bit signal which identify the instruction function
wire [0:3] Xreg, Y;     //4-bit signal for the activation of any register form the 4 registers

wire [7:0] R0, R1, R2, R3, A, G;        //These 8 bit signals used to carry data for these registers
wire [7:0] PCount;                      //8-bit output signal form the program counter
wire [1:8] FuncReg;                     //8-bit signal for control unit
wire [1:8] Func;                        //8-bit signal for control unit
wire [15:0] pcoutput;                   //16-bit signal from the RAM
wire [6:0] led1, led2, led1h, led2h;    //7-bit signal for Display unit


//1-bit signal used for various operations 
        wire  Clock, ClockS, Reset, Hold, Clockp, Resetp, Locked;

// Delay Locked Loop Buffer

        dll dll(Clockp, ClockS, Locked);

// Assign Clockp signal to Clock wire

        assign Clock = Locked ? ClockS : 1'b0 ;

// Input Buffers for Reset and Hold 
        
        IBUF rst(.I(Resetp), .O(Reset));
        IBUF hld(.I(Holdp), .O(Hold));

// Output Buffers for Display

        OBUF led10(.I(led1[0]), .O(led1h[0]));
        OBUF led11(.I(led1[1]), .O(led1h[1]));
        OBUF led12(.I(led1[2]), .O(led1h[2]));
        OBUF led13(.I(led1[3]), .O(led1h[3]));
        OBUF led14(.I(led1[4]), .O(led1h[4]));
        OBUF led15(.I(led1[5]), .O(led1h[5]));
        OBUF led16(.I(led1[6]), .O(led1h[6]));

        OBUF led20(.I(led2[0]), .O(led2h[0]));
        OBUF led21(.I(led2[1]), .O(led2h[1]));
        OBUF led22(.I(led2[2]), .O(led2h[2]));
        OBUF led23(.I(led2[3]), .O(led2h[3]));
        OBUF led24(.I(led2[4]), .O(led2h[4]));
        OBUF led25(.I(led2[5]), .O(led2h[5]));
        OBUF led26(.I(led2[6]), .O(led2h[6]));


// Clear Signal generation
        
        wire Clear = Reset | (~Locked) ; 

//Program Counter
         
        pcounter progcounter (Hold, Clear, Clock, Jmp, Jset, PCount, cmd, JZ);
         
//State Machine Counter
        
        upcount counter (Clear, Clock, Count, cmd, catch);

//Read RAM

        Ram ramreadload(Clock, cmd, PCount, Reset, pcoutput, catch );


//ALU
        alu alu(AddSub, A, BusWires, Sum);

//LED Display

        Display Dis1(Exe[3:0], Clock, Done, led1);
        Display Dis2(Exe[7:4], Clock, Done, led2);
                                   
//Control Unit
        //Instruction Decoding

        always @(catch or pcoutput)
                begin
                        F = pcoutput[15:12];
                        Rx = pcoutput[11:10];
                        Ry = pcoutput[9:8];
                        Data = pcoutput[7:0];
                        
                end

        assign Func = {F, Rx, Ry};
        wire FRin = catch & ~Count[1] & ~Count[0];
        regn functionreg (Func, FRin, Clock, FuncReg);

        assign I = FuncReg[1:4];
        dec2to4 decX (FuncReg[5:6], 1'b1, Xreg);
        dec2to4 decY (FuncReg[7:8], 1'b1, Y);
        
        //Instruction implementation
        
        always @(Count or I or Xreg or Y  or Data or BusWires or G or JZ)
        
        begin   
                        Extern = 1'b0;
                        Done = 1'b0;
                        Ain = 1'b0;
                        Gin = 1'b0;
                        Gout = 1'b0;
                        AddSub = 3'b000;
                        Rin = 4'b0;
                        Rout = 4'b0;

        begin


                        case (Count) 

                                2'b00: ;        //No operation in T0
                
                                2'b01:          //define signals in time step T1
                                
                                begin
                                        if (JZ == 1)                    // Check Jmp
                                                begin
                                                Jset = 1'b0;
                                                Jmp = 8'b00000000;
                                                end

                                        case (I)
                                                
                                                `Jump:                  //Jump
                                                begin
                                                        
                                                        Jset = 1'b1;
                                                        Jmp = Data;
                                                        Done = 1'b1;
                                                        Exe = Data;

                                                end

                                                `Load:                  //Load
                                                begin
                                                
                                                        Extern = 1;
                                                        Rin = Xreg;
                                                        Done = 1'b1;
                                                        Exe = Data;

                                                end

                                                `Move:                  //Move
                                                begin 
                        
                                                        Rout = Y;
                                                        Rin = Xreg;
                                                        Done = 1'b1;
                                                        Exe = BusWires;

                                                end

                                                `Add, `Sub, `Multiply, `And, `Or, `Not, `Nor, `Nand, `Ror, `Rol, `Shl, `Shr:    //Add, Sub, Logical, Shift
                                                begin
                                                        Rout = Xreg;
                                                        Ain = 1'b1;
                                                end
                                        
                                            default: ;

                                           endcase
                                        end
                                                
                                  2'b10:   //define signals in time step T2

                                        case (I)  

                                                `Not:                   //Not
                                                 begin
                                                        AddSub = `AluNot;
                                                        Gin = 1'b1;
                                                 end

                                                `Ror:                   //Rotate Right
                                                 begin
                                                        AddSub = `AluRor;
                                                        Gin = 1'b1;
                                                 end

                                                `Rol:                   //Rotate Left
                                                 begin
                                                        AddSub = `AluRol;
                                                        Gin = 1'b1;
                                                 end

                                                `Shl:                   //Shift Left
                                                 begin
                                                        AddSub = `AluShl;
                                                        Gin = 1'b1;
                                                 end

                                                `Shr:                   //Shift Right
                                                 begin
                                                        AddSub = `AluShl;
                                                        Gin = 1'b1;
                                                 end
                                                                                        
                                                `Add:                   //Add
                                                 begin
                                                        Rout = Y;
                                                        AddSub = `AluAdd;
                                                        Gin = 1'b1;
                                                 end

                                                 `Sub:                  //Sub
                                                 begin
                                                        Rout = Y;
                                                        AddSub = `AluSub;
                                                        Gin = 1'b1;
                                                 end

                                                 `Multiply:             //Multiplication
                                                 begin
                                                        Rout = Y;
                                                        AddSub = `AluMultiply;
                                                        Gin = 1'b1;
                                                 end

                                                 `And:                  //and
                                                 begin
                                                        Rout = Y;
                                                        AddSub = `AluAnd;
                                                        Gin = 1'b1;
                                                 end

                                                 `Nand:                 //nand
                                                 begin
                                                        Rout=Y;
                                                        AddSub = `AluNand;
                                                        Gin=1'b1;
                                                 end

                                                 `Or:                   //or
                                                 begin
                                                        Rout=Y;
                                                        AddSub = `AluOr;
                                                        Gin=1'b1;
                                                 end

                                                 `Nor:                  //nor
                                                 begin
                                                        Rout=Y;
                                                        AddSub = `AluNor;
                                                        Gin=1'b1;
                                                 end

                                                 default: ;


                                           endcase

                                        2'b11:          //define signals in time step T2
                                        begin
                                        
                                                case (I) 
        
                                                `Add, `Sub, `Multiply:                  // Add,Sub
                                                begin
                                                        Gout = 1'b1;
                                                        Rin = Xreg;
                                                        Done = 1'b1;
                                                        Exe = G;
                                                end

                                                `And, `Or, `Nand, `Nor, `Not:           //And, Or, Nand, Nor, Not
                                                begin
                                                        Gout = 1'b1;
                                                        Rin = Xreg;
                                                        Done = 1'b1;
                                                        Exe = G;
                                                end

                                                `Ror, `Rol, `Shl, `Shr:                 //Rotate right, Rotate left, Shift left, Shift right
                                                 begin
                                                        Gout = 1'b1;
                                                        Rin = Xreg;
                                                        Done = 1'b1;
                                                        Exe = G;
                                                end
                                                
                                                default: ;

                                                endcase

                                        end     
                                endcase
                end
        end             

//Register Creation

        regn reg_0 (BusWires[7:0], Rin[0], Clock, R0);
        regn reg_1 (BusWires[7:0], Rin[1], Clock, R1);
        regn reg_2 (BusWires[7:0], Rin[2], Clock, R2);
        regn reg_3 (BusWires[7:0], Rin[3], Clock, R3);

        regn reg_A (BusWires, Ain, Clock, A);

        regn reg_G (Sum, Gin, Clock, G);


//8 Bit Bus BusWires Implementation using Multiplexer
        
        wire [1:6] Sel = {Rout, Gout, Extern};

        always @(Sel or R0 or R1 or R2 or R3 or G or Data)
        begin
        if (Sel == 6'b100000)
                BusWires = R0;
        else if (Sel == 6'b010000)
                BusWires = R1;
        else if (Sel == 6'b001000)
                BusWires = R2;
        else if (Sel == 6'b000100)
                BusWires = R3;
        else if (Sel == 6'b000010)
                BusWires = G;
        else if (Sel == 6'b000001)
                BusWires = Data;
        else 
                BusWires = 8'bz;

        end

endmodule


//Machine Cycle(T) Counter

module upcount(Clear, Clock, Q, cmd, catch);
        
        input Clear, Clock, cmd, catch;
        output [1:0] Q;
        
        wire Clear, Clock, cmd, catch;  
        reg [1:0] Q;

        reg [3:0] RT1;

        
        always @(posedge Clock)
        begin
                        if (Clear == 1)
                        begin
                                Q <= 2'b00;
                                RT1 <= 4'b0000;
                        end

                        else if (cmd == 0)
                        begin
                                Q <= 2'b00;
                                RT1 <= 4'b0000;
                        end

                        else
                        begin
                                if (catch == 1'b1)
                                begin
                                        if (RT1 < 8'b0100)
                                        begin
                                                RT1 <= RT1 + 1;
                                                Q <= Q + 1 ;    
                                        end

                                        else if (RT1 == 8'b1111)
                                        begin
                                                RT1 <= 4'b0100;
                                        end

                                        else
                                                RT1 <= RT1 + 1;
                                end
                                else
                                begin
                                        Q <= 2'b0;
                                        RT1 <= 4'b0000;
                                end
                        end
        end


endmodule


//2-4 Decoder

module dec2to4(W, En, Y);
        input [1:0] W;
        input En;

        wire [1:0] W;
        wire En;

        output [0:3] Y;
        reg [0:3] Y;
        
        always @(W or En)
        begin
                if (En == 1)
                        case (W)
                                0: Y = 4'b1000;
                                1: Y = 4'b0100;
                                2: Y = 4'b0010;
                                3: Y = 4'b0001;
                        endcase
                else 
                        Y = 4'bz;
        end
endmodule


//8-Bit Register

module regn(R, Rin, Clock, Q);
        parameter n = 8;

        input [n-1:0] R;
        input Rin, Clock;

        wire [n-1:0] R;
        wire Rin, Clock;

        output [n-1:0] Q;
        reg [n-1:0] Q;

        always @(posedge Clock)
                if (Rin)
                        Q <= R;
        
endmodule

// 40K Block SRAM
//Read Ram 
module Ram(Clock, cmd, PcAddr, Reset, Inst, En);

        input Clock, cmd;
        input [7:0] PcAddr;
        input Reset;
        output [15:0] Inst;
        output En;

        wire Clock, cmd;
        wire [7:0] PcAddr;
        wire Reset;

        wire [15:0] Inst;       
        reg En, We, stop;

        reg [7:0]  WAddr, S;
        reg [15:0] WData;
        reg [15:0] Memory [0:10];
        reg enable, DoJob;      

        wire [7:0] Store;
        
        integer  count;

        always @(Reset)
        begin
                if (Reset == 1)
                        begin
                                Memory[0] =     16'h80FA;
                                Memory[1] =     16'h84F5;
                                Memory[2] =     16'h8822;
                                Memory[3] =     16'h2400;
                                Memory[4] =     16'h1D00;
                                Memory[5] =     16'h3B00;
                                Memory[6] =     16'h4400;
                                Memory[7] =     16'h5400;
                                Memory[8] =     16'h6400;
                                Memory[9] =     16'h7400;
                                Memory[10] =    16'hF409;
                                enable = 1;     
        
                        end
                else
                        begin 
                                enable = 0;     
                        end
        end

                
        always @(posedge Clock)
        begin   
        if (Reset == 1)
                begin
                        if (enable == 1)
                        begin   
                                if (count <= 10)
                                begin
        
                                WData = Memory[count];
                                WAddr <= WAddr + 1;
                                count <= count + 1;
                                DoJob = 1'b1;
                                end
        
                        end
                end

        else    
                begin

                DoJob = 1'b0;
                count <= 0;
                WAddr <= 8'b0;
                WData = 16'b0;
                En = cmd;
                end

        end
        
        always @(negedge Clock)
        begin
                if (DoJob == 1)
                begin
                        stop = 1'b1;
                        We = 1'b1;
                        S = WAddr;
                end
                else if (cmd == 1)
                begin
                        stop = 1'b1;
                        We = 1'b0;
                        S = PcAddr; 

                end
                else
                begin
                        stop = 1'b0;
                        We = 1'b0; 
                end
        end 

        RAMB4_S16 ram(.DO(Inst), .ADDR(S), .CLK(Clock), .DI(WData),
                                                .EN(stop), .RST(1'b0), .WE(We));

endmodule

//Program Counter

module pcounter(HButton, ClearCr, Clock, Jmp, Jset, Q1, cmd, Jz);
        
        input ClearCr, Clock;
        input HButton;
        input Jset;
        input [7:0] Jmp;

        wire ClearCr, Clock;
        wire HButton;
        wire Jset;
        wire [7:0] Jmp;

        output [7:0] Q1;
        output cmd;
        output Jz;

        reg [7:0] Q1;

        reg  work, cmd, Jz;


        always @(posedge Clock)
        begin
        
                if (ClearCr == 1)
                begin
                        Q1 <= 0;
                        work = 1'b0;
                end
                        
                else    if (HButton == 0)
                begin
                        if (work != 1'b1)
                        begin 
                        cmd = 1'b1;
                        work = 1'b1;
                                begin
                                if (Jset == 1)
                                        begin
                                        Q1 <= Jmp;
                                        Jz = 1'b1;
                                        end
                                else
                                        Q1 <= Q1 + 1 ;
                                end
                        end
                end
                else
                begin
                        cmd = 1'b0;
                        work = 1'b0;
                        Jz = 1'b0;
                end
        end     

endmodule



//Arthematic Logic Unit

module alu (Inst, A, BusWires, Result);

        input [3:0] Inst;
        input [7:0] A, BusWires;

        wire [3:0] Inst;
        wire [7:0] A, BusWires;

        output [7:0] Result;
        //output Cout, Zout, Sout;

        reg [7:0] Result;
        reg Zout, Sout, Cout;
                        
        always @(Inst  or A or BusWires or Result)

        begin
                Zout    = 1'b0;
                Sout    = 1'b0;
                Cout = 1'b0;
                Result = 8'b0;


        case (Inst)  // synopsis  parallel_case
        

                `AluMultiply:   
                                        begin 
                                        {Cout,Result}  = (A * BusWires);
                                        //Cout = Result[8]; 
                                        if (Result == 8'h00) 
                                        Zout = 1'b1; 
                                        if (Result[7] == 1) 
                                        Sout = 1'b1; 
                                        end

                `AluShl:                Result = {A[6:0], 1'b0};                                
                `AluShr:                Result = {1'b0, A[7:1]};

                `AluRol:                Result = {A[6:0], A[7]};
                `AluRor:                Result = {A[0], A[7:1]};

                `AluAdd:                begin 
                                        {Cout,Result}  = (A + BusWires);
                                        //Cout = Result[8];
                                        if (Result == 8'h00) 
                                        Zout = 1'b1; 
                                        if (Result[7] == 1) 
                                        Sout = 1'b1; 
                                        end

                `AluSub:                begin 
                                        {Cout,Result}  = (A - BusWires) ;
                                        //Cout = Result[8];
                                        if (Result == 8'h00) 
                                        Zout = 1'b1; 
                                        if (Result[7] == 1) 
                                        Sout = 1'b1; 
                                        end

                `AluAnd:                Result =   A & BusWires; 
                `AluNand:               Result =  ~(A & BusWires); 
                `AluOr:                 Result =   A | BusWires;
                `AluNor:                Result =  ~(A | BusWires);
                `AluNot:                Result =        ~(A);

                default:                begin
                                                Zout    = 1'b0;
                                                Sout    = 1'b0;
                                                Cout = 1'b0;
                                                Result = 8'b0;
                                        end

                
        endcase
        
        end
        
endmodule





/* Led: The 7 segment display */

module Display(buscontents, clk, Done, led);

        input [3:0] buscontents;
        input clk, Done;

        wire [3:0] buscontents;
        wire clk, Done;

        output [6:0] led;

        reg[6:0]        led;

        always @ (posedge clk)
                if (Done == 1)
                begin
                        case (buscontents)   // synopsis full_case parallel_case

                                4'b0000: led = 7'b1110111;
                                4'b0001: led = 7'b0010010;
                                4'b0010: led = 7'b1011101;
                                4'b0011: led = 7'b1011011;
                                4'b0100: led = 7'b0111010;
                                4'b0101: led = 7'b1101011;
                                4'b0110: led = 7'b1101111;
                                4'b0111: led = 7'b1010010;
                                4'b1000: led = 7'b1111111;
                                4'b1001: led = 7'b1111011;
                                4'b1010: led = 7'b1111110;
                                4'b1011: led = 7'b0101111;
                                4'b1100: led = 7'b0001101;
                                4'b1101: led = 7'b0011111;
                                4'b1110: led = 7'b1101101;
                                4'b1111: led = 7'b1101100;
                        endcase
                end

endmodule


//   Delay Lock Loops and Global clock buffers instantiation    
 
module dll(CLKIN, CLK1X, LOCKED2X);

input CLKIN;
output CLK1X, LOCKED2X;

wire CLK1X;

wire CLKIN_w, CLK1X_dll, LOCKED2X;


        IBUFG clkpad (.I(CLKIN), .O(CLKIN_w));

        CLKDLL dll2x (.CLKIN(CLKIN_w), .CLKFB(CLK1X), .RST(1'b0), 
                      .CLK0(CLK1X_dll), .CLK90(), .CLK180(), .CLK270(),
                      .CLK2X(), .CLKDV(), .LOCKED(LOCKED2X));

        BUFG   clk2xg (.I(CLK1X_dll),  .O(CLK1X));

        //OBUF   lckpad (.I(LOCKED2X), .O(LOCKED));

endmodule

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.