blob: 9fea3340b52689fe702377fdf8a5dd61d69a4574 [file] [log] [blame]
Andrew Attwood1d1e8c32021-11-26 15:05:07 +00001// 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-uom4b10c632021-11-25 11:23:15 +000041module 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;
152endmodule