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

Subversion Repositories qrisc32

[/] [qrisc32/] [trunk/] [qrisc32_ID.sv] - Rev 2

Compare with Previous | Blame | View Log

//////////////////////////////////////////////////////////////////////////////////////////////
//    Project Qrisc32 is risc cpu implementation, purpose is studying
//    Digital System Design course at Kyoung Hee University during my PhD earning
//    Copyright (C) 2010  Vinogradov Viacheslav
// 
//    This library is free software; you can redistribute it and/or
//   modify it under the terms of the GNU Lesser General Public
//    License as published by the Free Software Foundation; either
//    version 2.1 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public
//    License along with this library; if not, write to the Free Software
//    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
//
//////////////////////////////////////////////////////////////////////////////////////////////


import risc_pack::*;

module qrisc32_ID(
                input                           clk,reset,
                input [31:0]            instruction,
                input [31:0]            pc,

                input                           pipe_stall,//feed back from MEM stage
                input pipe_struct       pipe_wb_mem,//for memory read 
                input pipe_struct       pipe_wb_ex,//for R2 register and ALU operations only
        
                output pipe_struct      pipe_id_out,
                input                           verbose
        );
        
        import risc_pack::*;

        bit[31:0]                       rf[31:0];//32 regs width is 32
        bit[31:0]                       offset_w;
        pipe_struct                     pipe_id_out_w;  
        bit[31:0]                       nop_counter;
        bit[31:0]                       jmp_counter;
        bit[31:0]                       alu_counter;
        bit[31:0]                       oth_counter;
        
        //comb part
        always_comb
        begin
                pipe_id_out_w.dst_r     = instruction[04:00];
                pipe_id_out_w.src_r1    = instruction[09:05];
                pipe_id_out_w.src_r2    = instruction[14:10];
                pipe_id_out_w.incr_r2   = 0;
                pipe_id_out_w.incr_r2_enable    = 1;
                        
                        
                pipe_id_out_w.read_mem  = 0;
                pipe_id_out_w.write_mem = 0;
                pipe_id_out_w.write_reg = 0;
                        
                pipe_id_out_w.mul_op    = 0;
                pipe_id_out_w.add_op    = 0;
                pipe_id_out_w.or_op             = 0;
                pipe_id_out_w.and_op    = 0;
                pipe_id_out_w.xor_op    = 0;
                pipe_id_out_w.shl_op    = 0;
                pipe_id_out_w.shr_op    = 0;
                pipe_id_out_w.cmp_op    = 0;
                pipe_id_out_w.ldrf_op   = 0;
        
                        
                pipe_id_out_w.jmpunc    = 0;
                pipe_id_out_w.jmpz              = 0;
                pipe_id_out_w.jmpnz             = 0;
                pipe_id_out_w.jmpc              = 0;
                pipe_id_out_w.jmpnc             = 0;    
                        
                pipe_id_out_w.val_r1    =       (pipe_wb_mem.write_reg && pipe_wb_mem.dst_r==pipe_id_out_w.src_r1)?
                                                                        pipe_wb_mem.val_dst://forward from memory read
                                                                        //(pipe_wb_mem.incr_r2_enable && pipe_wb_mem.src_r2==pipe_id_out_w.src_r1)?
                                                                        //pipe_wb_mem.val_r2://forward from mem stage R2 register
                                                                        (pipe_wb_ex.write_reg && pipe_wb_ex.dst_r==pipe_id_out_w.src_r1)?
                                                                        pipe_wb_ex.val_dst://forward from execution stage DST register
                                                                        (pipe_wb_ex.incr_r2_enable && pipe_wb_ex.src_r2==pipe_id_out_w.src_r1)?
                                                                        pipe_wb_ex.val_r2://forward from execution stage R2 register
                                                                        rf[pipe_id_out_w.src_r1];//otherwise from register file
                                                                                
                pipe_id_out_w.val_r2    =       (pipe_wb_mem.write_reg && pipe_wb_mem.dst_r==pipe_id_out_w.src_r2)?
                                                                        pipe_wb_mem.val_dst://forward from memory read
                                                                        //(pipe_wb_mem.incr_r2_enable && pipe_wb_mem.src_r2==pipe_id_out_w.src_r2)?
                                                                        //pipe_wb_mem.val_r2://forward from mem stage R2 register
                                                                        (pipe_wb_ex.write_reg && pipe_wb_ex.dst_r==pipe_id_out_w.src_r2)?
                                                                        pipe_wb_ex.val_dst://forward from execution stage DST register                                                                  
                                                                        (pipe_wb_ex.incr_r2_enable && pipe_wb_ex.src_r2==pipe_id_out_w.src_r2)?
                                                                        pipe_wb_ex.val_r2://forward from execution stage R2 register    
                                                                        rf[pipe_id_out_w.src_r2];//otherwise from register file
                                                                                
                                                                                
                pipe_id_out_w.val_dst   =       (pipe_wb_mem.write_reg && pipe_wb_mem.dst_r==pipe_id_out_w.dst_r)?
                                                                        pipe_wb_mem.val_dst://forward from memory read
                                                                        //(pipe_wb_mem.incr_r2_enable && pipe_wb_mem.src_r2==pipe_id_out_w.dst_r)?
                                                                        //pipe_wb_mem.val_r2://forward from mem stage R2 register
                                                                        (pipe_wb_ex.write_reg && pipe_wb_ex.dst_r==pipe_id_out_w.dst_r)?
                                                                        pipe_wb_ex.val_dst://forward from execution stage DST register                                                                  
                                                                        (pipe_wb_ex.incr_r2_enable && pipe_wb_ex.src_r2==pipe_id_out_w.dst_r)?
                                                                        pipe_wb_ex.val_r2://forward from execution stage R2 register    
                                                                        rf[pipe_id_out_w.dst_r];//otherwise from register file
                        
                offset_w = (instruction[25])?pipe_id_out_w.val_r2:{{17{instruction[24]}},instruction[24:10]};//17 bit sign + 15 bit offset
                        
                case(instruction[24:22])
                        0:begin pipe_id_out_w.incr_r2=4'd0;pipe_id_out_w.incr_r2_enable = 0;end
                        1:pipe_id_out_w.incr_r2=4'd1;
                        2:pipe_id_out_w.incr_r2=4'd2;
                        3:pipe_id_out_w.incr_r2=4'd4;
                        4:begin pipe_id_out_w.incr_r2=4'd0;pipe_id_out_w.incr_r2_enable = 0;end
                        5:pipe_id_out_w.incr_r2=-4'd1;
                        6:pipe_id_out_w.incr_r2=-4'd2;
                        7:pipe_id_out_w.incr_r2=-4'd4;
                endcase
                        
                case(instruction[31:28])
                        //load and store
                        LDR:
                        case(instruction[27:26])
                                2'b00:
                                begin
                                pipe_id_out_w.write_reg = (pipe_id_out_w.dst_r!=pipe_id_out_w.src_r1)?1:0;//write from reg src1 to reg dst
                                //pipe_id_out_w.incr_r2_enable  = pipe_id_out_w.write_reg;
                                pipe_id_out_w.val_dst   = pipe_id_out_w.val_r1;
                                end
                                2'b01:
                                begin
                                        pipe_id_out_w.val_dst[31:16]    = instruction[20:5];
                                        pipe_id_out_w.write_reg = 1;//write from reg src1 to reg dst
                                        pipe_id_out_w.incr_r2_enable    = 0;
                                end
                                2'b10:
                                begin
                                        pipe_id_out_w.val_dst[15:0]     = instruction[20:5];
                                        pipe_id_out_w.write_reg = 1;//write from reg src1 to reg dst
                                        pipe_id_out_w.incr_r2_enable    = 0;
                                end
                                2'b11:
                                begin
                                        pipe_id_out_w.read_mem  = 1;//read from mem by Rscr2+Rsrc1 and then write to register
                                        pipe_id_out_w.write_reg = 1;//write from reg src1 to reg dst
                                        pipe_id_out_w.incr_r2_enable    = instruction[25];
                                        pipe_id_out_w.val_r2    = offset_w;
                                end     
                        endcase
                                
                        STR:
                        case(instruction[27:26])
                                //2'b11:
                                default:
                                begin
                                        pipe_id_out_w.write_mem = 1;//write Rdst to mem by Rscr2+Rsrc1
                                        pipe_id_out_w.val_r2    = offset_w;
                                        pipe_id_out_w.incr_r2_enable    = instruction[25];
                                end     
                        endcase
                                        
                        //jumps
                        JMPUNC:
                        case(instruction[27:26])
                                2'b00:
                                begin
                                        pipe_id_out_w.val_r1    =instruction[25:0];
                                        pipe_id_out_w.val_r2    ='0;//no offset
                                        pipe_id_out_w.incr_r2_enable    = 0;
                                        pipe_id_out_w.jmpunc    = 1;
                                end
                                2'b01://relative jump
                                begin
                                        pipe_id_out_w.val_r1    =pc;
                                        pipe_id_out_w.val_r2    =offset_w;//offset
                                        pipe_id_out_w.incr_r2_enable    = instruction[25];
                                        pipe_id_out_w.jmpunc    = 1;
                                end
                                2'b10://call
                                begin
                                        pipe_id_out_w.val_r1    =pc;
                                        pipe_id_out_w.val_r2    =offset_w;//offset
                                        pipe_id_out_w.val_dst   =pc;//return address
                                        pipe_id_out_w.incr_r2_enable    = instruction[25];
                                        pipe_id_out_w.jmpunc    = 1;
                                        pipe_id_out_w.write_reg = 1;
                                end
                                2'b11://ret
                                begin
                                        pipe_id_out_w.val_r1    =pipe_id_out_w.val_dst;
                                        pipe_id_out_w.val_r2    ='0;//offset
                                        pipe_id_out_w.incr_r2_enable    = instruction[25];
                                        pipe_id_out_w.jmpunc    = 1;
                                end                             
                        endcase
                                        
                        JMPF:
                        case(instruction[27:26])
                                2'b00://jmpz
                                begin
                                        pipe_id_out_w.val_r1    =pc;
                                        pipe_id_out_w.val_r2    =offset_w;//offset
                                        pipe_id_out_w.incr_r2_enable    = instruction[25];
                                        pipe_id_out_w.jmpz      = 1;
                                end
                                2'b01://jmpnz
                                begin
                                        pipe_id_out_w.val_r1    =pc;
                                        pipe_id_out_w.val_r2    =offset_w;//offset
                                        pipe_id_out_w.incr_r2_enable    = instruction[25];
                                        pipe_id_out_w.jmpnz     = 1;
                                end
                                2'b10://jmpc
                                begin
                                        pipe_id_out_w.val_r1    =pc;
                                        pipe_id_out_w.val_r2    =offset_w;//offset
                                        pipe_id_out_w.incr_r2_enable    = instruction[25];
                                        pipe_id_out_w.jmpc      = 1;
                                end
                                2'b11://jmpnc
                                begin
                                        pipe_id_out_w.val_r1    =pc;
                                        pipe_id_out_w.val_r2    =offset_w;//offset
                                        pipe_id_out_w.incr_r2_enable    = instruction[25];
                                        pipe_id_out_w.jmpnc     = 1;
                                end                             
                        endcase
                                        
                        //Arithmetic
                        ALU:
                        case(instruction[27:25])
                                3'd0:
                                begin
                                        pipe_id_out_w.write_reg = 1;
                                        pipe_id_out_w.and_op    = 1;
                                end
                                3'd1:
                                begin
                                        pipe_id_out_w.write_reg = 1;
                                        pipe_id_out_w.or_op     = 1;
                                end
                                3'd2:
                                begin
                                        pipe_id_out_w.write_reg = 1;
                                        pipe_id_out_w.xor_op    = 1;
                                end
                                3'd3:
                                begin
                                        pipe_id_out_w.write_reg = 1;
                                        pipe_id_out_w.add_op    = 1;
                                end
                                3'd4:
                                begin
                                        pipe_id_out_w.write_reg = 1;
                                        pipe_id_out_w.mul_op    = 1;
                                end
                                3'd5:
                                begin
                                        pipe_id_out_w.write_reg = 1;
                                        pipe_id_out_w.shl_op    = 1;
                                end
                                3'd6:
                                begin
                                        pipe_id_out_w.write_reg = 1;
                                        pipe_id_out_w.shr_op    = 1;
                                end
                                //cmp_op =7
                                default:
                                begin
                                        //pipe_id_out_w.write_reg       = 0;
                                        pipe_id_out_w.cmp_op    = 1;
                                end                             
                        endcase

                        LDRF:
                        case(instruction[27:26])
                                2'b00://ldrz
                                begin
                                        pipe_id_out_w.jmpz      = 1;
                                        pipe_id_out_w.ldrf_op   = 1;
                                        pipe_id_out_w.write_reg = 1;
                                end
                                2'b01://ldrnz
                                begin
                                        pipe_id_out_w.jmpnz     = 1;
                                        pipe_id_out_w.ldrf_op   = 1;
                                        pipe_id_out_w.write_reg = 1;    
                                end
                                2'b10://ldrc
                                begin
                                        pipe_id_out_w.ldrf_op   = 1;
                                        pipe_id_out_w.jmpc      = 1;
                                        pipe_id_out_w.write_reg = 1;    
                                end
                                2'b11://ldrnc
                                begin
                                        pipe_id_out_w.ldrf_op   = 1;
                                        pipe_id_out_w.jmpnc     = 1;
                                        pipe_id_out_w.write_reg = 1;    
                                end                             
                        endcase
                                        
                        default:
                                begin
                                        pipe_id_out_w='0;
                                end
                endcase
        end
        
        always@(posedge clk)// or posedge reset)
        if(reset)
        begin
                pipe_id_out<='0;
                for(int i=0;i<32;i++)
                        rf[i]<='0;
                nop_counter<='0;
                jmp_counter<='0;
                alu_counter<='0;
                oth_counter<='0;
        end
        else
        begin
                if(instruction==0)
                        nop_counter<=nop_counter+1;
                else
                if(instruction[31:28]==JMPUNC || instruction[31:28]==JMPF)
                        jmp_counter<=jmp_counter+1;
                else
                if(instruction[31:28]==ALU)
                        alu_counter<=alu_counter+1;
                else
                        oth_counter<=oth_counter+1;
                                
                if(~pipe_stall)
                        pipe_id_out<=pipe_id_out_w;

                if(pipe_wb_ex.write_reg)//from ex stage DST register
                        rf[pipe_wb_ex.dst_r]<=pipe_wb_ex.val_dst;

                if(pipe_wb_ex.incr_r2_enable)//from ex stage R2 register
                        rf[pipe_wb_ex.src_r2]<=pipe_wb_ex.val_r2;
                        
                if(pipe_wb_mem.write_reg)//from memory read stage
                        rf[pipe_wb_mem.dst_r]<=pipe_wb_mem.val_dst;
        
                //if(pipe_wb_mem.incr_r2_enable)//from mem stage R2 register
                //      rf[pipe_wb_mem.src_r2]<=pipe_wb_mem.val_r2;

                        
