⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 8251_8055_verilog.txt

📁 8251和8055的verilog源码
💻 TXT
📖 第 1 页 / 共 4 页
字号:
    end
    endtask


    /* fetch and execute instructions */
    task execute_instructions;
    forever begin
        instruction = instruction + 1;
        if(dflags[3])
            $display("executing instruction %d", instruction);

        @ec1 // clock cycle 1
            addr = pc;
            s = 0;
            iomff = 0;
            read = 1;
            write = 1;
            acontrol = 1;
            dcontrol = 1;
            aleff = 1;
            if(haltff) begin
                haltff = 1;
                s0ff = 0;
                s1ff = 0;
                haltreq;
            end
            else begin
                s0ff = 1;
                s1ff = 1;
            end
        @ec2
            aleff = 0;

        @ec1 // clock cycle 2
            read = 0;
            dcontrol = 0;
        @ec2
            ready_hold;

        @ec2 // clock cycle 3
            read = 1;
            data = ad;
            ir = ad;

        @ec1 // clock cycle 4
            if(do6cycles(ir)) begin
                // do a 6-cycle instruction fetch
                @ec1 @ec2 // conditional clock cycle 5
                    if(hold) begin
                        holdff =1 ;
                        acontrol = 0;
                        dcontrol = 0;
                        @ec2 hldaff = 1;
                    end
                    else begin
                        holdff = 0;
                        hldaff = 0;
                    end

                @ec1; // conditional clock cycle 6
            end

            if(holdff) holdit;
            checkint;
            do_instruction;

            while(hold) @ec2 begin
                acontrol = 0;
                dcontrol = 0;
            end
            holdff = 0;
            hldaff = 0;
            if(validint) interrupt;
    end
    endtask


    function do6cycles;
    input[7:0] ireg;
    begin
        do6cycles = 0;
        case(ireg[2:0])
            0, 4, 5, 7: if(ireg[7:6] == 3) do6cycles = 1;
            1: if((ireg[3] == 1) && (ireg[7:5] == 7)) do6cycles = 1;
            3: if(ireg[7:6] == 0) do6cycles = 1;
        endcase
    end
    endfunction


    task checkint;
    begin
        if(rst6p5)
            if((intmask[3] == 1) && (intmask[1] == 0)) intmask[6] = 1;
        else
            intmask[6] = 0;

        if(rst5p5)
            if((intmask[3] == 1) && (intmask[0] == 0)) intmask[5] = 1;
        else
            intmask[5] = 0;

        if({intmask[7], intmask[3:2]} == 6)
            intmask[4] = 1;
        else
            intmask[4] = 0;

        validint = (intmask[6:4] == 7) | trapff | intr;
    end
    endtask


    // concurently with executing instructions,
    // process primary inputs for processor interrupt
    always @(posedge trap) trapff = 1;

    always @(negedge trap) trapff = 0;

    always @(posedge rst7p5) intmask[7] = 1;


    /* check condition of ready and hold inputs */
    task ready_hold;
    begin
        while(!ready) @ec2;
        @ec1
            if(hold) begin
                holdff = 1;
                @ec2 hldaff = 1;
            end
    end
    endtask


    /* hold */
    task holdit;
    begin
        while(hold) @ec2 begin
            acontrol = 0;
            dcontrol = 0;
        end
        holdff = 0;
        @ec2 hldaff = 0;
    end
    endtask



    /* halt request */
    task haltreq;
    forever begin
        @ec2
            if(validint) begin
                haltff = 0;
                interrupt;
                disable haltreq;
            end
            else begin
                while(hold) @ec2 hldaff = 1;
                hldaff = 0;
                @ec2;
            end

        @ec1 #10
            dcontrol = 0;
            acontrol = 0;
            checkint;
    end
    endtask

    /* memory read */
    task memread;
    output[7:0] rdata;
    input[15:0] raddr;
    begin
        @ec1
            addr = raddr;
            s = 0;
            acontrol = 1;
            dcontrol = 1;
            iomff = int;
            s0ff = int;
            s1ff = 1;
            aleff = 1;
        @ec2
            aleff = 0;

        @ec1 
            dcontrol = 0;
            if(int)
                intaff = 0;
            else
                read = 0;
        @ec2
            ready_hold;
            checkint;

        @ec2
            intaff = 1;
            read = 1;
            rdata = ad;
        if(holdff) holdit;
    end
    endtask

    /* memory write */
    task memwrite;
    input[7:0] wdata;
    input[15:0] waddr;
    begin
        @ec1
            aleff = 1;
            s0ff = 1;
            s1ff = 0;
            s = 0;
            iomff = 0;
            addr = waddr;
            acontrol = 1;
            dcontrol = 1;
        @ec2
            aleff = 0;

        @ec1
            data = wdata;
            write = 0;
            s = 1;
        @ec2
            ready_hold;
            checkint;

        @ec2
            write = 1;
        if(holdff) holdit;
    end
    endtask

    /* reads from an i/o port */
    task ioread;
    input[7:0] sa;
    begin
        @ec1
            aleff = 1;
            s0ff = 0;
            s1ff = 1;
            s = 0;
            iomff = 1;
            addr = {sa, sa};
            acontrol = 1;
            dcontrol = 1;

        @ec2
            aleff = 0;

        @ec1
            dcontrol = 0;
            if(int)
                intaff = 0;
            else
                read = 0;

        @ec2
            ready_hold;

            checkint;

        @ec2
            intaff = 1;
            read = 1;
            acc = ad;
            if(dflags[2])
                $display("IN %h   data = %h", sa, acc);
    end
    endtask

    /* writes into i/o port */
    task iowrite;
    input[7:0] sa;
    begin
        @ec1
            addr = {sa, sa};
            aleff = 1;
            s0ff = 1;
            s1ff = 0;
            s = 0;
            iomff = 1;
            acontrol = 1;
            dcontrol = 1;

        @ec2
            aleff = 0;

        @ec1
            data = acc;
            write = 0;
            s = 1;

            if(dflags[2])
                $display("OUT %h   data = %h", sa, acc);

        @ec2
            ready_hold;

            checkint;

        @ec2
            write = 1;
            if(holdff) holdit;
    end
    endtask

    task interrupt;
    begin
        @ec1
            if(hold) begin
                holdff = 1;
                holdit;
                @ec2 hldaff = 1;
            end
            if(trapff) begin
                inte = intmask[3];
                trapi = 1;
                intic;
                pc = 'h24;
                trapi = 1;
                trapff = 0;
            end
            else if(intmask[7]) begin
                intic;
                pc = 'h3c;
                intmask[7] = 0;
            end
            else if(intmask[6]) begin
                intic;
                pc = 'h34;
                intmask[6] = 0;
            end
            else if(intmask[5]) begin
                intic;
                pc = 'h2c;
                intmask[5] = 0;
            end
            else if(intr) begin
                //?
            end
    end
    endtask

    task intic;
    begin
        aleff = 1;
        s0ff = 1;
        s1ff = 1;
        s = 0;
        iomff = 1;
        addr = pc;
        read = 1;
        write = 1;
        acontrol = 1;
        dcontrol = 1;

        @ec2 aleff = 0;
        @ec1 dcontrol = 0;
        repeat(4) @ec1;
        push2b(pc[15:8], pc[7:0]);
    end
    endtask


    /* execute instruction */
    task do_instruction;
    begin
      if(dflags[1])
        $display( "C%bZ%bM%bE%bI%b A=%h B=%h%h D=%h%h H=%h%h S=%h P=%h IR=%h",
                  cc, cz, cs, cp, cac, acc, regb,regc, regd,rege, regh,regl,
                  sp, pc, ir);

        pc = pc + 1;
        @ec2 // instruction decode synchronized with clock 2 event
            case(ir[7:6])
                0:
                    case(ir[2:0])
                        0: newops;
                        1: if(ir[3]) addhl; else lrpi;
                        2: sta_lda;
                        3: inx_dcx;
                        4: inr;
                        5: dcr;
                        6: movi;
                        7: racc_spec;
                    endcase
                1:
                    move;
                2:
                    rmop;
                3:
                    case(ir[2:0])
                        0,
                        2,
                        4: condjcr;
                        1: if(ir[3]) decode1; else pop;
                        3: decode2;
                        5: if(ir[3]) decode3; else push;
                        6: immacc;
                        7: restart;
                    endcase
            endcase
    end
    endtask

    /* move register to register */
    task move;
        case(ir[2:0])
            0: rmov(regb); // MOV -,B
            1: rmov(regc); // MOV -,C
            2: rmov(regd); // MOV -,D
            3: rmov(rege); // MOV -,E
            4: rmov(regh); // MOV -,H
            5: rmov(regl); // MOV -,L
            6:
                if(ir[5:3] == 6) haltff = 1; // HLT
                else begin // MOV -,M
                    memread(data, {regh, regl});
                    rmov(data);
                end

            7: rmov(acc); // MOV -,A
        endcase
    endtask

    /* enabled only by move */
    task rmov;
    input[7:0] fromreg;
        case(ir[5:3])
            0: regb = fromreg; // MOV B,-
            1: regc = fromreg; // MOV C,-
            2: regd = fromreg; // MOV D,-
            3: rege = fromreg; // MOV E,-
            4: regh = fromreg; // MOV H,-
            5: regl = fromreg; // MOV L,-
            6: memwrite(fromreg, {regh, regl}); // MOV M,-
            7: acc = fromreg; // MOV A,-
        endcase
    endtask

    /* move register and memory immediate */
    task movi;
    begin
        case(ir[5:3])
            0: memread(regb, pc); // MVI B
            1: memread(regc, pc); // MVI C
            2: memread(regd, pc); // MVI D
            3: memread(rege, pc); // MVI E
            4: memread(regh, pc); // MVI H
            5: memread(regl, pc); // MVI L
            6: // MVI M
                begin
                    memread(data, pc);
                    memwrite(data, {regh, regl});
                end

            7: memread(acc, pc); // MVI A
        endcase
        pc = pc + 1;
    end
    endtask

    /* increment register and memory contents */
    task inr;
        case(ir[5:3])
            0: doinc(regb); // INR B
            1: doinc(regc); // INR C
            2: doinc(regd); // INR D
            3: doinc(rege); // INR E
            4: doinc(regh); // INR H
            5: doinc(regl); // INR L
            6: // INR M
                begin
                    memread(data, {regh, regl});
                    doinc(data);
                    memwrite(data, {regh, regl});
                end

            7: doinc(acc); // INR A
        endcase
    endtask

    /* enabled only from incrm */
    task doinc;
    inout[7:0] sr;
    begin
        cac = sr[3:0] == 'b1111;
        sr = sr + 1;
        calpsz(sr);
    end
    endtask

    /* decrement register and memory contents */
    task dcr;
        case(ir[5:3])
            0: dodec(regb); // DCR B
            1: dodec(regc); // DCR C
            2: dodec(regd); // DCR D
            3: dodec(rege); // DCR E
            4: dodec(regh); // DCR H
            5: dodec(regl); // DCR L
            6: // DCR M
                begin
                    memread(data, {regh, regl});
                    dodec(data);
                    memwrite(data, {regh, regl});
                end

            7: dodec(acc); // DCR A
        endcase
    endtask

    /* enabled only from decrm */
    task dodec;
    inout[7:0] sr;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -