data/full_repos/permissive/181665138/verilog/capitolo_vi/sEP8.v
 line:491: before: "=="
1: b"%Error: data/full_repos/permissive/181665138/verilog/capitolo_vi/sEP8.v:491: syntax error, unexpected ==, expecting ')' or ',' or or\n    always @(reset_ == 0) #1\n                    ^~\n%Error: Cannot continue\n"
module sEP8(d7_d0, a23_a0, mr_, mw_, ior_, iow_, clock, reset_);
    input           clock, reset_;
    input   [7:0]   d7_d0;
    output  [23:0]  a23_a0;
    output          mr_, mw_;
    output          ior_, iow_;



    reg         DIR;
    reg [7:0]   D7_D0;
    reg [23:0]  A23_A0;
    reg         MR_, MW_, IOR_, IOW_;
    assign      mr_ = MR_;
    assign      mw_ = MW_;
    assign      ior_ = IOR_;
    assign      iow_ = IOW_;
    assign      a23_a0 = A23_A0;
    assign      d7_d0 = (DIR == 1)?D7_D0:'HZZ;


    reg [2:0]   NUMLOC;
    reg [7:0]   AL, AH, F, OPCODE, SOURCE, APP3, APP2, APP1, APP0;
    reg [23:0]  DP, IP, SP, DEST_ADDR;


    reg [6:0]   STAR, MJR;
    parameter fetch0=0,
              fetch1=1,
              fetch2=2,
              fetchF2_0=3,
              fetchF2_1=4,
              fetchF3_0=5,
              fetchF4_0=6,
              fetchF4_1=7,
              fetchF5_0=8,
              fetchF5_1=9,
              fetchF5_2=10,
              fetchF6_0=11,
              fetchF6_1=12,
              fetchF7_0=13,
              fetchF7_1=14,
              fetchEnd=15,
              fetchEnd1=16,
              nop=17,
              hlt=18,
              ALtoAH=19,
              AHtoAL=20,
              incDP=21,
              ldAL=22,
              ldAH=23,
              storeAL=24,
              storeAH=25,
              ldSP=26,
              ldSP1=27,
              ldimmDP=28,
              ldimmDP1=29,
              lddirDP=30,
              lddirDP1=31,
              lddirDP2=32,
              storeDP=33,
              storeDP1=34,
              in=35,
              in1=36,
              in2=37,
              in3=38,
              out=39,
              out1=40,
              out2=41,
              out3=42,
              out4=43,
              aluAL=44,
              aluAH=45,
              jmp=46,
              pushAL=47,
              pushAH=48,
              pushDP=49,
              popAL=50,
              popAL1=51,
              popAH=52,
              popAH1=53,
              popDP=54,
              popDP1=55,
              call=56,
              call1=57,
              ret=58,
              ret1=59,
              nvi=60,
              readB=61,
              readW=62,
              readM=63,
              readL=64,
              read0=65,
              read1=66,
              read2=67,
              read3=68,
              read4=69,
              writeB=70,
              writeW=71,
              writeM=72,
              writeL=73,
              write0=74,
              write1=75,
              write2=76,
              write3=77,
              write4=78,
              write5=79,
              write6=80,
              write7=81,
              write8=82,
              write9=83,
              write10=84,
              write11=85;














    function valid_fetch;
        input [7:0] opcode;
        
        casex(opcode[7:5])
            'B000:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                    'B00110: valid_fetch = 1;
                    'B00111: valid_fetch = 1;
                    'B01000: valid_fetch = 1;
                    'B01001: valid_fetch = 1;
                    'B01010: valid_fetch = 1;
                    'B01011: valid_fetch = 1;
                    'B01111: valid_fetch = 1;
                    'B10000: valid_fetch = 1;
                    'B10001: valid_fetch = 1;
                endcase
            'B001:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                endcase
            'B010:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                    'B00110: valid_fetch = 1;
                    'B00111: valid_fetch = 1;
                    'B01000: valid_fetch = 1;
                    'B01001: valid_fetch = 1;
                    'B01010: valid_fetch = 1;
                    'B01011: valid_fetch = 1;
                endcase
            'B011:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                endcase
            'B100:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                    'B00110: valid_fetch = 1;
                    'B00111: valid_fetch = 1;
                    'B01000: valid_fetch = 1;
                    'B01001: valid_fetch = 1;
                    'B01010: valid_fetch = 1;
                    'B01011: valid_fetch = 1;
                endcase
            'B101:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                    'B00110: valid_fetch = 1;
                    'B00111: valid_fetch = 1;
                    'B01000: valid_fetch = 1;
                    'B01001: valid_fetch = 1;
                    'B01010: valid_fetch = 1;
                    'B01011: valid_fetch = 1;
                endcase
            'B110:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                endcase
            'B111:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                    'B00110: valid_fetch = 1;
                    'B00111: valid_fetch = 1;
                    'B01000: valid_fetch = 1;
                    'B01001: valid_fetch = 1;
                    'B01010: valid_fetch = 1;
                    'B01011: valid_fetch = 1;
                endcase
        endcase
    endfunction







    function [6:0] first_execution_state;
        input [7:0] opcode;
        casex(opcode)

            'B00000000: first_execution_state = hlt;
            'B00000001: first_execution_state = nop;
            'B00000010: first_execution_state = ALtoAH;
            'B00000011: first_execution_state = AHtoAL;
            'B00000100: first_execution_state = incDP;
            'B00000101: first_execution_state = aluAL;
            'B00000110: first_execution_state = aluAL;
            'B00000111: first_execution_state = aluAL;
            'B00001000: first_execution_state = aluAH;
            'B00001001: first_execution_state = aluAH;
            'B00001010: first_execution_state = aluAH;
			'B00001011: first_execution_state = pushAL;
            'B00001100: first_execution_state = popAL;
            'B00001101: first_execution_state = pushAH;
            'B00001110: first_execution_state = popAH;
            'B00001111: first_execution_state = pushDP;
            'B00010000: first_execution_state = popDP;
            'B00010001: first_execution_state = ret;


            'B00100000: first_execution_state = in;
            'B00100001: first_execution_state = out;
            'B00100010: first_execution_state = ldimmDP;
            'B00100011: first_execution_state = ldSP;
            'B00100100: first_execution_state = lddirDP;
            'B00100101: first_execution_state = storeDP;


            'B01000000: first_execution_state = ldAL;
            'B01000001: first_execution_state = aluAL;
            'B01000010: first_execution_state = aluAL;
            'B01000011: first_execution_state = aluAL;
            'B01000100: first_execution_state = aluAL;
            'B01000101: first_execution_state = aluAL;
            'B01000110: first_execution_state = ldAH;
            'B01000111: first_execution_state = aluAH;
            'B01001000: first_execution_state = aluAH;
            'B01001001: first_execution_state = aluAH;
            'B01001010: first_execution_state = aluAH;
            'B01001011: first_execution_state = aluAH;


            'B01100000: first_execution_state = storeAL;
            'B01100001: first_execution_state = storeAH;


            'B10000000: first_execution_state = ldAL;
            'B10000001: first_execution_state = aluAH;
            'B10000010: first_execution_state = aluAL;
            'B10000011: first_execution_state = aluAL;
            'B10000100: first_execution_state = aluAL;
            'B10000101: first_execution_state = aluAL;
            'B10000110: first_execution_state = ldAH;
            'B10000111: first_execution_state = aluAH;
            'B10001000: first_execution_state = aluAH;
            'B10001001: first_execution_state = aluAH;
            'B10001010: first_execution_state = aluAH;
            'B10001011: first_execution_state = aluAH;


			'B10100000: first_execution_state = ldAL;
            'B10100001: first_execution_state = aluAL;
            'B10100010: first_execution_state = aluAL;
            'B10100011: first_execution_state = aluAL;
            'B10100100: first_execution_state = aluAL;
            'B10100101: first_execution_state = aluAL;
            'B10100110: first_execution_state = ldAH;
            'B10100111: first_execution_state = aluAH;
            'B10101000: first_execution_state = aluAH;
            'B10101001: first_execution_state = aluAH;
            'B10101010: first_execution_state = aluAH;
            'B10101011: first_execution_state = aluAH;


            'B11000000: first_execution_state = storeAL;
            'B11000001: first_execution_state = storeAH;


            'B11100000: first_execution_state = jmp;
            'B11100001: first_execution_state = jmp;
            'B11100010: first_execution_state = jmp;
            'B11100011: first_execution_state = jmp;
            'B11100100: first_execution_state = jmp;
            'B11100101: first_execution_state = jmp;
            'B11100110: first_execution_state = jmp;
            'B11100111: first_execution_state = jmp;
            'B11101000: first_execution_state = jmp;
            'B11101001: first_execution_state = jmp;
            'B11101010: first_execution_state = jmp;
            'B11101011: first_execution_state = jmp;
            'B11101100: first_execution_state = jmp;
            'B11101101: first_execution_state = jmp;
            'B11101110: first_execution_state = jmp;
            'B11101111: first_execution_state = jmp;
            'B11110000: first_execution_state = jmp;
            'B11110001: first_execution_state = jmp;
            'B11110010: first_execution_state = jmp;
            'B11110011: first_execution_state = call;
        endcase
    endfunction











    function jmp_condition;
        input [7:0] opcode;
        input [7:0] flag;
        jmp_condition = 0;


    endfunction












    function [7:0] alu_result;
        input [7:0] opcode, operando1, operando2;
        alu_result = 'B00000000;


    endfunction






    function [3:0] alu_flag;
        input [7:0] opcode, operando1, operando2;
        alu_flag = 'B0000;


    endfunction


    parameter [2:0] F0 = 'B000, F1 = 'B001, F2 = 'B010, F3 = 'B011,
                    F4 = 'B100, F5 = 'B101, F6 = 'B110, F7 = 'B111;



    always @(reset_ == 0) #1
        begin
            IP <= 'HFF0000;
            F <= 'H00;
            DIR <= 0;
            MR_ <= 1;
            MW_ <= 1;
            IOR_ <= 1;
            IOW_ <= 1;
            STAR <= fetch0;
        end



    always @(posedge clock) if (reset_ == 1) #3
        casex(STAR)




            fetch0:
            begin
                A23_A0 <= IP;
                IP <= IP + 1;
                MJR <= fetch1;
                STAR <= readB;
            end



            fetch1:
            begin
                OPCODE <= APP0;

                MJR <= (APP0[7:5] == F0)? fetchEnd:
                       (APP0[7:5] == F1)? fetchEnd:
                       (APP0[7:5] == F2)? fetchF2_0:
                       (APP0[7:5] == F3)? fetchF3_0:
                       (APP0[7:5] == F4)? fetchF4_0:
                       (APP0[7:5] == F5)? fetchF5_0:
                       (APP0[7:5] == F6)? fetchF6_0:
