Decode attn in the major opcode decode table
authorPaul Mackerras <paulus@ozlabs.org>
Mon, 6 Apr 2020 04:07:45 +0000 (14:07 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Tue, 7 Apr 2020 10:09:08 +0000 (20:09 +1000)
This decodes attn using entry 0 of the major_decode_rom_array table
instead of a special case in the decode1_1 process.  This means that
only the major opcode (the top 6 bits) is checked at decode time.
To make sure the instruction is attn not some random illegal pattern,
we now check bits 1-10 of the instruction at execute time and
generate an illegal instruction interrupt if those bits are not
0100000000.

This reduces LUT consumption by 42 LUTs on the Arty A7-100.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
decode1.vhdl
execute1.vhdl

index dbcea4781c42783e99faea0ecd610bbb63091c1b..8c7d5f2ca4f340470d31f8135c41353ae9e1b5af 100644 (file)
@@ -42,6 +42,7 @@ architecture behaviour of decode1 is
                15 =>       (ALU,    OP_ADD,       RA_OR_ZERO, CONST_SI_HI, NONE, RT,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- addis
                28 =>       (ALU,    OP_AND,       NONE,       CONST_UI,    RS,   RA,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE,  '0', '0'), -- andi.
                29 =>       (ALU,    OP_AND,       NONE,       CONST_UI_HI, RS,   RA,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE,  '0', '0'), -- andis.
+                 0 =>       (ALU,    OP_ATTN,      NONE,       NONE,        NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- attn
                18 =>       (ALU,    OP_B,         NONE,       CONST_LI,    NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0'), -- b
                16 =>       (ALU,    OP_BC,        SPR,        CONST_BD,    NONE, SPR , '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0'), -- bc
                11 =>       (ALU,    OP_CMP,       RA,         CONST_SI,    NONE, NONE, '0', '1', '1', '0', ONE,  '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0'), -- cmpi
@@ -343,7 +344,6 @@ architecture behaviour of decode1 is
 
         --                                       unit     internal      in1         in2          in3   out   CR   CR   inv  inv  cry   cry  ldst  BR   sgn  upd  rsrv 32b  sgn  rc    lk   sgl
         --                                                      op                                           in   out   A   out  in    out  len        ext                                 pipe
-        constant attn_instr    : decode_rom_t := (ALU,    OP_ATTN,      NONE,       NONE,        NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1');
        constant nop_instr     : decode_rom_t := (ALU,    OP_NOP,       NONE,       NONE,        NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0');
 
 begin
@@ -402,9 +402,6 @@ begin
                 elsif std_match(f_in.insn, "01100000000000000000000000000000") then
                         report "PPC_nop";
                         v.decode := nop_instr;
-                elsif std_match(f_in.insn, "000000---------------0100000000-") then
-                        report "PPC_attn";
-                        v.decode := attn_instr;
 
                 else
                         v.decode := major_decode_rom_array(to_integer(majorop));
index dd5cb21641f6231394cacc0924fe24023bfd4f9c..6915a43132a9464532e5175497368672d1e6241b 100644 (file)
@@ -444,8 +444,14 @@ begin
                     illegal := '1';
                 end if;
            when OP_ATTN =>
-               terminate_out <= '1';
-               report "ATTN";
+                -- check bits 1-10 of the instruction to make sure it's attn
+                -- if not then it is illegal
+                if e_in.insn(10 downto 1) = "0100000000" then
+                    terminate_out <= '1';
+                    report "ATTN";
+                else
+                    illegal := '1';
+                end if;
            when OP_NOP =>
                -- Do nothing
            when OP_ADD | OP_CMP | OP_TRAP =>