//synthesys translate_off
                if(verbose)
                begin
                        if(~pipe_stall)
                        begin
                                case(instruction[31:28])
                                        //load and store
                                        LDR:
                                        case(instruction[27:26])
                                                2'b00:$display("LDR R%0d, R%0d, R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                                2'b01:$display("LDRH R%0d,0x%x",pipe_id_out_w.dst_r,instruction[20:5]);
                                                2'b10:$display("LDRL R%0d,0x%x",pipe_id_out_w.dst_r,instruction[20:5]);
                                                2'b11:$display("LDRP R%0d,[R%0d +%0d],R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,$signed(offset_w),pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                        endcase
                                                
                                STR:
                                case(instruction[27:26])
                                        default:$display("STR R%0d,[R%0d +%0d],R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,$signed(offset_w),pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                endcase
                                                
                                //jumps
                                JMPUNC:
                                case(instruction[27:26])
                                        2'b00:$display("JMP 0x%0x",instruction[25:0]);
                                        2'b01://relative jump
                                        $display("JMPR PC 0x%0x + offset %0d",pc,$signed(offset_w));
                                        2'b10://call
                                        $display("CALLR PC 0x%0x + offset %0d",pc,$signed(offset_w));
                                        2'b11://ret
                                        $display("RET to 0x%0x",pipe_id_out_w.val_dst);
                                endcase
                                                
                                JMPF:
                                case(instruction[27:26])
                                        2'b00://jmpz
                                                $display("JMPZ PC 0x%0x + offset %0d",pc,$signed(offset_w));
                                        2'b01://jmpnz
                                                $display("JMPNZ PC 0x%0x + offset %0d",pc,$signed(offset_w));
                                        2'b10://jmpc
                                                $display("JMPC PC 0x%0x + offset %0d",pc,$signed(offset_w));
                                        2'b11://jmpnc
                                                $display("JMPNC PC 0x%0x + offset %0d",pc,$signed(offset_w));   
                                endcase
                                                
                                //Arithmetic
                                ALU:
                                case(instruction[27:25])
                                        3'd0:$display("AND R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                        3'd1:$display("OR  R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                        3'd2:$display("XOR R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                        3'd3:$display("ADD R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                        3'd4:$display("MUL R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                        3'd5:$display("SHL R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                        3'd6:$display("SHR R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                        default:$display("CMP R%0d with R%0d+%d",pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));             
                                endcase
                                
                                LDRF:
                                case(instruction[27:26])
                                        2'b00://ldrz
                                                $display("LDRZ R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                        2'b01://ldrnz
                                                $display("LDRNZ R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                        2'b10://ldrc
                                                $display("LDRC R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                        2'b11://ldrnc
                                                $display("LDRNC R%0d,R%0d,R%0d+%d",pipe_id_out_w.dst_r,pipe_id_out_w.src_r1,pipe_id_out_w.src_r2,$signed(pipe_id_out_w.incr_r2));
                                endcase
                                
                                default:
                                        if(!reset)
                                        begin
                                                $display("Unknown Command %x",instruction[31:28]);
                                                $stop;
                                        end
                        endcase
                        end
                        else
                                $display("[ID stage] STALLED!",instruction[31:28]);
                end
//synthesys translate_on                
        end

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.