Andrew Attwood | 1d1e8c3 | 2021-11-26 15:05:07 +0000 | [diff] [blame] | 1 | // Copyright lowRISC contributors. |
| 2 | // Copyright 2017 ETH Zurich and University of Bologna. |
| 3 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| 4 | // SPDX-License-Identifier: Apache-2.0 |
| 5 | |
| 6 | //////////////////////////////////////////////////////////////////////////////// |
| 7 | // Engineer: Matthias Baer - baermatt@student.ethz.ch // |
| 8 | // // |
| 9 | // Additional contributions by: // |
| 10 | // Sven Stucki - svstucki@student.ethz.ch // |
| 11 | // // |
| 12 | // // |
| 13 | // Design Name: RISC-V processor core // |
| 14 | // Project Name: ibex // |
| 15 | // Language: SystemVerilog // |
| 16 | // // |
| 17 | // Description: Defines for various constants used by the processor core. // |
| 18 | // // |
| 19 | //////////////////////////////////////////////////////////////////////////////// |
| 20 | |
| 21 | // Copyright lowRISC contributors. |
| 22 | // Copyright 2017 ETH Zurich and University of Bologna. |
| 23 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| 24 | // SPDX-License-Identifier: Apache-2.0 |
| 25 | |
| 26 | //////////////////////////////////////////////////////////////////////////////// |
| 27 | // Engineer: Matthias Baer - baermatt@student.ethz.ch // |
| 28 | // // |
| 29 | // Additional contributions by: // |
| 30 | // Sven Stucki - svstucki@student.ethz.ch // |
| 31 | // // |
| 32 | // // |
| 33 | // Design Name: RISC-V processor core // |
| 34 | // Project Name: ibex // |
| 35 | // Language: SystemVerilog // |
| 36 | // // |
| 37 | // Description: Defines for various constants used by the processor core. // |
| 38 | // // |
| 39 | //////////////////////////////////////////////////////////////////////////////// |
| 40 | |
nguyendao-uom | 4b10c63 | 2021-11-25 11:23:15 +0000 | [diff] [blame] | 41 | module ibex_compressed_decoder ( |
| 42 | instr_i, |
| 43 | instr_o, |
| 44 | is_compressed_o, |
| 45 | illegal_instr_o |
| 46 | ); |
| 47 | input wire [31:0] instr_i; |
| 48 | output reg [31:0] instr_o; |
| 49 | output wire is_compressed_o; |
| 50 | output reg illegal_instr_o; |
| 51 | localparam [6:0] ibex_defines_OPCODE_BRANCH = 7'h63; |
| 52 | localparam [6:0] ibex_defines_OPCODE_JAL = 7'h6f; |
| 53 | localparam [6:0] ibex_defines_OPCODE_JALR = 7'h67; |
| 54 | localparam [6:0] ibex_defines_OPCODE_LOAD = 7'h03; |
| 55 | localparam [6:0] ibex_defines_OPCODE_LUI = 7'h37; |
| 56 | localparam [6:0] ibex_defines_OPCODE_OP = 7'h33; |
| 57 | localparam [6:0] ibex_defines_OPCODE_OPIMM = 7'h13; |
| 58 | localparam [6:0] ibex_defines_OPCODE_STORE = 7'h23; |
| 59 | always @(*) begin |
| 60 | illegal_instr_o = 1'b0; |
| 61 | instr_o = {32 {1'sb0}}; |
| 62 | case (instr_i[1:0]) |
| 63 | 2'b00: |
| 64 | case (instr_i[15:13]) |
| 65 | 3'b000: begin |
| 66 | instr_o = {2'b00, instr_i[10:7], instr_i[12:11], instr_i[5], instr_i[6], 2'b00, 5'h02, 3'b000, 2'b01, instr_i[4:2], {ibex_defines_OPCODE_OPIMM}}; |
| 67 | if (instr_i[12:5] == 8'b00000000) |
| 68 | illegal_instr_o = 1'b1; |
| 69 | end |
| 70 | 3'b010: instr_o = {5'b00000, instr_i[5], instr_i[12:10], instr_i[6], 2'b00, 2'b01, instr_i[9:7], 3'b010, 2'b01, instr_i[4:2], {ibex_defines_OPCODE_LOAD}}; |
| 71 | 3'b110: instr_o = {5'b00000, instr_i[5], instr_i[12], 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b010, instr_i[11:10], instr_i[6], 2'b00, {ibex_defines_OPCODE_STORE}}; |
| 72 | default: illegal_instr_o = 1'b1; |
| 73 | endcase |
| 74 | 2'b01: |
| 75 | case (instr_i[15:13]) |
| 76 | 3'b000: instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], instr_i[11:7], 3'b000, instr_i[11:7], {ibex_defines_OPCODE_OPIMM}}; |
| 77 | 3'b001, 3'b101: instr_o = {instr_i[12], instr_i[8], instr_i[10:9], instr_i[6], instr_i[7], instr_i[2], instr_i[11], instr_i[5:3], {9 {instr_i[12]}}, 4'b0000, ~instr_i[15], {ibex_defines_OPCODE_JAL}}; |
| 78 | 3'b010: begin |
| 79 | instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 5'b00000, 3'b000, instr_i[11:7], {ibex_defines_OPCODE_OPIMM}}; |
| 80 | if (instr_i[11:7] == 5'b00000) |
| 81 | illegal_instr_o = 1'b1; |
| 82 | end |
| 83 | 3'b011: begin |
| 84 | instr_o = {{15 {instr_i[12]}}, instr_i[6:2], instr_i[11:7], {ibex_defines_OPCODE_LUI}}; |
| 85 | if (instr_i[11:7] == 5'h02) |
| 86 | instr_o = {{3 {instr_i[12]}}, instr_i[4:3], instr_i[5], instr_i[2], instr_i[6], 4'b0000, 5'h02, 3'b000, 5'h02, {ibex_defines_OPCODE_OPIMM}}; |
| 87 | else if (instr_i[11:7] == 5'b00000) |
| 88 | illegal_instr_o = 1'b1; |
| 89 | if ({instr_i[12], instr_i[6:2]} == 6'b000000) |
| 90 | illegal_instr_o = 1'b1; |
| 91 | end |
| 92 | 3'b100: |
| 93 | case (instr_i[11:10]) |
| 94 | 2'b00, 2'b01: begin |
| 95 | instr_o = {1'b0, instr_i[10], 5'b00000, instr_i[6:2], 2'b01, instr_i[9:7], 3'b101, 2'b01, instr_i[9:7], {ibex_defines_OPCODE_OPIMM}}; |
| 96 | if (instr_i[12] == 1'b1) |
| 97 | illegal_instr_o = 1'b1; |
| 98 | if (instr_i[6:2] == 5'b00000) |
| 99 | illegal_instr_o = 1'b1; |
| 100 | end |
| 101 | 2'b10: instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], {ibex_defines_OPCODE_OPIMM}}; |
| 102 | 2'b11: |
| 103 | case ({instr_i[12], instr_i[6:5]}) |
| 104 | 3'b000: instr_o = {9'b010000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b000, 2'b01, instr_i[9:7], {ibex_defines_OPCODE_OP}}; |
| 105 | 3'b001: instr_o = {9'b000000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b100, 2'b01, instr_i[9:7], {ibex_defines_OPCODE_OP}}; |
| 106 | 3'b010: instr_o = {9'b000000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b110, 2'b01, instr_i[9:7], {ibex_defines_OPCODE_OP}}; |
| 107 | 3'b011: instr_o = {9'b000000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], {ibex_defines_OPCODE_OP}}; |
| 108 | 3'b100, 3'b101, 3'b110, 3'b111: illegal_instr_o = 1'b1; |
| 109 | endcase |
| 110 | endcase |
| 111 | 3'b110, 3'b111: instr_o = {{4 {instr_i[12]}}, instr_i[6:5], instr_i[2], 5'b00000, 2'b01, instr_i[9:7], 2'b00, instr_i[13], instr_i[11:10], instr_i[4:3], instr_i[12], {ibex_defines_OPCODE_BRANCH}}; |
| 112 | default: |
| 113 | ; |
| 114 | endcase |
| 115 | 2'b10: |
| 116 | case (instr_i[15:13]) |
| 117 | 3'b000: begin |
| 118 | instr_o = {7'b0000000, instr_i[6:2], instr_i[11:7], 3'b001, instr_i[11:7], {ibex_defines_OPCODE_OPIMM}}; |
| 119 | if (instr_i[11:7] == 5'b00000) |
| 120 | illegal_instr_o = 1'b1; |
| 121 | if ((instr_i[12] == 1'b1) || (instr_i[6:2] == 5'b00000)) |
| 122 | illegal_instr_o = 1'b1; |
| 123 | end |
| 124 | 3'b010: begin |
| 125 | instr_o = {4'b0000, instr_i[3:2], instr_i[12], instr_i[6:4], 2'b00, 5'h02, 3'b010, instr_i[11:7], ibex_defines_OPCODE_LOAD}; |
| 126 | if (instr_i[11:7] == 5'b00000) |
| 127 | illegal_instr_o = 1'b1; |
| 128 | end |
| 129 | 3'b100: |
| 130 | if (instr_i[12] == 1'b0) begin |
| 131 | instr_o = {7'b0000000, instr_i[6:2], 5'b00000, 3'b000, instr_i[11:7], {ibex_defines_OPCODE_OP}}; |
| 132 | if (instr_i[6:2] == 5'b00000) |
| 133 | instr_o = {12'b000000000000, instr_i[11:7], 3'b000, 5'b00000, {ibex_defines_OPCODE_JALR}}; |
| 134 | end |
| 135 | else begin |
| 136 | instr_o = {7'b0000000, instr_i[6:2], instr_i[11:7], 3'b000, instr_i[11:7], {ibex_defines_OPCODE_OP}}; |
| 137 | if (instr_i[11:7] == 5'b00000) begin |
| 138 | instr_o = 32'h00100073; |
| 139 | if (instr_i[6:2] != 5'b00000) |
| 140 | illegal_instr_o = 1'b1; |
| 141 | end |
| 142 | else if (instr_i[6:2] == 5'b00000) |
| 143 | instr_o = {12'b000000000000, instr_i[11:7], 3'b000, 5'b00001, {ibex_defines_OPCODE_JALR}}; |
| 144 | end |
| 145 | 3'b110: instr_o = {4'b0000, instr_i[8:7], instr_i[12], instr_i[6:2], 5'h02, 3'b010, instr_i[11:9], 2'b00, {ibex_defines_OPCODE_STORE}}; |
| 146 | default: illegal_instr_o = 1'b1; |
| 147 | endcase |
| 148 | default: instr_o = instr_i; |
| 149 | endcase |
| 150 | end |
| 151 | assign is_compressed_o = instr_i[1:0] != 2'b11; |
| 152 | endmodule |