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

Subversion Repositories qrisc32

[/] [qrisc32/] [trunk/] [qrisc32_TB.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
//
//
//////////////////////////////////////////////////////////////////////////////////////////////



`timescale 1ns / 1ns

module qrisc32_tb;
//Parameters declaration: 
        import risc_pack::*;
        
        //Internal signals declarations:
        bit reset,clk;
        //I data        
        logic[31:0]     idata;
        logic[31:0]     iaddr;
        logic           ird;
        logic           ireq;
        
        //D read
        logic[31:0]     rdata;
        logic[31:0]     raddr;
        logic           rrd;
        logic           rreq=0;
        
        //D write
        logic[31:0]     wdata;
        logic[31:0]     waddr;
        logic           wwr;
        logic           wreq=0;
        logic           Istop_active,Dstop_active;
        bit                     Istop_enable,Dstop_enable;
        bit                     verbose;
                
        //emulates Instruction ram
        mem             Iram(
                .clk(clk),
                .add_r(iaddr),
                .add_w(32'h0),
                .data_w(32'h0),
                .rd(ird),
                .wr(1'b0),
                .data_r(idata),
                .req(ireq),
                .stop_enable(Istop_enable),
                .stop_active(Istop_active),
                .verbose(verbose)
        );
        defparam Iram.size=256;
        defparam Iram.adr_limit=93;
        
        //emulates Data ram
        mem             Dram(
                .clk(clk),
                .add_r(raddr),
                .add_w(waddr),
                .data_w(wdata),
                .rd(rrd),
                .wr(wwr),
                .data_r(rdata),
                .req(),
                .stop_enable(Dstop_enable),
                .stop_active(Dstop_active),
                .verbose(verbose)
        );
        defparam Dram.size=10;
        defparam Dram.adr_limit=10;
        
        // Unit Under Test port map
        qrisc32 UUT(
                .reset(reset),
                .clk(clk),
                //avalon master port only for  reading instructions
                .avm_instructions_data(idata),
                .avm_instructions_addr(iaddr),
                .avm_instructions_rd(ird),
                .avm_instructions_wait_req(ireq),
        
                //avalon master port only for  reading data
                .avm_datar_data(rdata),
                .avm_datar_addr(raddr),
                .avm_datar_rd(rrd),
                .avm_datar_wait_req(rreq),

                //avalon master port only for  writing data
                .avm_dataw_data(wdata),
                .avm_dataw_addr(waddr),
                .avm_dataw_wr(wwr),
                .avm_dataw_wait_req(wreq),
                .verbose(verbose)
        );

        int address;
        bit signed[14:0] jmpr_label0,jmpr_label1;
        bit [25:0] ilabel,jlabel,inclabel,jmp_label1;
        
        function        void loadIram;
                input[31:0]     data;
                begin
                        Iram.sram[address] = data;
                        address=address+1;
                end
        endfunction

        task    load_buble_sort;
        /*buble algorithm
                R0=mem[00],R1=mem[04],R2=mem[08],R3=mem[c],R4=mem[10]
                R5=mem[14],R6=mem[18],R7=mem[1c],R8=mem[20],R9=mem[24]
                R10=R0;
                R11=R0;//minimum
                if R1<R11
                        R11=R1
                if R2<R11
                        R11=R2
                if R3<R11
                        R11=R3
                if R4<R11
                        R11=R4
                if R5<R11
                        R11=R5
                if R6<R11
                        R11=R6
                if R7<R11
                        R11=R7
                if R8<R11
                        R11=R8
                if R9<R11
                        R11=R9
                mem[0]=R11;
                                         
                for (i = 36; i > 0; i-=4)//36,32,28,24,20,16,12,8,4
                {
                        if R0>R10
                                R10=R0
                        if R1>R10
                                R10=R1
                        if R2>R10
                                R10=R2
                        if R3>R10
                                R10=R3
                        if R4>R10
                                R10=R4
                        if R5>R10
                                R10=R5
                        if R6>R10
                                R10=R6
                        if R7>R10
                                R10=R7
                        if R8>R10
                                R10=R8
                        if R9>R10
                                R10=R9
                                
                        mem[i]=R10;

                        //substitute maximum by minimum
                        if R10=R0
                                R0=R11
                        if R10=R1
                                R1=R11
                        if R10=R2
                                R2=R11
                        if R10=R3
                                R3=R11
                        if R10=R4
                                R4=R11
                        if R10=R5
                                R5=R11
                        if R10=R6
                                R6=R11
                        if R10=R7
                                R7=R11
                        if R10=R8
                                R8=R11
                        if R10=R9
                                R9=R11
                                
                }*/
        //loading instructions
                address=0;
                //verbose=1;
                //Istop_enable=1;
                
                loadIram({LDRH,16'h0000,R12});//R12 is 36
                loadIram({XOR,DECR_0,7'h0,R13,R13,R13});//R13 is 0
                loadIram({LDRH,16'hFFFF,R14});//R14 is -4
                loadIram({LDRL,16'h0024,R12});//R12 is 36
                
                loadIram({LDRP,OFFSET_CODE,15'd00,R13,R0});//ldr R0,[R13+0]
                loadIram({LDRP,OFFSET_CODE,15'd04,R13,R1});//ldr R1,[R13+4]
                loadIram({LDRP,OFFSET_CODE,15'd08,R13,R2});//ldr R2,[R13+8]
                loadIram({LDRP,OFFSET_CODE,15'd12,R13,R3});//ldr R3,[R13+12]
                loadIram({LDRP,OFFSET_CODE,15'd16,R13,R4});//ldr R4,[R13+16]

                loadIram({LDRP,OFFSET_CODE,15'd20,R13,R5});//ldr R5,[R13+20]
                loadIram({LDRP,OFFSET_CODE,15'd24,R13,R6});//ldr R6,[R13+24]
                loadIram({LDRP,OFFSET_CODE,15'd28,R13,R7});//ldr R7,[R13+28]
                loadIram({LDRP,OFFSET_CODE,15'd32,R13,R8});//ldr R8,[R13+32]
                loadIram({LDRP,OFFSET_CODE,15'd36,R13,R9});//ldr R9,[R13+36]

                loadIram({LDRL,-16'd4,R14});//R14 is -4
                
                //search for minimum
                loadIram({CMP,INCR_0,7'h0,R0,R1,R1});
                loadIram({LDRC,INCR_0,7'h0,R0,R1,R16});
                
                loadIram({CMP,INCR_0,7'h0,R3,R2,R2});
                loadIram({LDRC,INCR_0,7'h0,R3,R2,R17});
                
                loadIram({CMP,INCR_0,7'h0,R5,R4,R4});
                loadIram({LDRC,INCR_0,7'h0,R5,R4,R18});
                
                loadIram({CMP,INCR_0,7'h0,R7,R6,R6});
                loadIram({LDRC,INCR_0,7'h0,R7,R6,R19});

                loadIram({CMP,INCR_0,7'h0,R9,R8,R8});
                loadIram({LDRC,INCR_0,7'h0,R9,R8,R20});

                loadIram({CMP,INCR_0,7'h0,R17,R16,R16});
                loadIram({LDRC,INCR_0,7'h0,R17,R16,R21});

                loadIram({CMP,INCR_0,7'h0,R19,R18,R18});
                loadIram({LDRC,INCR_0,7'h0,R19,R18,R22});

                loadIram({CMP,INCR_0,7'h0,R21,R20,R20});
                loadIram({LDRC,INCR_0,7'h0,R21,R20,R23});
                loadIram({NOP});

                loadIram({CMP,INCR_0,7'h0,R23,R22,R22});
                loadIram({LDRC,INCR_0,7'h0,R23,R22,R11});

                loadIram({NOP});
                //minimum write
                loadIram({STRP,OFFSET_CODE,15'd0,R13,R11});//str R10,[R13+0]

                //
                //search for maximum
                loadIram({CMP,INCR_0,7'h0,R0,R1,R1});
                loadIram({LDRNC,INCR_0,7'h0,R0,R1,R16});
                
                loadIram({CMP,INCR_0,7'h0,R3,R2,R2});
                jmpr_label0=4*address;
                loadIram({LDRNC,INCR_0,7'h0,R3,R2,R17});
                
                loadIram({CMP,INCR_0,7'h0,R5,R4,R4});
                loadIram({LDRNC,INCR_0,7'h0,R5,R4,R18});
                
                loadIram({CMP,INCR_0,7'h0,R7,R6,R6});
                loadIram({LDRNC,INCR_0,7'h0,R7,R6,R19});

                loadIram({CMP,INCR_0,7'h0,R9,R8,R8});
                loadIram({LDRNC,INCR_0,7'h0,R9,R8,R20});

                loadIram({CMP,INCR_0,7'h0,R17,R16,R16});
                loadIram({LDRNC,INCR_0,7'h0,R17,R16,R21});

                loadIram({CMP,INCR_0,7'h0,R19,R18,R18});
                loadIram({LDRNC,INCR_0,7'h0,R19,R18,R22});

                loadIram({CMP,INCR_0,7'h0,R21,R20,R20});
                loadIram({LDRNC,INCR_0,7'h0,R21,R20,R23});
                loadIram({NOP});

                loadIram({CMP,INCR_0,7'h0,R23,R22,R22});
                loadIram({LDRNC,INCR_0,7'h0,R23,R22,R10});
                loadIram({NOP});
                
                loadIram({STRP,OFFSET_CODE,15'd0,R12,R10});//str R10,[R12+0]

                loadIram({ADD,DECR_0,7'h0,R14,R12,R12});//R12 = R12 + R12( -4)
                
                loadIram({CMP,INCR_0,7'h0,R0,R10,R10});
                loadIram({LDRZ,INCR_0,7'h0,R0,R11,R0});
                loadIram({CMP,INCR_0,7'h0,R1,R10,R10});
                loadIram({LDRZ,INCR_0,7'h0,R1,R11,R1});
                loadIram({CMP,INCR_0,7'h0,R2,R10,R10});
                loadIram({LDRZ,INCR_0,7'h0,R2,R11,R2});
                loadIram({CMP,INCR_0,7'h0,R3,R10,R10});
                loadIram({LDRZ,INCR_0,7'h0,R3,R11,R3});
                loadIram({CMP,INCR_0,7'h0,R4,R10,R10});
                loadIram({LDRZ,INCR_0,7'h0,R4,R11,R4});
                loadIram({CMP,INCR_0,7'h0,R5,R10,R10});
                loadIram({LDRZ,INCR_0,7'h0,R5,R11,R5});
                loadIram({CMP,INCR_0,7'h0,R6,R10,R10});
                loadIram({LDRZ,INCR_0,7'h0,R6,R11,R6});
                loadIram({CMP,INCR_0,7'h0,R7,R10,R10});
                loadIram({LDRZ,INCR_0,7'h0,R7,R11,R7});
                loadIram({CMP,INCR_0,7'h0,R8,R10,R10});
                loadIram({LDRZ,INCR_0,7'h0,R8,R11,R8});
                loadIram({CMP,INCR_0,7'h0,R9,R10,R10});
                loadIram({LDRZ,INCR_0,7'h0,R9,R11,R9});
                
                loadIram({CMP,INCR_0,7'h0,R13,R12,R12});//cmp R12 with R13(0)
                 
                jmpr_label1=jmpr_label0-4*address-8;
                loadIram({JMPNZ,OFFSET_CODE,jmpr_label1,10'h0});
                loadIram({LDRR,DECR_0,7'h0,R11,R11,R10});//R10 =R11
                
                loadIram({CMP,INCR_0,7'h0,R0,R1,R1});
                loadIram({LDRNC,INCR_0,7'h0,R0,R1,R16});
                loadIram({CMP,INCR_0,7'h0,R3,R2,R2});
                
                
        endtask;


        task    load_shell_sort_mdf;
        /*new algorithm
                for(inc = 20;inc>0;inc=inc/2)//20, 8 and 4 (5,2,1)
                {
                        for (i = inc; i < 40; i+=4)//0..4..8..c and etc
                        {
                                temp = a[i];
                                for (j = i; (j >= inc) && (a[j-inc] > temp); j =j-inc)
                                {
                                        a[j] = a[j-inc];
                                }       
                        a[j] = temp;
                        }
                }*/
        //---------------------  reverse(709) random(714) sorted(516)
        //loading instructions
                address=0;
                loadIram({LDRH,16'h0000,R5});//R5 inc = 5
                loadIram({LDRH,16'h0000,R8});//R8 =1
                loadIram({LDRH,16'h0000,R9});//R9 =2
                loadIram({LDRH,16'h0000,R10});//R10 is 4
                loadIram({LDRH,16'h0000,R12});//R12 is 40
                loadIram({LDRH,16'hFFFF,R13});//R13 is mask 0xffff_ffff
                loadIram({LDRH,16'h0000,R14});//R14 is 3

                loadIram({LDRL,16'h0005,R5});//R5 inc = 5               
                loadIram({LDRL,16'h0001,R8});//R8 =1
                loadIram({LDRL,16'h0002,R9});//R9 =2
                loadIram({LDRL,16'h0004,R10});//R10 is 4
                loadIram({LDRL,16'h0028,R12});//R12 is 40
                loadIram({LDRL,16'hFFFF,R13});//R13 is mask 0xffff_ffff
                loadIram({LDRL,16'h0003,R14});//R14 is 3
                                
                //R5 - inc
                //R6 - -inc
                //R7 - j-inc
                //R4 - i
                //R3 - J
                //for (inc...
                inclabel = 4*address;
                jmpr_label0 = 4*address;
                loadIram({SHL,INCR_0,7'h0,R9,R5,R5});//R5 = R5<<R9( R5<<2)
                                
                jmpr_label1=1000*4;//out of code
                loadIram({JMPZ,OFFSET_CODE,jmpr_label1,10'h0});//R5>0?

                loadIram({XOR,DECR_0,7'h0,R13,R5,R6});//R6 = R5 xor R13
                loadIram({LDRR,DECR_0,7'h0,R5,R5,R4});//i(R4)=inc (R5)
                loadIram({ADD,DECR_0,7'h0,R8,R6,R6});//R6 = R6 + R8( +1)
                loadIram({SHR,INCR_0,7'h0,R14,R5,R5});//R5 = R5>>R14( R5>>3))
                
                loadIram({CMP,INCR_0,7'h0,R12,R4,R4});//compare R4 with R12(i == 40) if 0 then reached maximum-> stop
                ilabel=4*address;

                jmpr_label1=jmpr_label0-4*address-8;
                loadIram({JMPZ,OFFSET_CODE,jmpr_label1,10'h0});//if =40 then goto inc
                
                //temp  - r1
                loadIram({LDRP,OFFSET_CODE,15'd0,R4,R1});//ldr R1,[R4]
                
                //for (j = i;..
                loadIram({LDRR,DECR_0,7'h0,R4,R4,R3});//j(R3)=i(R4)
                loadIram({ADD,DECR_0,7'h0,R4,R6,R7});//R7 = R4+R6=(i)j-inc
                
                loadIram({CMP,INCR_0,7'h0,R5,R3,R3});//cmp R3 j with R5 inc
                jlabel=4*address;
                //a[j-inc]  - r0
                loadIram({LDRP,OFFSET_CODE,15'd0,R7,R0});//ldrp R0,[R7]
                
                jmpr_label1=13*4;
                loadIram({JMPC,OFFSET_CODE,jmpr_label1,10'h0});//c=1 then R3 j < R5 inc 
                loadIram({NOP});loadIram({NOP});loadIram({NOP});
                
                //a[j-inc] > temp?
                loadIram({CMP,INCR_0,7'h0,R1,R0,R0});//cmp R0 a[j-inc] with R1 temp

                jmpr_label1=8*4;
                loadIram({JMPC,OFFSET_CODE,jmpr_label1,10'h0});//c=1 then R0>R1 
                loadIram({NOP});loadIram({NOP});loadIram({NOP});loadIram({NOP});

                loadIram({JMP,jlabel});//goto next cycle of J
                loadIram({LDRR,DECR_0,7'h0,R7,R7,R3});//j=j-inc,  R3=R7
                //a[j] = a[j-inc];
                loadIram({STRP,OFFSET_CODE,15'd0,R3,R0});//str R0,[R3+0]
                loadIram({ADD,DECR_0,7'h0,R3,R6,R7});//R7 = R3+R6=j-inc
                loadIram({CMP,INCR_0,7'h0,R5,R3,R3});//cmp R3 j with R5 inc
                
                //
                loadIram({JMP,ilabel});//goto next cycle of i
                loadIram({ADD,DECR_0,7'h0,R10,R4,R4});//R4=R4+R10...i+=4
                //a[j] = temp;
                loadIram({STRP,OFFSET_CODE,15'd0,R3,R1});//str R3,[R7+0]
                loadIram({CMP,INCR_0,7'h0,R12,R4,R4});//compare R4 with R12(i == 40) if 0 then reached maximum-> stop
                loadIram({NOP});
        endtask;


        task    shell_first;

        //old
        // for (i = 0; i < 36; i+=4) {
        // temp = a[i+4];
        // for (j = i; (j >= 0) && (a[j] > temp); j -= 4)a[j+4] = a[j];
        // a[j+4] = temp;
                
        //loading instructions
                address=0;
                loadIram({LDRH,16'h0000,R10});//R10 is 4
                loadIram({LDRH,16'hffff,R11});//R11 is -4
                loadIram({LDRH,16'h0000,R12});//R12 is 36
                jmp_label1 = 4*address+4*8;
                loadIram({JMP,jmp_label1});//goto entry point
                
                loadIram({XOR,INCR_0,7'h0,R4,R4,R4});//i base of data
                loadIram({LDRL,16'h0004,R10});//R10 is 4
                loadIram({LDRL,16'hFFFC,R11});//R11 is -4
                loadIram({LDRL,16'h0024,R12});//R12 is 36
                //R4  is i=0 base of data
                //R7  is J
                
                //end of main cycle
                jmpr_label0=4*address;
                jmpr_label1=4*address+32*8;
                
                loadIram({JMPZ,OFFSET_CODE,jmpr_label1,10'h0});//goto to out of main cycle
                loadIram({LDRR,DECR_0,7'h0,R5,R4,R7});//R7 = R4   ->R7 is J             
                //a[j+4] = temp;
                loadIram({STRP,OFFSET_CODE,15'd4,R7,R0});//str R0,[R7+4]
                //main cycle here (I)-------------------------------------------------
                //entry point
                //temp=a[i],  R0 is temp
                loadIram({LDRP,OFFSET_CODE,15'd0,R4,R15});//ldr R0,[R4+0]

                //check j <0
                loadIram({XOR,DECR_0,7'h0,R7,R11,R2});//compare R7 with -4
                loadIram({LDRP,OFFSET_CODE,15'd4,R4,R0});//ldr R0,[R4+4]
                //
                jmp_label1=4*address;
                jmpr_label1=jmpr_label0-4*address-8;
                loadIram({JMPZ,OFFSET_CODE,jmpr_label1,10'h0});//Z=1 when J<0 goto end of main cycle a[j+4] = temp;
                //i+=4
                loadIram({ADD,DECR_0,7'h0,R10,R4,R4});//R4 = R4+4
                loadIram({LDRR,DECR_0,7'h0,R15,R15,R1});//R1=R15
                //check i =36?
                loadIram({XOR,INCR_0,7'h0,R12,R4,R2});//R2=R4^R12(i xor 36) if 0 then reached maximum-> stop            
                //a[j] read
                loadIram({LDRP,OFFSET_CODE,-15'd4,R7,R15});//ldr R15,[R7-4]             
                
                //compare R1(a[j]) with R0(temp)
                loadIram({CMP,INCR_0,7'h0,R0,R1,R2});
                jmpr_label1=jmpr_label0-4*address-8;
                loadIram({JMPC,OFFSET_CODE,jmpr_label1,10'h0});//c=1 then R1<=R0   - (a[j] > temp) is false goto end of subcycle (A[j+4]=temp)
                loadIram({NOP});loadIram({NOP});loadIram({NOP});
                //check i =36?
                loadIram({XOR,INCR_0,7'h0,R12,R4,R2});//R2=R4^R12(i xor 36) if 0 then reached maximum-> stop    
                
                loadIram({JMP,jmp_label1});//goto subcycle
                //j-=4
                loadIram({ADD,DECR_0,7'h0,R7,R11,R7});//R7 = R7-4
                //i-=4
                loadIram({ADD,DECR_0,7'h0,R11,R4,R4});//R4 = R4-4               
                //a[j+4] = a[j](R1);
                loadIram({STRP,OFFSET_CODE,15'd8,R7,R1});//str R1,[R7+4]                A[j+4]=temp
                loadIram({XOR,DECR_0,7'h0,R7,R11,R2});//compare R7 with -4
        
        endtask;

        task    load_unsorted_data(bit[1:0] kind);
        //loading  unsorted data in Dram
                for(int i=0;i<10;i++)
                        Dram.sram[i]=(kind==0)? 10-i:                   //reverse unsorted
                                                (kind==1)?      100+$random%100://randomly unsorted
                                                                        i+1;                    //already sorted
        endtask;
        
        task    start;
                reset=1;
                $display("Programm size is %d Words",address);
                #100;
                reset=0;
                #1us;
                @(posedge       Istop_active);
                $display("Sort finished");
                $display("Cycles for sorting -->%0d<--",cycles);
        endtask;
                
        initial
        begin
                Istop_enable=0;
                Dstop_enable=0;
                verbose=0;
                for(int i=0;i<3;i++)
                begin
                        $display("------------------Start round %d------------------",i);
                        load_unsorted_data(i);
                        $display("Load buble sort...");
                        load_buble_sort;
                        start;
                        
                        load_unsorted_data(i);
                        $display("Load shell modified...");
                        load_shell_sort_mdf;
                        start;
                        
                        load_unsorted_data(i);
                        $display("Load shell first...");
                        shell_first;
                        start;
                
                end
                $finish;
        end
        
        initial
        begin
                clk=0;
                forever #10 clk<=!clk;
        end

        int cycles;
        
        always@(posedge clk or posedge reset)
        if(reset)
                cycles=0;
        else
                cycles=cycles+1;
        
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.