fetchF7_0;

                STAR <= (valid_fetch(APP0) == 1)? fetch2:nvi;
            end



            fetch2:
            begin
                STAR <= MJR;
            end





            fetchF2_0:
            begin
                A23_A0 <= DP;
                MJR <= fetchF2_1;
                STAR <= readB;
            end


            fetchF2_1:
            begin
                SOURCE <= APP0;
                STAR <= fetchEnd;
            end






            fetchF3_0:
            begin
                DEST_ADDR <= DP;
                STAR <= fetchEnd;
            end





            fetchF4_0:
            begin
                A23_A0 <= IP;
                IP <= IP + 1;
                MJR <= fetchF4_1;
                STAR <= readB;
            end


            fetchF4_1:
            begin
                SOURCE <= APP0;
                STAR <= fetchEnd;
            end






            fetchF5_0:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= fetchF5_1;
                STAR <= readM;
            end


            fetchF5_1:
            begin
                A23_A0 <= {APP2, APP1, APP0};
                MJR <= fetchF5_2;
                STAR <= readB;
            end


            fetchF5_2:
            begin
                SOURCE <= APP0;
                STAR <= fetchEnd;
            end






            fetchF6_0:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= fetchF6_1;
                STAR <= readM;
            end



            fetchF6_1:
            begin
                DEST_ADDR <= {APP2, APP1, APP0};
                STAR <= fetchEnd;
            end





            fetchF7_0:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= fetchF7_1;
                STAR <= readM;
            end


            fetchF7_1:
            begin
                DEST_ADDR <= {APP2, APP1, APP0};
                STAR <= fetchEnd;
            end




            fetchEnd:
            begin
                MJR <= first_execution_state(OPCODE);
                STAR <= fetchEnd1;
            end

            fetchEnd1:
            begin
                STAR <= MJR;
            end



            











            hlt:
            begin
                STAR <= hlt;
            end






            nop:
            begin
                STAR <= fetch0;
            end



            ALtoAH:
            begin
                AH <= AL;
                STAR <= fetch0;
            end



            AHtoAL:
            begin
                AL <= AH;
                STAR <= fetch0;
            end



            incDP:
            begin
                DP <= DP + 1;
                STAR <= fetch0;
            end





            ldAL:
            begin
                AL <= SOURCE;
                STAR <= fetch0;
            end





            ldAH:
            begin
                AH <= SOURCE;
                STAR <= fetch0;
            end




            storeAL:
            begin
                A23_A0 <= DEST_ADDR;
                APP0 <= AL;
                MJR <= fetch0;
                STAR <= writeB;
            end




            storeAH:
            begin
                A23_A0 <= DEST_ADDR;
                APP0 <= AH;
                MJR <= fetch0;
                STAR <= writeB;
            end




            ldSP:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= ldSP1;
                STAR <= readM;
            end


            ldSP1:
            begin
                SP <= {APP2, APP1, APP0};
                STAR <= fetch0;
            end




            ldimmDP:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= ldimmDP1;
                STAR <= readM;
            end


            ldimmDP1:
            begin
                DP <= {APP2, APP1, APP0};
                STAR <= fetch0;
            end






            lddirDP:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= lddirDP1;
                STAR <= readM;
            end



            lddirDP1:
            begin
                A23_A0 <= {APP2, APP1, APP0};
                MJR <= lddirDP2;
                STAR <= readM;
            end


            lddirDP2:
            begin
                DP <= {APP2, APP1, APP0};
                STAR <= fetch0;
            end






            storeDP:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= storeDP1;
                STAR <= readM;
            end



            storeDP1:
            begin
                A23_A0 <= {APP2, APP1, APP0};
                {APP2, APP1, APP0} <= DP;
                MJR <= fetch0;
                STAR <= writeM;
            end
            


















            in:
            begin
                A23_A0 <= IP;
                IP <= IP + 2;
                MJR <= in1;
                STAR <= readW;
            end


            in1:
            begin
                A23_A0 <= {'H00, APP1, APP0};
                STAR <= in2;
            end


            in2:
            begin
                IOR_ <= 0;
                STAR <= in3;
            end


            in3:
            begin
                AL <= d7_d0;
                IOR_ <= 1;
                STAR <= fetch0;
            end
















            out:
            begin
                A23_A0 <= IP;
                IP <= IP + 2;
                MJR <= out1;
                STAR <= readW;
            end


            out1:
            begin
                A23_A0 <= {'H00, APP1, APP0};
                D7_D0 <= AL;
                DIR <= 1;
                STAR <= out2;
            end


            out2:
            begin
                IOW_ <= 0;
                STAR <= out3;
            end


            out3:
            begin
                IOW_ <= 1;
                STAR <= out4;
            end


            out4:
            begin
                DIR <= 0;
                STAR <= fetch0;
            end




















            aluAL:
            begin
                AL <= alu_result(OPCODE, SOURCE, AL);
                F <= {F[7:4], alu_flag(OPCODE, SOURCE, AL)};
                STAR <= fetch0;
            end




















            aluAH:
            begin
                AH <= alu_result(OPCODE, SOURCE, AH);
                F <= {F[7:4], alu_flag(OPCODE, SOURCE, AH)};
                STAR <= fetch0;
            end





















            jmp:
            begin
                IP <= (jmp_condition(OPCODE, F) == 1)? DEST_ADDR : IP;
                STAR <= fetch0;
            end




























            pushAL:
            begin
                A23_A0 <= SP - 1;
                SP <= SP - 1;
                APP0 <= AL;
                MJR <= fetch0;
                STAR <= writeB;
            end



            pushAH:
            begin
                A23_A0 <= SP - 1;
                SP <= SP - 1;
                APP0 <= AH;
                MJR <= fetch0;
                STAR <= writeB;
            end



            pushDP:
            begin
                A23_A0 <= SP - 3;
                SP <= SP - 3;
                {APP2, APP1, APP0} <= DP;
                MJR <= fetch0;
                STAR <= writeM;
            end






            popAL:
            begin
                A23_A0 <= SP;
                SP <= SP + 1;
                MJR <= popAL1;
                STAR <= readB;
            end


            popAL1:
            begin
                AL <= APP0;
                STAR <= fetch0;
            end





            popAH:
            begin
                A23_A0 <= SP;
                SP <= SP + 1;
                MJR <= popAH1;
                STAR <= readB;
            end


            popAH1:
            begin
                AH <= APP0;
                STAR <= fetch0;
            end






            popDP:
            begin
                A23_A0 <= SP;
                SP <= SP + 3;
                MJR <= popDP1;
                STAR <= readM;
            end


            popDP1:
            begin
                DP <= {APP2, APP1, APP0};
                STAR <= fetch0;
            end





            call:
            begin
                A23_A0 <= SP - 3;
                SP <= SP - 3;
                {APP2, APP1, APP0} <= IP;
                MJR <= call1;
                STAR <= writeM;
            end


            call1:
            begin
                IP <= DEST_ADDR;
                STAR <= fetch0;
            end






            ret:
            begin
                A23_A0 <= SP;
                SP <= SP + 3;
                MJR <= ret1;
                STAR <= readM;
            end


            ret1:
            begin
                IP <= {APP2, APP1, APP0};
                STAR <= fetch0;
            end



            nvi:
            begin
                STAR <= nvi;
            end





















            readB:
            begin
                MR_ <= 0;
                DIR <= 0;
                NUMLOC <= 1;
                STAR <= read0;
            end

            readW:
            begin
                MR_ <= 0;
                DIR <= 0;
                NUMLOC <= 2;
                STAR <= read0;
            end

            readM:
            begin
                MR_ <= 0;
                DIR <= 0;
                NUMLOC <= 3;
                STAR <= read0;
            end

            readL:
            begin
                MR_ <= 0;
                DIR <= 0;
                NUMLOC <= 4;
                STAR <= read0;
            end

            read0:
            begin
                APP0 <= d7_d0;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= (NUMLOC == 1)? read4:read1;
            end

            read1:
            begin
                APP1 <= d7_d0;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= (NUMLOC == 1)? read4:read2;
            end

            read2:
            begin
                APP2 <= d7_d0;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= (NUMLOC == 1)? read4:read3;
            end

            read3:
            begin
                APP3 <= d7_d0;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= read4;
            end

            read4:
            begin
                MR_ <= 1;
                STAR <= MJR;
            end





















            writeB:
            begin
                D7_D0 <= APP0;
                DIR <= 1;
                NUMLOC <= 1;
                STAR <= write0;
            end

            writeW:
            begin
                D7_D0 <= APP0;
                DIR <= 1;
                NUMLOC <= 2;
                STAR <= write0;
            end

            writeM:
            begin
                D7_D0 <= APP0;
                DIR <= 1;
                NUMLOC <= 3;
                STAR <= write0;
            end

            writeL:
            begin
                D7_D0 <= APP0;
                DIR <= 1;
                NUMLOC <= 4;
                STAR <= write0;
            end

            write0:
            begin
                MW_ <= 0;
                STAR <= write1;
            end

            write1:
            begin
                MW_ <= 1;
                STAR <= (NUMLOC == 1)? write11:write2;
            end

            write2:
            begin
                D7_D0 <= APP1;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= write3;
            end

            write3:
            begin
                MW_ <= 0;
                STAR <= write4;
            end

            write4:
            begin
                MW_ <= 1;
                STAR <= (NUMLOC == 1)? write11:write5;
            end

            write5:
            begin
				D7_D0 <= APP2;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= write6;
            end

            write6:
            begin
				MW_ <= 0;
                STAR <= write7;
            end

            write7:
            begin
				MW_ <= 1;
                STAR <= (NUMLOC == 1)? write11:write8;
            end

            write8:
            begin
				D7_D0 <= APP3;
                A23_A0 <= A23_A0 + 1;
                STAR <= write9;
            end

            write9:
            begin
                MW_ <= 0;
                STAR <= write10;
            end

            write10:
            begin
                MW_ <= 1;
                STAR <= write11;
            end

            write11:
            begin
                DIR <= 0;
                STAR <= MJR;
            end
        endcase
endmodule
module sEP8(d7_d0, a23_a0, mr_, mw_, ior_, iow_, clock, reset_);

    input           clock, reset_;
    input   [7:0]   d7_d0;
    output  [23:0]  a23_a0;
    output          mr_, mw_;
    output          ior_, iow_;



    reg         DIR;
    reg [7:0]   D7_D0;
    reg [23:0]  A23_A0;
    reg         MR_, MW_, IOR_, IOW_;
    assign      mr_ = MR_;
    assign      mw_ = MW_;
    assign      ior_ = IOR_;
    assign      iow_ = IOW_;
    assign      a23_a0 = A23_A0;
    assign      d7_d0 = (DIR == 1)?D7_D0:'HZZ;


    reg [2:0]   NUMLOC;
    reg [7:0]   AL, AH, F, OPCODE, SOURCE, APP3, APP2, APP1, APP0;
    reg [23:0]  DP, IP, SP, DEST_ADDR;


    reg [6:0]   STAR, MJR;
    parameter fetch0=0,
              fetch1=1,
              fetch2=2,
              fetchF2_0=3,
              fetchF2_1=4,
              fetchF3_0=5,
              fetchF4_0=6,
              fetchF4_1=7,
              fetchF5_0=8,
              fetchF5_1=9,
              fetchF5_2=10,
              fetchF6_0=11,
              fetchF6_1=12,
              fetchF7_0=13,
              fetchF7_1=14,
              fetchEnd=15,
              fetchEnd1=16,
              nop=17,
              hlt=18,
              ALtoAH=19,
              AHtoAL=20,
              incDP=21,
              ldAL=22,
              ldAH=23,
              storeAL=24,
              storeAH=25,
              ldSP=26,
              ldSP1=27,
              ldimmDP=28,
              ldimmDP1=29,
              lddirDP=30,
              lddirDP1=31,
              lddirDP2=32,
              storeDP=33,
              storeDP1=34,
              in=35,
              in1=36,
              in2=37,
              in3=38,
              out=39,
              out1=40,
              out2=41,
              out3=42,
              out4=43,
              aluAL=44,
              aluAH=45,
              jmp=46,
              pushAL=47,
              pushAH=48,
              pushDP=49,
              popAL=50,
              popAL1=51,
              popAH=52,
              popAH1=53,
              popDP=54,
              popDP1=55,
              call=56,
              call1=57,
              ret=58,
              ret1=59,
              nvi=60,
              readB=61,
              readW=62,
              readM=63,
              readL=64,
              read0=65,
              read1=66,
              read2=67,
              read3=68,
              read4=69,
              writeB=70,
              writeW=71,
              writeM=72,
              writeL=73,
              write0=74,
              write1=75,
              write2=76,
              write3=77,
              write4=78,
              write5=79,
              write6=80,
              write7=81,
              write8=82,
              write9=83,
              write10=84,
              write11=85;














    function valid_fetch;
        input [7:0] opcode;
        
        casex(opcode[7:5])
            'B000:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                    'B00110: valid_fetch = 1;
                    'B00111: valid_fetch = 1;
                    'B01000: valid_fetch = 1;
                    'B01001: valid_fetch = 1;
                    'B01010: valid_fetch = 1;
                    'B01011: valid_fetch = 1;
                    'B01111: valid_fetch = 1;
                    'B10000: valid_fetch = 1;
                    'B10001: valid_fetch = 1;
                endcase
            'B001:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                endcase
            'B010:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                    'B00110: valid_fetch = 1;
                    'B00111: valid_fetch = 1;
                    'B01000: valid_fetch = 1;
                    'B01001: valid_fetch = 1;
                    'B01010: valid_fetch = 1;
                    'B01011: valid_fetch = 1;
                endcase
            'B011:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                endcase
            'B100:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                    'B00110: valid_fetch = 1;
                    'B00111: valid_fetch = 1;
                    'B01000: valid_fetch = 1;
                    'B01001: valid_fetch = 1;
                    'B01010: valid_fetch = 1;
                    'B01011: valid_fetch = 1;
                endcase
            'B101:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                    'B00110: valid_fetch = 1;
                    'B00111: valid_fetch = 1;
                    'B01000: valid_fetch = 1;
                    'B01001: valid_fetch = 1;
                    'B01010: valid_fetch = 1;
                    'B01011: valid_fetch = 1;
                endcase
            'B110:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                endcase
            'B111:
                casex(opcode[4:0])
                    'B00000: valid_fetch = 1;
                    'B00001: valid_fetch = 1;
                    'B00010: valid_fetch = 1;
                    'B00011: valid_fetch = 1;
                    'B00100: valid_fetch = 1;
                    'B00101: valid_fetch = 1;
                    'B00110: valid_fetch = 1;
                    'B00111: valid_fetch = 1;
                    'B01000: valid_fetch = 1;
                    'B01001: valid_fetch = 1;
                    'B01010: valid_fetch = 1;
                    'B01011: valid_fetch = 1;
                endcase
        endcase
    endfunction







    function [6:0] first_execution_state;
        input [7:0] opcode;
        casex(opcode)

            'B00000000: first_execution_state = hlt;
            'B00000001: first_execution_state = nop;
            'B00000010: first_execution_state = ALtoAH;
            'B00000011: first_execution_state = AHtoAL;
            'B00000100: first_execution_state = incDP;
            'B00000101: first_execution_state = aluAL;
            'B00000110: first_execution_state = aluAL;
            'B00000111: first_execution_state = aluAL;
            'B00001000: first_execution_state = aluAH;
            'B00001001: first_execution_state = aluAH;
            'B00001010: first_execution_state = aluAH;
			'B00001011: first_execution_state = pushAL;
            'B00001100: first_execution_state = popAL;
            'B00001101: first_execution_state = pushAH;
            'B00001110: first_execution_state = popAH;
            'B00001111: first_execution_state = pushDP;
            'B00010000: first_execution_state = popDP;
            'B00010001: first_execution_state = ret;


            'B00100000: first_execution_state = in;
            'B00100001: first_execution_state = out;
            'B00100010: first_execution_state = ldimmDP;
            'B00100011: first_execution_state = ldSP;
            'B00100100: first_execution_state = lddirDP;
            'B00100101: first_execution_state = storeDP;


            'B01000000: first_execution_state = ldAL;
            'B01000001: first_execution_state = aluAL;
            'B01000010: first_execution_state = aluAL;
            'B01000011: first_execution_state = aluAL;
            'B01000100: first_execution_state = aluAL;
            'B01000101: first_execution_state = aluAL;
            'B01000110: first_execution_state = ldAH;
            'B01000111: first_execution_state = aluAH;
            'B01001000: first_execution_state = aluAH;
            'B01001001: first_execution_state = aluAH;
            'B01001010: first_execution_state = aluAH;
            'B01001011: first_execution_state = aluAH;


            'B01100000: first_execution_state = storeAL;
            'B01100001: first_execution_state = storeAH;


            'B10000000: first_execution_state = ldAL;
            'B10000001: first_execution_state = aluAH;
            'B10000010: first_execution_state = aluAL;
            'B10000011: first_execution_state = aluAL;
            'B10000100: first_execution_state = aluAL;
            'B10000101: first_execution_state = aluAL;
            'B10000110: first_execution_state = ldAH;
            'B10000111: first_execution_state = aluAH;
            'B10001000: first_execution_state = aluAH;
            'B10001001: first_execution_state = aluAH;
            'B10001010: first_execution_state = aluAH;
            'B10001011: first_execution_state = aluAH;


			'B10100000: first_execution_state = ldAL;
            'B10100001: first_execution_state = aluAL;
            'B10100010: first_execution_state = aluAL;
            'B10100011: first_execution_state = aluAL;
            'B10100100: first_execution_state = aluAL;
            'B10100101: first_execution_state = aluAL;
            'B10100110: first_execution_state = ldAH;
            'B10100111: first_execution_state = aluAH;
            'B10101000: first_execution_state = aluAH;
            'B10101001: first_execution_state = aluAH;
            'B10101010: first_execution_state = aluAH;
            'B10101011: first_execution_state = aluAH;


            'B11000000: first_execution_state = storeAL;
            'B11000001: first_execution_state = storeAH;


            'B11100000: first_execution_state = jmp;
            'B11100001: first_execution_state = jmp;
            'B11100010: first_execution_state = jmp;
            'B11100011: first_execution_state = jmp;
            'B11100100: first_execution_state = jmp;
            'B11100101: first_execution_state = jmp;
            'B11100110: first_execution_state = jmp;
            'B11100111: first_execution_state = jmp;
            'B11101000: first_execution_state = jmp;
            'B11101001: first_execution_state = jmp;
            'B11101010: first_execution_state = jmp;
            'B11101011: first_execution_state = jmp;
            'B11101100: first_execution_state = jmp;
            'B11101101: first_execution_state = jmp;
            'B11101110: first_execution_state = jmp;
            'B11101111: first_execution_state = jmp;
            'B11110000: first_execution_state = jmp;
            'B11110001: first_execution_state = jmp;
            'B11110010: first_execution_state = jmp;
            'B11110011: first_execution_state = call;
        endcase
    endfunction











    function jmp_condition;
        input [7:0] opcode;
        input [7:0] flag;
        jmp_condition = 0;


    endfunction












    function [7:0] alu_result;
        input [7:0] opcode, operando1, operando2;
        alu_result = 'B00000000;


    endfunction






    function [3:0] alu_flag;
        input [7:0] opcode, operando1, operando2;
        alu_flag = 'B0000;


    endfunction


    parameter [2:0] F0 = 'B000, F1 = 'B001, F2 = 'B010, F3 = 'B011,
                    F4 = 'B100, F5 = 'B101, F6 = 'B110, F7 = 'B111;



    always @(reset_ == 0) #1
        begin
            IP <= 'HFF0000;
            F <= 'H00;
            DIR <= 0;
            MR_ <= 1;
            MW_ <= 1;
            IOR_ <= 1;
            IOW_ <= 1;
            STAR <= fetch0;
        end



    always @(posedge clock) if (reset_ == 1) #3
        casex(STAR)




            fetch0:
            begin
                A23_A0 <= IP;
                IP <= IP + 1;
                MJR <= fetch1;
                STAR <= readB;
            end



            fetch1:
            begin
                OPCODE <= APP0;

                MJR <= (APP0[7:5] == F0)? fetchEnd:
                       (APP0[7:5] == F1)? fetchEnd:
                       (APP0[7:5] == F2)? fetchF2_0:
                       (APP0[7:5] == F3)? fetchF3_0:
                       (APP0[7:5] == F4)? fetchF4_0:
                       (APP0[7:5] == F5)? fetchF5_0:
                       (APP0[7:5] == F6)? fetchF6_0:
fetchF7_0;

                STAR <= (valid_fetch(APP0) == 1)? fetch2:nvi;
            end



            fetch2:
            begin
                STAR <= MJR;
            end





            fetchF2_0:
            begin
                A23_A0 <= DP;
                MJR <= fetchF2_1;
                STAR <= readB;
            end


            fetchF2_1:
            begin
                SOURCE <= APP0;
                STAR <= fetchEnd;
            end






            fetchF3_0:
            begin
                DEST_ADDR <= DP;
                STAR <= fetchEnd;
            end





            fetchF4_0:
            begin
                A23_A0 <= IP;
                IP <= IP + 1;
                MJR <= fetchF4_1;
                STAR <= readB;
            end


            fetchF4_1:
            begin
                SOURCE <= APP0;
                STAR <= fetchEnd;
            end






            fetchF5_0:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= fetchF5_1;
                STAR <= readM;
            end


            fetchF5_1:
            begin
                A23_A0 <= {APP2, APP1, APP0};
                MJR <= fetchF5_2;
                STAR <= readB;
            end


            fetchF5_2:
            begin
                SOURCE <= APP0;
                STAR <= fetchEnd;
            end






            fetchF6_0:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= fetchF6_1;
                STAR <= readM;
            end



            fetchF6_1:
            begin
                DEST_ADDR <= {APP2, APP1, APP0};
                STAR <= fetchEnd;
            end





            fetchF7_0:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= fetchF7_1;
                STAR <= readM;
            end


            fetchF7_1:
            begin
                DEST_ADDR <= {APP2, APP1, APP0};
                STAR <= fetchEnd;
            end




            fetchEnd:
            begin
                MJR <= first_execution_state(OPCODE);
                STAR <= fetchEnd1;
            end

            fetchEnd1:
            begin
                STAR <= MJR;
            end



            











            hlt:
            begin
                STAR <= hlt;
            end






            nop:
            begin
                STAR <= fetch0;
            end



            ALtoAH:
            begin
                AH <= AL;
                STAR <= fetch0;
            end



            AHtoAL:
            begin
                AL <= AH;
                STAR <= fetch0;
            end



            incDP:
            begin
                DP <= DP + 1;
                STAR <= fetch0;
            end





            ldAL:
            begin
                AL <= SOURCE;
                STAR <= fetch0;
            end





            ldAH:
            begin
                AH <= SOURCE;
                STAR <= fetch0;
            end




            storeAL:
            begin
                A23_A0 <= DEST_ADDR;
                APP0 <= AL;
                MJR <= fetch0;
                STAR <= writeB;
            end




            storeAH:
            begin
                A23_A0 <= DEST_ADDR;
                APP0 <= AH;
                MJR <= fetch0;
                STAR <= writeB;
            end




            ldSP:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= ldSP1;
                STAR <= readM;
            end


            ldSP1:
            begin
                SP <= {APP2, APP1, APP0};
                STAR <= fetch0;
            end




            ldimmDP:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= ldimmDP1;
                STAR <= readM;
            end


            ldimmDP1:
            begin
                DP <= {APP2, APP1, APP0};
                STAR <= fetch0;
            end






            lddirDP:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= lddirDP1;
                STAR <= readM;
            end



            lddirDP1:
            begin
                A23_A0 <= {APP2, APP1, APP0};
                MJR <= lddirDP2;
                STAR <= readM;
            end


            lddirDP2:
            begin
                DP <= {APP2, APP1, APP0};
                STAR <= fetch0;
            end






            storeDP:
            begin
                A23_A0 <= IP;
                IP <= IP + 3;
                MJR <= storeDP1;
                STAR <= readM;
            end



            storeDP1:
            begin
                A23_A0 <= {APP2, APP1, APP0};
                {APP2, APP1, APP0} <= DP;
                MJR <= fetch0;
                STAR <= writeM;
            end
            


















            in:
            begin
                A23_A0 <= IP;
                IP <= IP + 2;
                MJR <= in1;
                STAR <= readW;
            end


            in1:
            begin
                A23_A0 <= {'H00, APP1, APP0};
                STAR <= in2;
            end


            in2:
            begin
                IOR_ <= 0;
                STAR <= in3;
            end


            in3:
            begin
                AL <= d7_d0;
                IOR_ <= 1;
                STAR <= fetch0;
            end
















            out:
            begin
                A23_A0 <= IP;
                IP <= IP + 2;
                MJR <= out1;
                STAR <= readW;
            end


            out1:
            begin
                A23_A0 <= {'H00, APP1, APP0};
                D7_D0 <= AL;
                DIR <= 1;
                STAR <= out2;
            end


            out2:
            begin
                IOW_ <= 0;
                STAR <= out3;
            end


            out3:
            begin
                IOW_ <= 1;
                STAR <= out4;
            end


            out4:
            begin
                DIR <= 0;
                STAR <= fetch0;
            end




















            aluAL:
            begin
                AL <= alu_result(OPCODE, SOURCE, AL);
                F <= {F[7:4], alu_flag(OPCODE, SOURCE, AL)};
                STAR <= fetch0;
            end




















            aluAH:
            begin
                AH <= alu_result(OPCODE, SOURCE, AH);
                F <= {F[7:4], alu_flag(OPCODE, SOURCE, AH)};
                STAR <= fetch0;
            end





















            jmp:
            begin
                IP <= (jmp_condition(OPCODE, F) == 1)? DEST_ADDR : IP;
                STAR <= fetch0;
            end




























            pushAL:
            begin
                A23_A0 <= SP - 1;
                SP <= SP - 1;
                APP0 <= AL;
                MJR <= fetch0;
                STAR <= writeB;
            end



            pushAH:
            begin
                A23_A0 <= SP - 1;
                SP <= SP - 1;
                APP0 <= AH;
                MJR <= fetch0;
                STAR <= writeB;
            end



            pushDP:
            begin
                A23_A0 <= SP - 3;
                SP <= SP - 3;
                {APP2, APP1, APP0} <= DP;
                MJR <= fetch0;
                STAR <= writeM;
            end






            popAL:
            begin
                A23_A0 <= SP;
                SP <= SP + 1;
                MJR <= popAL1;
                STAR <= readB;
            end


            popAL1:
            begin
                AL <= APP0;
                STAR <= fetch0;
            end





            popAH:
            begin
                A23_A0 <= SP;
                SP <= SP + 1;
                MJR <= popAH1;
                STAR <= readB;
            end


            popAH1:
            begin
                AH <= APP0;
                STAR <= fetch0;
            end






            popDP:
            begin
                A23_A0 <= SP;
                SP <= SP + 3;
                MJR <= popDP1;
                STAR <= readM;
            end


            popDP1:
            begin
                DP <= {APP2, APP1, APP0};
                STAR <= fetch0;
            end





            call:
            begin
                A23_A0 <= SP - 3;
                SP <= SP - 3;
                {APP2, APP1, APP0} <= IP;
                MJR <= call1;
                STAR <= writeM;
            end


            call1:
            begin
                IP <= DEST_ADDR;
                STAR <= fetch0;
            end






            ret:
            begin
                A23_A0 <= SP;
                SP <= SP + 3;
                MJR <= ret1;
                STAR <= readM;
            end


            ret1:
            begin
                IP <= {APP2, APP1, APP0};
                STAR <= fetch0;
            end



            nvi:
            begin
                STAR <= nvi;
            end





















            readB:
            begin
                MR_ <= 0;
                DIR <= 0;
                NUMLOC <= 1;
                STAR <= read0;
            end

            readW:
            begin
                MR_ <= 0;
                DIR <= 0;
                NUMLOC <= 2;
                STAR <= read0;
            end

            readM:
            begin
                MR_ <= 0;
                DIR <= 0;
                NUMLOC <= 3;
                STAR <= read0;
            end

            readL:
            begin
                MR_ <= 0;
                DIR <= 0;
                NUMLOC <= 4;
                STAR <= read0;
            end

            read0:
            begin
                APP0 <= d7_d0;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= (NUMLOC == 1)? read4:read1;
            end

            read1:
            begin
                APP1 <= d7_d0;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= (NUMLOC == 1)? read4:read2;
            end

            read2:
            begin
                APP2 <= d7_d0;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= (NUMLOC == 1)? read4:read3;
            end

            read3:
            begin
                APP3 <= d7_d0;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= read4;
            end

            read4:
            begin
                MR_ <= 1;
                STAR <= MJR;
            end





















            writeB:
            begin
                D7_D0 <= APP0;
                DIR <= 1;
                NUMLOC <= 1;
                STAR <= write0;
            end

            writeW:
            begin
                D7_D0 <= APP0;
                DIR <= 1;
                NUMLOC <= 2;
                STAR <= write0;
            end

            writeM:
            begin
                D7_D0 <= APP0;
                DIR <= 1;
                NUMLOC <= 3;
                STAR <= write0;
            end

            writeL:
            begin
                D7_D0 <= APP0;
                DIR <= 1;
                NUMLOC <= 4;
                STAR <= write0;
            end

            write0:
            begin
                MW_ <= 0;
                STAR <= write1;
            end

            write1:
            begin
                MW_ <= 1;
                STAR <= (NUMLOC == 1)? write11:write2;
            end

            write2:
            begin
                D7_D0 <= APP1;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= write3;
            end

            write3:
            begin
                MW_ <= 0;
                STAR <= write4;
            end

            write4:
            begin
                MW_ <= 1;
                STAR <= (NUMLOC == 1)? write11:write5;
            end

            write5:
            begin
				D7_D0 <= APP2;
                A23_A0 <= A23_A0 + 1;
                NUMLOC <= NUMLOC - 1;
                STAR <= write6;
            end

            write6:
            begin
				MW_ <= 0;
                STAR <= write7;
            end

            write7:
            begin
				MW_ <= 1;
                STAR <= (NUMLOC == 1)? write11:write8;
            end

            write8:
            begin
				D7_D0 <= APP3;
                A23_A0 <= A23_A0 + 1;
                STAR <= write9;
            end

            write9:
            begin
                MW_ <= 0;
                STAR <= write10;
            end

            write10:
            begin
                MW_ <= 1;
                STAR <= write11;
            end

            write11:
            begin
                DIR <= 0;
                STAR <= MJR;
            end
        endcase
endmodule