| module ibex_compressed_decoder ( |
| clk_i, |
| rst_ni, |
| valid_i, |
| instr_i, |
| instr_o, |
| is_compressed_o, |
| illegal_instr_o |
| ); |
| input wire clk_i; |
| input wire rst_ni; |
| input wire valid_i; |
| input wire [31:0] instr_i; |
| output reg [31:0] instr_o; |
| output wire is_compressed_o; |
| output reg illegal_instr_o; |
| wire unused_valid; |
| assign unused_valid = valid_i; |
| wire unused_clk_i; |
| wire unused_rst_ni; |
| assign unused_clk_i = clk_i; |
| assign unused_rst_ni = rst_ni; |
| always @(*) begin |
| instr_o = instr_i; |
| illegal_instr_o = 1'b0; |
| case (instr_i[1:0]) |
| 2'b00: |
| case (instr_i[15:13]) |
| 3'b000: begin |
| 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], 7'h13}; |
| if (instr_i[12:5] == 8'b00000000) |
| illegal_instr_o = 1'b1; |
| end |
| 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], 7'h03}; |
| 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, 7'h23}; |
| 3'b001, 3'b011, 3'b100, 3'b101, 3'b111: illegal_instr_o = 1'b1; |
| default: illegal_instr_o = 1'b1; |
| endcase |
| 2'b01: |
| case (instr_i[15:13]) |
| 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], 7'h13}; |
| 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], 7'h6f}; |
| 3'b010: instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 5'b00000, 3'b000, instr_i[11:7], 7'h13}; |
| 3'b011: begin |
| instr_o = {{15 {instr_i[12]}}, instr_i[6:2], instr_i[11:7], 7'h37}; |
| if (instr_i[11:7] == 5'h02) |
| 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, 7'h13}; |
| if ({instr_i[12], instr_i[6:2]} == 6'b000000) |
| illegal_instr_o = 1'b1; |
| end |
| 3'b100: |
| case (instr_i[11:10]) |
| 2'b00, 2'b01: begin |
| 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], 7'h13}; |
| if (instr_i[12] == 1'b1) |
| illegal_instr_o = 1'b1; |
| end |
| 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], 7'h13}; |
| 2'b11: |
| case ({instr_i[12], instr_i[6:5]}) |
| 3'b000: instr_o = {9'b010000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b000, 2'b01, instr_i[9:7], 7'h33}; |
| 3'b001: instr_o = {9'b000000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b100, 2'b01, instr_i[9:7], 7'h33}; |
| 3'b010: instr_o = {9'b000000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b110, 2'b01, instr_i[9:7], 7'h33}; |
| 3'b011: instr_o = {9'b000000001, instr_i[4:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], 7'h33}; |
| 3'b100, 3'b101, 3'b110, 3'b111: illegal_instr_o = 1'b1; |
| default: illegal_instr_o = 1'b1; |
| endcase |
| default: illegal_instr_o = 1'b1; |
| endcase |
| 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], 7'h63}; |
| default: illegal_instr_o = 1'b1; |
| endcase |
| 2'b10: |
| case (instr_i[15:13]) |
| 3'b000: begin |
| instr_o = {7'b0000000, instr_i[6:2], instr_i[11:7], 3'b001, instr_i[11:7], 7'h13}; |
| if (instr_i[12] == 1'b1) |
| illegal_instr_o = 1'b1; |
| end |
| 3'b010: begin |
| 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], 7'h03}; |
| if (instr_i[11:7] == 5'b00000) |
| illegal_instr_o = 1'b1; |
| end |
| 3'b100: |
| if (instr_i[12] == 1'b0) begin |
| if (instr_i[6:2] != 5'b00000) |
| instr_o = {7'b0000000, instr_i[6:2], 5'b00000, 3'b000, instr_i[11:7], 7'h33}; |
| else begin |
| instr_o = {12'b000000000000, instr_i[11:7], 3'b000, 5'b00000, 7'h67}; |
| if (instr_i[11:7] == 5'b00000) |
| illegal_instr_o = 1'b1; |
| end |
| end |
| else if (instr_i[6:2] != 5'b00000) |
| instr_o = {7'b0000000, instr_i[6:2], instr_i[11:7], 3'b000, instr_i[11:7], 7'h33}; |
| else if (instr_i[11:7] == 5'b00000) |
| instr_o = 32'h00100073; |
| else |
| instr_o = {12'b000000000000, instr_i[11:7], 3'b000, 5'b00001, 7'h67}; |
| 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, 7'h23}; |
| 3'b001, 3'b011, 3'b101, 3'b111: illegal_instr_o = 1'b1; |
| default: illegal_instr_o = 1'b1; |
| endcase |
| 2'b11: |
| ; |
| default: illegal_instr_o = 1'b1; |
| endcase |
| end |
| assign is_compressed_o = instr_i[1:0] != 2'b11; |
| endmodule |