data/full_repos/permissive/174323821/hdl/cpu/j68/j68_decode.v
 line:82: before: "LONG"
1: b"%Error: data/full_repos/permissive/174323821/hdl/cpu/j68/j68_decode.v:335: Cannot find file containing module: 'j68_decode_rom'\n    j68_decode_rom\n    ^~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/174323821/hdl/cpu/j68,data/full_repos/permissive/174323821/j68_decode_rom\n             data/full_repos/permissive/174323821/hdl/cpu/j68,data/full_repos/permissive/174323821/j68_decode_rom.v\n             data/full_repos/permissive/174323821/hdl/cpu/j68,data/full_repos/permissive/174323821/j68_decode_rom.sv\n             j68_decode_rom\n             j68_decode_rom.v\n             j68_decode_rom.sv\n             obj_dir/j68_decode_rom\n             obj_dir/j68_decode_rom.v\n             obj_dir/j68_decode_rom.sv\n%Error: Exiting due to 1 error(s)\n"
module j68_decode
(
    input             rst,
    input             clk,
    input             clk_ena,
    input             ins_rdy,
    input      [15:0] instr,
    input             ext_rdy,
    input      [15:0] ext_wd,
    input             imm_rdy,
    input      [15:0] imm_wd,
    input             user_mode,
    input      [3:0]  ccr_in,
    output     [11:0] dec_jmp,
    output     [3:0]  ea1_jmp,
    output     [3:0]  ea2_jmp,
    output reg [15:0] imm_val,
    output     [15:0] ea1_bit,
    output reg        cc_jmp,
    output            ext_inst,
    output            bit_inst,
    output            vld_inst
);
    parameter USE_CLK_ENA = 0;
    

    localparam [11:0] OP_PRIVILEDGED = (USE_CLK_ENA) ? 12'h038 : 12'h039;
    localparam [11:0] OP_ILLEGAL     = (USE_CLK_ENA) ? 12'h03A : 12'h03B;
  


















































  

    wire [15:0] w_grp_p0;
    

    wire [15:0] w_ea1b_p0;
    reg  [15:0] r_ea1b_p1;
    wire [9:0]  w_ea2b_p0;
    

    wire [3:0]  w_ea1_jmp_p0;
    reg  [3:0]  r_ea1_jmp_p1;

    wire [3:0]  w_ea2_jmp_p0;
    reg  [3:0]  r_ea2_jmp_p1;

    

    wire        w_g0_immed_p0;
    wire        w_g0_bitimm_p0;
    wire        w_g0_bitop_p0;
    wire        w_g4_misc_p0;
    wire        w_g4_oneop_p0;
    wire        w_g4_twoop_p0;
    wire        w_g5_addsub_p0;
    wire        w_g6_bsr_p0;
    wire        w_gE_shmem_p0;
    wire        w_gE_shreg_p0;
    

    wire        w_g4_nbcd_p0;
    wire        w_g8_sbcd_p0;
    wire        w_gC_abcd_p0;
    wire        w_g4_negx_p0;
    wire        w_g9_subx_p0;
    wire        w_gD_addx_p0;
    

    wire        w_ill_ins_p0;
    reg         r_ill_ins_p1;
    wire        w_prv_ins_p0;
    reg         r_prv_ins_p1;
    wire        w_ext_ins_p0;
    reg         r_ext_ins_p1;

    wire        w_bit_ins_p0;
    reg         r_bit_ins_p1;

    reg         w_vld_ins_p1;
    reg         r_vld_ins_p2;
    

    wire        w_call1_ena_p0;
    wire        w_call2_ena_p0;
    reg  [1:0]  r_call_en_p1;
    reg  [11:0] r_call_p2;
    

    wire [5:0]  w_idx6_5_0_p0;
    wire [5:0]  w_idx5_B_6_p0;
    wire [5:0]  w_idx4_8_3_p0;
    wire [5:0]  w_idx4_F_C_p0;
    wire [5:0]  w_idx3_8_6_p0;
    wire [5:0]  w_idx3_A_8_p0;
    wire [5:0]  w_idx2_7_6_p0;
    

    wire [7:0]  w_addr_p0;
    wire [35:0] w_data_p1;
    reg  [15:0] w_ea1m_p1;
    reg  [5:0]  w_incr_p1;
    reg  [11:0] w_call_p1;
    

    wire [15:0] w_imm3_i;
    wire [15:0] w_imm4_i;
    wire [15:0] w_imm8_i;
    wire [15:0] w_imm5_e;
    wire [15:0] w_imm8_e;
    

    assign w_grp_p0[0]    = (instr[15:12] == 4'b0000) ? 1'b1 : 1'b0;
    assign w_grp_p0[1]    = (instr[15:12] == 4'b0001) ? 1'b1 : 1'b0;
    assign w_grp_p0[2]    = (instr[15:12] == 4'b0010) ? 1'b1 : 1'b0;
    assign w_grp_p0[3]    = (instr[15:12] == 4'b0011) ? 1'b1 : 1'b0;
    assign w_grp_p0[4]    = (instr[15:12] == 4'b0100) ? 1'b1 : 1'b0;
    assign w_grp_p0[5]    = (instr[15:12] == 4'b0101) ? 1'b1 : 1'b0;
    assign w_grp_p0[6]    = (instr[15:12] == 4'b0110) ? 1'b1 : 1'b0;
    assign w_grp_p0[7]    = (instr[15:12] == 4'b0111) ? 1'b1 : 1'b0;
    assign w_grp_p0[8]    = (instr[15:12] == 4'b1000) ? 1'b1 : 1'b0;
    assign w_grp_p0[9]    = (instr[15:12] == 4'b1001) ? 1'b1 : 1'b0;
    assign w_grp_p0[10]   = (instr[15:12] == 4'b1010) ? 1'b1 : 1'b0;
    assign w_grp_p0[11]   = (instr[15:12] == 4'b1011) ? 1'b1 : 1'b0;
    assign w_grp_p0[12]   = (instr[15:12] == 4'b1100) ? 1'b1 : 1'b0;
    assign w_grp_p0[13]   = (instr[15:12] == 4'b1101) ? 1'b1 : 1'b0;
    assign w_grp_p0[14]   = (instr[15:12] == 4'b1110) ? 1'b1 : 1'b0;
    assign w_grp_p0[15]   = (instr[15:12] == 4'b1111) ? 1'b1 : 1'b0;
    

    assign w_ea1b_p0[15]  = (instr[5:0] == 6'b111111) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[14]  = (instr[5:0] == 6'b111110) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[13]  = (instr[5:0] == 6'b111101) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[12]  = (instr[5:0] == 6'b111100) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[11]  = (instr[5:0] == 6'b111011) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[10]  = (instr[5:0] == 6'b111010) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[9]   = (instr[5:0] == 6'b111001) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[8]   = (instr[5:0] == 6'b111000) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[7]   = (instr[5:4] == 2'b00)     ? 1'b1 : 1'b0;
    assign w_ea1b_p0[6]   = (instr[5:3] == 3'b110)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[5]   = (instr[5:3] == 3'b101)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[4]   = (instr[5:3] == 3'b100)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[3]   = (instr[5:3] == 3'b011)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[2]   = (instr[5:3] == 3'b010)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[1]   = (instr[5:3] == 3'b001)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[0]   = (instr[5:3] == 3'b000)    ? 1'b1 : 1'b0;
    

    assign w_ea2b_p0[9]   = (instr[8:6]  == 3'b111) 
                         && (instr[11:10] != 2'b00)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[8]   = (instr[11:6] == 6'b001111) ? 1'b1 : 1'b0;
    assign w_ea2b_p0[7]   = (instr[11:6] == 6'b000111) ? 1'b1 : 1'b0;
    assign w_ea2b_p0[6]   = (instr[8:6]  == 3'b110)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[5]   = (instr[8:6]  == 3'b101)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[4]   = (instr[8:6]  == 3'b100)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[3]   = (instr[8:6]  == 3'b011)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[2]   = (instr[8:6]  == 3'b010)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[1]   = (instr[8:6]  == 3'b001)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[0]   = (instr[8:6]  == 3'b000)    ? 1'b1 : 1'b0;
    

    assign w_ea1_jmp_p0[3]   = (instr[5:3] == 3'b111) ? 1'b1 : 1'b0;
    assign w_ea1_jmp_p0[2:0] = (instr[5:3] == 3'b111) ? instr[2:0] : instr[5:3];
    assign w_ea2_jmp_p0[3]   = (instr[8:6] == 3'b111) ? 1'b1 : 1'b0;
    assign w_ea2_jmp_p0[2:0] = (instr[8:6] == 3'b111) ? instr[11:9] : instr[8:6];
    

    assign w_g0_immed_p0  = w_grp_p0[0]  &  ~instr[8];
    assign w_g0_bitimm_p0 = (instr[15:8] == 8'b0000_1000) ? 1'b1 : 1'b0;
    assign w_g0_bitop_p0  = w_grp_p0[0]  &   instr[8];
    assign w_g4_misc_p0   = (instr[15:6] == 10'b0100_111_001) ? 1'b1 : 1'b0;
    assign w_g4_oneop_p0  = w_grp_p0[4]  &  ~instr[8] & ~w_g4_misc_p0;
    assign w_g4_twoop_p0  = w_grp_p0[4]  &   instr[8];
    assign w_g5_addsub_p0 = w_grp_p0[5]  & ~(instr[7] & instr[6]);
    assign w_g6_bsr_p0    = (instr[11:8] == 4'b0001) ? 1'b1 : 1'b0;
    assign w_gE_shmem_p0  = w_grp_p0[14] &   instr[7] & instr[6];
    assign w_gE_shreg_p0  = w_grp_p0[14] & ~(instr[7] & instr[6]);
    

    assign w_g4_nbcd_p0   = (w_grp_p0[4])  && (instr[11:6] == 6'b100000) ? 1'b1 : 1'b0;
    assign w_g8_sbcd_p0   = (w_grp_p0[8])  &&  (instr[8:4] == 5'b10000)  ? 1'b1 : 1'b0;
    assign w_gC_abcd_p0   = (w_grp_p0[12]) &&  (instr[8:4] == 5'b10000)  ? 1'b1 : 1'b0;
    assign w_g4_negx_p0   = (w_grp_p0[4])  && (instr[11:8] == 4'b0000)   ? 1'b1 : 1'b0;
    assign w_g9_subx_p0   = (w_grp_p0[9])  && ((instr[8:4] == 5'b10000) ||
                                               (instr[8:4] == 5'b10100) ||
                                               (instr[8:4] == 5'b11000)) ? 1'b1 : 1'b0;
    assign w_gD_addx_p0   = (w_grp_p0[13]) && ((instr[8:4] == 5'b10000) ||
                                               (instr[8:4] == 5'b10100) ||
                                               (instr[8:4] == 5'b11000)) ? 1'b1 : 1'b0;
    assign w_ext_ins_p0   = w_g4_negx_p0 | w_g9_subx_p0 | w_gD_addx_p0
                          | w_g4_nbcd_p0 | w_g8_sbcd_p0 | w_gC_abcd_p0;
    

    assign w_bit_ins_p0   = w_g0_bitop_p0 | w_g0_bitimm_p0;
    

    assign w_ill_ins_p0   = (w_grp_p0[1]  & w_ea2b_p0[1])
                          | (w_grp_p0[1]  & w_ea2b_p0[9])
                          | (w_grp_p0[2]  & w_ea2b_p0[9])
                          | (w_grp_p0[3]  & w_ea2b_p0[9])
                          | (w_grp_p0[7]  & instr[8])
                          | (w_grp_p0[14] & instr[11] & instr[7] & instr[6]);

    assign w_prv_ins_p0   = ((w_grp_p0[0])  && (instr[6]) && (w_ea1b_p0[12]))
                         || ((w_g4_misc_p0) && ((instr[5:4] == 2'b10) ||
                                                (instr[5:0] == 6'b110000) ||
                                                (instr[6:1] == 6'b11001)))
                         || ((w_grp_p0[4])  && (instr[11:6] == 6'b011011))
                         ? user_mode : 1'b0;
    

    assign w_call1_ena_p0 = (w_grp_p0[0]  & w_ea1b_p0[0])
                          | (w_grp_p0[2]  & w_ea2b_p0[1])
                          | (w_grp_p0[3]  & w_ea2b_p0[1])
                          | (w_grp_p0[4]  & ~w_g4_misc_p0 & w_ea1b_p0[0])
                          | (w_grp_p0[6]  & w_g6_bsr_p0)
                          | (w_grp_p0[8]  & w_ea1b_p0[0])
                          | (w_grp_p0[9]  & w_ea1b_p0[0])
                          | (w_grp_p0[12] & w_ea1b_p0[0])
                          | (w_grp_p0[13] & w_ea1b_p0[0]);

    assign w_call2_ena_p0 = (w_grp_p0[0]  & ~instr[8]     & w_ea1b_p0[12])
                          | (w_grp_p0[0]  & instr[8]      & w_ea1b_p0[1])
                          | (w_grp_p0[4]  & ~w_g4_misc_p0 & w_ea1b_p0[3])
                          | (w_grp_p0[4]  & ~w_g4_misc_p0 & w_ea1b_p0[4])
                          | (w_grp_p0[5]  & w_ea1b_p0[1])
                          | (w_grp_p0[8]  & w_ea1b_p0[1])
                          | (w_grp_p0[9]  & w_ea1b_p0[1])
                          | (w_grp_p0[11] & w_ea1b_p0[1])
                          | (w_grp_p0[12] & w_ea1b_p0[1])
                          | (w_grp_p0[13] & w_ea1b_p0[1]);
    

    assign w_idx6_5_0_p0  = (w_g4_misc_p0)
                          ? instr[5:0]
                          : 6'b000000;
    assign w_idx5_B_6_p0  = (w_g0_immed_p0 | w_g4_oneop_p0)
                          ? { instr[14], instr[11:9], instr[7:6] }
                          : 6'b000000;
    assign w_idx4_8_3_p0  = (w_gE_shreg_p0)
                          ? { instr[7:6], instr[8], instr[5:3] }
                          : 6'b000000;
    assign w_idx4_F_C_p0  = (w_grp_p0[1] | w_grp_p0[2] | w_grp_p0[3] | w_grp_p0[6] | w_grp_p0[7] | w_grp_p0[10] | w_grp_p0[15])
                          ? { 2'b11, instr[15:12] }
                          : 6'b000000;                    
    assign w_idx3_8_6_p0  = (w_grp_p0[5] | w_grp_p0[8] | w_grp_p0[9] | w_grp_p0[11] | w_grp_p0[12] | w_grp_p0[13])
                          ? { instr[14] ^ ~instr[15], instr[13] ^ ~instr[15], instr[12] ^ ~instr[15], instr[8:6] }
                          : 6'b000000;
    assign w_idx3_A_8_p0  = (w_gE_shmem_p0)
                          ? { 3'b110, instr[10:8] }
                          : 6'b000000;
    assign w_idx2_7_6_p0  = (w_g0_bitop_p0 | w_g4_twoop_p0)
                          ? { 3'b111, instr[14], instr[7:6] }
                          : 6'b000000;
    

    assign w_addr_p0[7]   = ((instr[12]   | instr[13]) & ~instr[15])
                          | instr[15]     | w_g0_bitop_p0 | w_g4_twoop_p0;
    assign w_addr_p0[6]   = w_grp_p0[5]   | w_grp_p0[8]   | w_grp_p0[9]
                          | w_grp_p0[11]  | w_grp_p0[12]  | w_grp_p0[13]
                          | w_g0_immed_p0 | w_g0_bitop_p0 | w_g4_oneop_p0
                          | w_g4_twoop_p0 | w_gE_shmem_p0;
    assign w_addr_p0[5:0] = w_idx6_5_0_p0 | w_idx5_B_6_p0 | w_idx4_8_3_p0
                          | w_idx4_F_C_p0 | w_idx3_8_6_p0 | w_idx3_A_8_p0
                          | w_idx2_7_6_p0;
    

    j68_decode_rom
    #(
        .USE_CLK_ENA (USE_CLK_ENA)
    )
    U_decode_rom
    (
        .clock       (clk),
        .address     (w_addr_p0),
        .q           (w_data_p1)
    );
    
    always@(*) begin
    

        case (w_data_p1[11:8])
            4'b0000 : w_ea1m_p1 = 16'b000_00000_00000000;
            4'b0001 : w_ea1m_p1 = 16'b000_00011_01110101;
            4'b0010 : w_ea1m_p1 = 16'b000_00011_01111100;
            4'b0011 : w_ea1m_p1 = 16'b000_00011_01111101;
            4'b0100 : w_ea1m_p1 = 16'b000_00011_01111110;
            4'b0101 : w_ea1m_p1 = 16'b000_00011_01111111;
            4'b0110 : w_ea1m_p1 = 16'b000_01111_01001101;
            4'b0111 : w_ea1m_p1 = 16'b000_01111_01100100;
            4'b1000 : w_ea1m_p1 = 16'b000_01111_01100101;
            4'b1001 : w_ea1m_p1 = 16'b000_01111_01101100;
            4'b1010 : w_ea1m_p1 = 16'b000_01111_01111101;
            4'b1011 : w_ea1m_p1 = 16'b000_10011_01111101;
            4'b1100 : w_ea1m_p1 = 16'b000_11111_01111101;
            4'b1101 : w_ea1m_p1 = 16'b000_11111_01111111;
            default : w_ea1m_p1 = 16'b111_11111_01111111;
        endcase

        w_incr_p1 = (w_data_p1[23:18] & {6{r_call_en_p1[0]}})
                  | (w_data_p1[17:12] & {6{r_call_en_p1[1]}});

        if (((w_ea1m_p1 & r_ea1b_p1) == 16'h0000) || (r_ill_ins_p1)) begin

            w_call_p1    = OP_ILLEGAL;
            w_vld_ins_p1 = 1'b0;
        end
        else if (r_prv_ins_p1) begin

            w_call_p1    = OP_PRIVILEDGED;
            w_vld_ins_p1 = 1'b1;
        end
        else begin

            w_call_p1    = w_data_p1[35:24] + { 6'b000000, w_incr_p1 };
            w_vld_ins_p1 = 1'b1;
        end
    end


    always @(posedge rst or posedge clk) begin : DECODE_P1_P2
    
        if (rst) begin
            r_ea1_jmp_p1 <= 4'b0000;
            r_ea2_jmp_p1 <= 4'b0000;
            r_ill_ins_p1 <= 1'b0;
            r_prv_ins_p1 <= 1'b0;
            r_ext_ins_p1 <= 1'b0;
            r_bit_ins_p1 <= 1'b0;
            r_call_en_p1 <= 2'b00;
            r_ea1b_p1    <= 16'b0000000_00000000;      
            


            r_vld_ins_p2 <= 1'b0;


            r_call_p2    <= 12'h000;
        end
        else if (clk_ena) begin

            r_ea1_jmp_p1 <= w_ea1_jmp_p0;
            r_ea2_jmp_p1 <= w_ea2_jmp_p0;
            r_ill_ins_p1 <= w_ill_ins_p0;
            r_prv_ins_p1 <= w_prv_ins_p0;
            r_ext_ins_p1 <= w_ext_ins_p0;
            r_bit_ins_p1 <= w_bit_ins_p0;
            r_call_en_p1 <= { w_call2_ena_p0, w_call1_ena_p0 };
            r_ea1b_p1    <= w_ea1b_p0;



            r_vld_ins_p2 <= w_vld_ins_p1;


            r_call_p2    <= w_call_p1;
        end
    end
  
    assign vld_inst = r_vld_ins_p2;
    assign ext_inst = r_ext_ins_p1;
    assign bit_inst = r_bit_ins_p1;
    assign dec_jmp  = r_call_p2;
    assign ea1_jmp  = r_ea1_jmp_p1;
    assign ea2_jmp  = r_ea2_jmp_p1;
    assign ea1_bit  = r_ea1b_p1;



    assign w_imm3_i[15:4] = 12'h000;
    assign w_imm3_i[3]    = (instr[11:9] == 3'b000) ? (w_g5_addsub_p0 | (w_gE_shreg_p0 & ~instr[5])) : 1'b0;
    assign w_imm3_i[2:0]  = (w_g5_addsub_p0 | (w_gE_shreg_p0 & ~instr[5])) ? instr[11:9] : 3'b000;

    assign w_imm4_i[15:8] = 8'h00;
    assign w_imm4_i[7:0]  = (w_g4_misc_p0) ? {2'b10, instr[3:0], 2'b00} : 8'h00;

    assign w_imm8_i[15:8] = (w_grp_p0[6] | (w_grp_p0[7] & ~instr[8])) ? {8{instr[7]}} : 8'h00;
    assign w_imm8_i[7:0]  = (w_grp_p0[6] | (w_grp_p0[7] & ~instr[8])) ? instr[7:0] : 8'h00;



    assign w_imm5_e[15:5] = 11'b0;
    assign w_imm5_e[4:0]  = ext_wd[4:0];

    assign w_imm8_e[15:8] = {8{ext_wd[7]}};
    assign w_imm8_e[7:0]  = ext_wd[7:0];


    always @(posedge rst or posedge clk) begin : IMMED_VAL
    
        if (rst) begin
            imm_val <= 16'h0000;
        end
        else if (clk_ena) begin
            if (ins_rdy) imm_val <= w_imm3_i | w_imm4_i | w_imm8_i;
            if (ext_rdy) begin
                if (w_g0_bitimm_p0) begin
                    imm_val <= w_imm5_e;
                end
                else begin
                    imm_val <= w_imm8_e;
                end
            end
            if (imm_rdy) imm_val <= imm_wd;
        end
    end
  

    always @(posedge rst or posedge clk) begin : CC_JUMP_FLAG
    
        if (rst) begin
            cc_jmp <= 1'b0;
        end
        else if (clk_ena) begin
            case (instr[11:8])
                4'b0000 : cc_jmp <= 1'b1;
                4'b0001 : cc_jmp <= 1'b0;
                4'b0010 : cc_jmp <= ~(ccr_in[0] | ccr_in[2]);
                4'b0011 : cc_jmp <=   ccr_in[0] | ccr_in[2];
                4'b0100 : cc_jmp <= ~ ccr_in[0];
                4'b0101 : cc_jmp <=   ccr_in[0];
                4'b0110 : cc_jmp <= ~ ccr_in[2];
                4'b0111 : cc_jmp <=   ccr_in[2];
                4'b1000 : cc_jmp <= ~ ccr_in[1];
                4'b1001 : cc_jmp <=   ccr_in[1];
                4'b1010 : cc_jmp <= ~ ccr_in[3];
                4'b1011 : cc_jmp <=   ccr_in[3];
                4'b1100 : cc_jmp <= ~(ccr_in[1] ^ ccr_in[3]);
                4'b1101 : cc_jmp <=   ccr_in[1] ^ ccr_in[3];
                4'b1110 : cc_jmp <= ~((ccr_in[1] ^ ccr_in[3]) | ccr_in[2]);
                4'b1111 : cc_jmp <=   (ccr_in[1] ^ ccr_in[3]) | ccr_in[2];
            endcase
        end
    end
  
endmodule
module j68_decode
(
    input             rst,
    input             clk,
    input             clk_ena,
    input             ins_rdy,
    input      [15:0] instr,
    input             ext_rdy,
    input      [15:0] ext_wd,
    input             imm_rdy,
    input      [15:0] imm_wd,
    input             user_mode,
    input      [3:0]  ccr_in,
    output     [11:0] dec_jmp,
    output     [3:0]  ea1_jmp,
    output     [3:0]  ea2_jmp,
    output reg [15:0] imm_val,
    output     [15:0] ea1_bit,
    output reg        cc_jmp,
    output            ext_inst,
    output            bit_inst,
    output            vld_inst
);

    parameter USE_CLK_ENA = 0;
    

    localparam [11:0] OP_PRIVILEDGED = (USE_CLK_ENA) ? 12'h038 : 12'h039;
    localparam [11:0] OP_ILLEGAL     = (USE_CLK_ENA) ? 12'h03A : 12'h03B;
  


















































  

    wire [15:0] w_grp_p0;
    

    wire [15:0] w_ea1b_p0;
    reg  [15:0] r_ea1b_p1;
    wire [9:0]  w_ea2b_p0;
    

    wire [3:0]  w_ea1_jmp_p0;
    reg  [3:0]  r_ea1_jmp_p1;

    wire [3:0]  w_ea2_jmp_p0;
    reg  [3:0]  r_ea2_jmp_p1;

    

    wire        w_g0_immed_p0;
    wire        w_g0_bitimm_p0;
    wire        w_g0_bitop_p0;
    wire        w_g4_misc_p0;
    wire        w_g4_oneop_p0;
    wire        w_g4_twoop_p0;
    wire        w_g5_addsub_p0;
    wire        w_g6_bsr_p0;
    wire        w_gE_shmem_p0;
    wire        w_gE_shreg_p0;
    

    wire        w_g4_nbcd_p0;
    wire        w_g8_sbcd_p0;
    wire        w_gC_abcd_p0;
    wire        w_g4_negx_p0;
    wire        w_g9_subx_p0;
    wire        w_gD_addx_p0;
    

    wire        w_ill_ins_p0;
    reg         r_ill_ins_p1;
    wire        w_prv_ins_p0;
    reg         r_prv_ins_p1;
    wire        w_ext_ins_p0;
    reg         r_ext_ins_p1;

    wire        w_bit_ins_p0;
    reg         r_bit_ins_p1;

    reg         w_vld_ins_p1;
    reg         r_vld_ins_p2;
    

    wire        w_call1_ena_p0;
    wire        w_call2_ena_p0;
    reg  [1:0]  r_call_en_p1;
    reg  [11:0] r_call_p2;
    

    wire [5:0]  w_idx6_5_0_p0;
    wire [5:0]  w_idx5_B_6_p0;
    wire [5:0]  w_idx4_8_3_p0;
    wire [5:0]  w_idx4_F_C_p0;
    wire [5:0]  w_idx3_8_6_p0;
    wire [5:0]  w_idx3_A_8_p0;
    wire [5:0]  w_idx2_7_6_p0;
    

    wire [7:0]  w_addr_p0;
    wire [35:0] w_data_p1;
    reg  [15:0] w_ea1m_p1;
    reg  [5:0]  w_incr_p1;
    reg  [11:0] w_call_p1;
    

    wire [15:0] w_imm3_i;
    wire [15:0] w_imm4_i;
    wire [15:0] w_imm8_i;
    wire [15:0] w_imm5_e;
    wire [15:0] w_imm8_e;
    

    assign w_grp_p0[0]    = (instr[15:12] == 4'b0000) ? 1'b1 : 1'b0;
    assign w_grp_p0[1]    = (instr[15:12] == 4'b0001) ? 1'b1 : 1'b0;
    assign w_grp_p0[2]    = (instr[15:12] == 4'b0010) ? 1'b1 : 1'b0;
    assign w_grp_p0[3]    = (instr[15:12] == 4'b0011) ? 1'b1 : 1'b0;
    assign w_grp_p0[4]    = (instr[15:12] == 4'b0100) ? 1'b1 : 1'b0;
    assign w_grp_p0[5]    = (instr[15:12] == 4'b0101) ? 1'b1 : 1'b0;
    assign w_grp_p0[6]    = (instr[15:12] == 4'b0110) ? 1'b1 : 1'b0;
    assign w_grp_p0[7]    = (instr[15:12] == 4'b0111) ? 1'b1 : 1'b0;
    assign w_grp_p0[8]    = (instr[15:12] == 4'b1000) ? 1'b1 : 1'b0;
    assign w_grp_p0[9]    = (instr[15:12] == 4'b1001) ? 1'b1 : 1'b0;
    assign w_grp_p0[10]   = (instr[15:12] == 4'b1010) ? 1'b1 : 1'b0;
    assign w_grp_p0[11]   = (instr[15:12] == 4'b1011) ? 1'b1 : 1'b0;
    assign w_grp_p0[12]   = (instr[15:12] == 4'b1100) ? 1'b1 : 1'b0;
    assign w_grp_p0[13]   = (instr[15:12] == 4'b1101) ? 1'b1 : 1'b0;
    assign w_grp_p0[14]   = (instr[15:12] == 4'b1110) ? 1'b1 : 1'b0;
    assign w_grp_p0[15]   = (instr[15:12] == 4'b1111) ? 1'b1 : 1'b0;
    

    assign w_ea1b_p0[15]  = (instr[5:0] == 6'b111111) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[14]  = (instr[5:0] == 6'b111110) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[13]  = (instr[5:0] == 6'b111101) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[12]  = (instr[5:0] == 6'b111100) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[11]  = (instr[5:0] == 6'b111011) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[10]  = (instr[5:0] == 6'b111010) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[9]   = (instr[5:0] == 6'b111001) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[8]   = (instr[5:0] == 6'b111000) ? 1'b1 : 1'b0;
    assign w_ea1b_p0[7]   = (instr[5:4] == 2'b00)     ? 1'b1 : 1'b0;
    assign w_ea1b_p0[6]   = (instr[5:3] == 3'b110)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[5]   = (instr[5:3] == 3'b101)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[4]   = (instr[5:3] == 3'b100)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[3]   = (instr[5:3] == 3'b011)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[2]   = (instr[5:3] == 3'b010)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[1]   = (instr[5:3] == 3'b001)    ? 1'b1 : 1'b0;
    assign w_ea1b_p0[0]   = (instr[5:3] == 3'b000)    ? 1'b1 : 1'b0;
    

    assign w_ea2b_p0[9]   = (instr[8:6]  == 3'b111) 
                         && (instr[11:10] != 2'b00)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[8]   = (instr[11:6] == 6'b001111) ? 1'b1 : 1'b0;
    assign w_ea2b_p0[7]   = (instr[11:6] == 6'b000111) ? 1'b1 : 1'b0;
    assign w_ea2b_p0[6]   = (instr[8:6]  == 3'b110)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[5]   = (instr[8:6]  == 3'b101)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[4]   = (instr[8:6]  == 3'b100)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[3]   = (instr[8:6]  == 3'b011)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[2]   = (instr[8:6]  == 3'b010)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[1]   = (instr[8:6]  == 3'b001)    ? 1'b1 : 1'b0;
    assign w_ea2b_p0[0]   = (instr[8:6]  == 3'b000)    ? 1'b1 : 1'b0;
    

    assign w_ea1_jmp_p0[3]   = (instr[5:3] == 3'b111) ? 1'b1 : 1'b0;
    assign w_ea1_jmp_p0[2:0] = (instr[5:3] == 3'b111) ? instr[2:0] : instr[5:3];
    assign w_ea2_jmp_p0[3]   = (instr[8:6] == 3'b111) ? 1'b1 : 1'b0;
    assign w_ea2_jmp_p0[2:0] = (instr[8:6] == 3'b111) ? instr[11:9] : instr[8:6];
    

    assign w_g0_immed_p0  = w_grp_p0[0]  &  ~instr[8];
    assign w_g0_bitimm_p0 = (instr[15:8] == 8'b0000_1000) ? 1'b1 : 1'b0;
    assign w_g0_bitop_p0  = w_grp_p0[0]  &   instr[8];
    assign w_g4_misc_p0   = (instr[15:6] == 10'b0100_111_001) ? 1'b1 : 1'b0;
    assign w_g4_oneop_p0  = w_grp_p0[4]  &  ~instr[8] & ~w_g4_misc_p0;
    assign w_g4_twoop_p0  = w_grp_p0[4]  &   instr[8];
    assign w_g5_addsub_p0 = w_grp_p0[5]  & ~(instr[7] & instr[6]);
    assign w_g6_bsr_p0    = (instr[11:8] == 4'b0001) ? 1'b1 : 1'b0;
    assign w_gE_shmem_p0  = w_grp_p0[14] &   instr[7] & instr[6];
    assign w_gE_shreg_p0  = w_grp_p0[14] & ~(instr[7] & instr[6]);
    

    assign w_g4_nbcd_p0   = (w_grp_p0[4])  && (instr[11:6] == 6'b100000) ? 1'b1 : 1'b0;
    assign w_g8_sbcd_p0   = (w_grp_p0[8])  &&  (instr[8:4] == 5'b10000)  ? 1'b1 : 1'b0;
    assign w_gC_abcd_p0   = (w_grp_p0[12]) &&  (instr[8:4] == 5'b10000)  ? 1'b1 : 1'b0;
    assign w_g4_negx_p0   = (w_grp_p0[4])  && (instr[11:8] == 4'b0000)   ? 1'b1 : 1'b0;
    assign w_g9_subx_p0   = (w_grp_p0[9])  && ((instr[8:4] == 5'b10000) ||
                                               (instr[8:4] == 5'b10100) ||
                                               (instr[8:4] == 5'b11000)) ? 1'b1 : 1'b0;
    assign w_gD_addx_p0   = (w_grp_p0[13]) && ((instr[8:4] == 5'b10000) ||
                                               (instr[8:4] == 5'b10100) ||
                                               (instr[8:4] == 5'b11000)) ? 1'b1 : 1'b0;
    assign w_ext_ins_p0   = w_g4_negx_p0 | w_g9_subx_p0 | w_gD_addx_p0
                          | w_g4_nbcd_p0 | w_g8_sbcd_p0 | w_gC_abcd_p0;
    

    assign w_bit_ins_p0   = w_g0_bitop_p0 | w_g0_bitimm_p0;
    

    assign w_ill_ins_p0   = (w_grp_p0[1]  & w_ea2b_p0[1])
                          | (w_grp_p0[1]  & w_ea2b_p0[9])
                          | (w_grp_p0[2]  & w_ea2b_p0[9])
                          | (w_grp_p0[3]  & w_ea2b_p0[9])
                          | (w_grp_p0[7]  & instr[8])
                          | (w_grp_p0[14] & instr[11] & instr[7] & instr[6]);

    assign w_prv_ins_p0   = ((w_grp_p0[0])  && (instr[6]) && (w_ea1b_p0[12]))
                         || ((w_g4_misc_p0) && ((instr[5:4] == 2'b10) ||
                                                (instr[5:0] == 6'b110000) ||
                                                (instr[6:1] == 6'b11001)))
                         || ((w_grp_p0[4])  && (instr[11:6] == 6'b011011))
                         ? user_mode : 1'b0;
    

    assign w_call1_ena_p0 = (w_grp_p0[0]  & w_ea1b_p0[0])
                          | (w_grp_p0[2]  & w_ea2b_p0[1])
                          | (w_grp_p0[3]  & w_ea2b_p0[1])
                          | (w_grp_p0[4]  & ~w_g4_misc_p0 & w_ea1b_p0[0])
                          | (w_grp_p0[6]  & w_g6_bsr_p0)
                          | (w_grp_p0[8]  & w_ea1b_p0[0])
                          | (w_grp_p0[9]  & w_ea1b_p0[0])
                          | (w_grp_p0[12] & w_ea1b_p0[0])
                          | (w_grp_p0[13] & w_ea1b_p0[0]);

    assign w_call2_ena_p0 = (w_grp_p0[0]  & ~instr[8]     & w_ea1b_p0[12])
                          | (w_grp_p0[0]  & instr[8]      & w_ea1b_p0[1])
                          | (w_grp_p0[4]  & ~w_g4_misc_p0 & w_ea1b_p0[3])
                          | (w_grp_p0[4]  & ~w_g4_misc_p0 & w_ea1b_p0[4])
                          | (w_grp_p0[5]  & w_ea1b_p0[1])
                          | (w_grp_p0[8]  & w_ea1b_p0[1])
                          | (w_grp_p0[9]  & w_ea1b_p0[1])
                          | (w_grp_p0[11] & w_ea1b_p0[1])
                          | (w_grp_p0[12] & w_ea1b_p0[1])
                          | (w_grp_p0[13] & w_ea1b_p0[1]);
    

    assign w_idx6_5_0_p0  = (w_g4_misc_p0)
                          ? instr[5:0]
                          : 6'b000000;
    assign w_idx5_B_6_p0  = (w_g0_immed_p0 | w_g4_oneop_p0)
                          ? { instr[14], instr[11:9], instr[7:6] }
                          : 6'b000000;
    assign w_idx4_8_3_p0  = (w_gE_shreg_p0)
                          ? { instr[7:6], instr[8], instr[5:3] }
                          : 6'b000000;
    assign w_idx4_F_C_p0  = (w_grp_p0[1] | w_grp_p0[2] | w_grp_p0[3] | w_grp_p0[6] | w_grp_p0[7] | w_grp_p0[10] | w_grp_p0[15])
                          ? { 2'b11, instr[15:12] }
                          : 6'b000000;                    
    assign w_idx3_8_6_p0  = (w_grp_p0[5] | w_grp_p0[8] | w_grp_p0[9] | w_grp_p0[11] | w_grp_p0[12] | w_grp_p0[13])
                          ? { instr[14] ^ ~instr[15], instr[13] ^ ~instr[15], instr[12] ^ ~instr[15], instr[8:6] }
                          : 6'b000000;
    assign w_idx3_A_8_p0  = (w_gE_shmem_p0)
                          ? { 3'b110, instr[10:8] }
                          : 6'b000000;
    assign w_idx2_7_6_p0  = (w_g0_bitop_p0 | w_g4_twoop_p0)
                          ? { 3'b111, instr[14], instr[7:6] }
                          : 6'b000000;
    

    assign w_addr_p0[7]   = ((instr[12]   | instr[13]) & ~instr[15])
                          | instr[15]     | w_g0_bitop_p0 | w_g4_twoop_p0;
    assign w_addr_p0[6]   = w_grp_p0[5]   | w_grp_p0[8]   | w_grp_p0[9]
                          | w_grp_p0[11]  | w_grp_p0[12]  | w_grp_p0[13]
                          | w_g0_immed_p0 | w_g0_bitop_p0 | w_g4_oneop_p0
                          | w_g4_twoop_p0 | w_gE_shmem_p0;
    assign w_addr_p0[5:0] = w_idx6_5_0_p0 | w_idx5_B_6_p0 | w_idx4_8_3_p0
                          | w_idx4_F_C_p0 | w_idx3_8_6_p0 | w_idx3_A_8_p0
                          | w_idx2_7_6_p0;
    

    j68_decode_rom
    #(
        .USE_CLK_ENA (USE_CLK_ENA)
    )
    U_decode_rom
    (
        .clock       (clk),
        .address     (w_addr_p0),
        .q           (w_data_p1)
    );
    
    always@(*) begin
    

        case (w_data_p1[11:8])
            4'b0000 : w_ea1m_p1 = 16'b000_00000_00000000;
            4'b0001 : w_ea1m_p1 = 16'b000_00011_01110101;
            4'b0010 : w_ea1m_p1 = 16'b000_00011_01111100;
            4'b0011 : w_ea1m_p1 = 16'b000_00011_01111101;
            4'b0100 : w_ea1m_p1 = 16'b000_00011_01111110;
            4'b0101 : w_ea1m_p1 = 16'b000_00011_01111111;
            4'b0110 : w_ea1m_p1 = 16'b000_01111_01001101;
            4'b0111 : w_ea1m_p1 = 16'b000_01111_01100100;
            4'b1000 : w_ea1m_p1 = 16'b000_01111_01100101;
            4'b1001 : w_ea1m_p1 = 16'b000_01111_01101100;
            4'b1010 : w_ea1m_p1 = 16'b000_01111_01111101;
            4'b1011 : w_ea1m_p1 = 16'b000_10011_01111101;
            4'b1100 : w_ea1m_p1 = 16'b000_11111_01111101;
            4'b1101 : w_ea1m_p1 = 16'b000_11111_01111111;
            default : w_ea1m_p1 = 16'b111_11111_01111111;
        endcase

        w_incr_p1 = (w_data_p1[23:18] & {6{r_call_en_p1[0]}})
                  | (w_data_p1[17:12] & {6{r_call_en_p1[1]}});

        if (((w_ea1m_p1 & r_ea1b_p1) == 16'h0000) || (r_ill_ins_p1)) begin

            w_call_p1    = OP_ILLEGAL;
            w_vld_ins_p1 = 1'b0;
        end
        else if (r_prv_ins_p1) begin

            w_call_p1    = OP_PRIVILEDGED;
            w_vld_ins_p1 = 1'b1;
        end
        else begin

            w_call_p1    = w_data_p1[35:24] + { 6'b000000, w_incr_p1 };
            w_vld_ins_p1 = 1'b1;
        end
    end


    always @(posedge rst or posedge clk) begin : DECODE_P1_P2
    
        if (rst) begin
            r_ea1_jmp_p1 <= 4'b0000;
            r_ea2_jmp_p1 <= 4'b0000;
            r_ill_ins_p1 <= 1'b0;
            r_prv_ins_p1 <= 1'b0;
            r_ext_ins_p1 <= 1'b0;
            r_bit_ins_p1 <= 1'b0;
            r_call_en_p1 <= 2'b00;
            r_ea1b_p1    <= 16'b0000000_00000000;      
            


            r_vld_ins_p2 <= 1'b0;


            r_call_p2    <= 12'h000;
        end
        else if (clk_ena) begin

            r_ea1_jmp_p1 <= w_ea1_jmp_p0;
            r_ea2_jmp_p1 <= w_ea2_jmp_p0;
            r_ill_ins_p1 <= w_ill_ins_p0;
            r_prv_ins_p1 <= w_prv_ins_p0;
            r_ext_ins_p1 <= w_ext_ins_p0;
            r_bit_ins_p1 <= w_bit_ins_p0;
            r_call_en_p1 <= { w_call2_ena_p0, w_call1_ena_p0 };
            r_ea1b_p1    <= w_ea1b_p0;



            r_vld_ins_p2 <= w_vld_ins_p1;


            r_call_p2    <= w_call_p1;
        end
    end
  
    assign vld_inst = r_vld_ins_p2;
    assign ext_inst = r_ext_ins_p1;
    assign bit_inst = r_bit_ins_p1;
    assign dec_jmp  = r_call_p2;
    assign ea1_jmp  = r_ea1_jmp_p1;
    assign ea2_jmp  = r_ea2_jmp_p1;
    assign ea1_bit  = r_ea1b_p1;



    assign w_imm3_i[15:4] = 12'h000;
    assign w_imm3_i[3]    = (instr[11:9] == 3'b000) ? (w_g5_addsub_p0 | (w_gE_shreg_p0 & ~instr[5])) : 1'b0;
    assign w_imm3_i[2:0]  = (w_g5_addsub_p0 | (w_gE_shreg_p0 & ~instr[5])) ? instr[11:9] : 3'b000;

    assign w_imm4_i[15:8] = 8'h00;
    assign w_imm4_i[7:0]  = (w_g4_misc_p0) ? {2'b10, instr[3:0], 2'b00} : 8'h00;

    assign w_imm8_i[15:8] = (w_grp_p0[6] | (w_grp_p0[7] & ~instr[8])) ? {8{instr[7]}} : 8'h00;
    assign w_imm8_i[7:0]  = (w_grp_p0[6] | (w_grp_p0[7] & ~instr[8])) ? instr[7:0] : 8'h00;



    assign w_imm5_e[15:5] = 11'b0;
    assign w_imm5_e[4:0]  = ext_wd[4:0];

    assign w_imm8_e[15:8] = {8{ext_wd[7]}};
    assign w_imm8_e[7:0]  = ext_wd[7:0];


    always @(posedge rst or posedge clk) begin : IMMED_VAL
    
        if (rst) begin
            imm_val <= 16'h0000;
        end
        else if (clk_ena) begin
            if (ins_rdy) imm_val <= w_imm3_i | w_imm4_i | w_imm8_i;
            if (ext_rdy) begin
                if (w_g0_bitimm_p0) begin
                    imm_val <= w_imm5_e;
                end
                else begin
                    imm_val <= w_imm8_e;
                end
            end
            if (imm_rdy) imm_val <= imm_wd;
        end
    end
  

    always @(posedge rst or posedge clk) begin : CC_JUMP_FLAG
    
        if (rst) begin
            cc_jmp <= 1'b0;
        end
        else if (clk_ena) begin
            case (instr[11:8])
                4'b0000 : cc_jmp <= 1'b1;
                4'b0001 : cc_jmp <= 1'b0;
                4'b0010 : cc_jmp <= ~(ccr_in[0] | ccr_in[2]);
                4'b0011 : cc_jmp <=   ccr_in[0] | ccr_in[2];
                4'b0100 : cc_jmp <= ~ ccr_in[0];
                4'b0101 : cc_jmp <=   ccr_in[0];
                4'b0110 : cc_jmp <= ~ ccr_in[2];
                4'b0111 : cc_jmp <=   ccr_in[2];
                4'b1000 : cc_jmp <= ~ ccr_in[1];
                4'b1001 : cc_jmp <=   ccr_in[1];
                4'b1010 : cc_jmp <= ~ ccr_in[3];
                4'b1011 : cc_jmp <=   ccr_in[3];
                4'b1100 : cc_jmp <= ~(ccr_in[1] ^ ccr_in[3]);
                4'b1101 : cc_jmp <=   ccr_in[1] ^ ccr_in[3];
                4'b1110 : cc_jmp <= ~((ccr_in[1] ^ ccr_in[3]) | ccr_in[2]);
                4'b1111 : cc_jmp <=   (ccr_in[1] ^ ccr_in[3]) | ccr_in[2];
            endcase
        end
    end
  
endmodule