OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_decompressor.vhd] - Blame information for rev 49

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 zero_gravi
-- #################################################################################################
2 49 zero_gravi
-- # << NEORV32 - CPU: Compressed Instructions Decoder (RISC-V "C" Extension) >>                   #
3 2 zero_gravi
-- # ********************************************************************************************* #
4
-- # BSD 3-Clause License                                                                          #
5
-- #                                                                                               #
6 49 zero_gravi
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved.                                     #
7 2 zero_gravi
-- #                                                                                               #
8
-- # Redistribution and use in source and binary forms, with or without modification, are          #
9
-- # permitted provided that the following conditions are met:                                     #
10
-- #                                                                                               #
11
-- # 1. Redistributions of source code must retain the above copyright notice, this list of        #
12
-- #    conditions and the following disclaimer.                                                   #
13
-- #                                                                                               #
14
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
15
-- #    conditions and the following disclaimer in the documentation and/or other materials        #
16
-- #    provided with the distribution.                                                            #
17
-- #                                                                                               #
18
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
19
-- #    endorse or promote products derived from this software without specific prior written      #
20
-- #    permission.                                                                                #
21
-- #                                                                                               #
22
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
23
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
24
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
25
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
26
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
27
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
28
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
29
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
30
-- # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
31
-- # ********************************************************************************************* #
32
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
33
-- #################################################################################################
34
 
35
library ieee;
36
use ieee.std_logic_1164.all;
37
use ieee.numeric_std.all;
38
 
39
library neorv32;
40
use neorv32.neorv32_package.all;
41
 
42
entity neorv32_cpu_decompressor is
43
  port (
44
    -- instruction input --
45
    ci_instr16_i : in  std_ulogic_vector(15 downto 0); -- compressed instruction input
46
    -- instruction output --
47
    ci_illegal_o : out std_ulogic; -- is an illegal compressed instruction
48
    ci_instr32_o : out std_ulogic_vector(31 downto 0)  -- 32-bit decompressed instruction
49
  );
50
end neorv32_cpu_decompressor;
51
 
52
architecture neorv32_cpu_decompressor_rtl of neorv32_cpu_decompressor is
53
 
54
  -- compressed instruction layout --
55
  constant ci_opcode_lsb_c : natural :=  0;
56
  constant ci_opcode_msb_c : natural :=  1;
57
  constant ci_rd_3_lsb_c   : natural :=  2;
58
  constant ci_rd_3_msb_c   : natural :=  4;
59
  constant ci_rd_5_lsb_c   : natural :=  7;
60
  constant ci_rd_5_msb_c   : natural := 11;
61
  constant ci_rs1_3_lsb_c  : natural :=  7;
62
  constant ci_rs1_3_msb_c  : natural :=  9;
63
  constant ci_rs1_5_lsb_c  : natural :=  7;
64
  constant ci_rs1_5_msb_c  : natural := 11;
65
  constant ci_rs2_3_lsb_c  : natural :=  2;
66
  constant ci_rs2_3_msb_c  : natural :=  4;
67
  constant ci_rs2_5_lsb_c  : natural :=  2;
68
  constant ci_rs2_5_msb_c  : natural :=  6;
69
  constant ci_funct3_lsb_c : natural := 13;
70
  constant ci_funct3_msb_c : natural := 15;
71
 
72
begin
73
 
74
  -- Compressed Instruction Decoder ---------------------------------------------------------
75
  -- -------------------------------------------------------------------------------------------
76
  decompressor: process(ci_instr16_i)
77
    variable imm20_v : std_ulogic_vector(20 downto 0);
78
    variable imm12_v : std_ulogic_vector(12 downto 0);
79
  begin
80
    -- defaults --
81
    ci_illegal_o <= '0';
82
    ci_instr32_o <= (others => '0');
83
 
84
    -- 22-bit sign-extended immediate for J/JAL --
85
    imm20_v := (others => ci_instr16_i(12)); -- sign extension
86
    imm20_v(00):= '0';
87
    imm20_v(01):= ci_instr16_i(3);
88
    imm20_v(02):= ci_instr16_i(4);
89
    imm20_v(03):= ci_instr16_i(5);
90
    imm20_v(04):= ci_instr16_i(11);
91
    imm20_v(05):= ci_instr16_i(2);
92
    imm20_v(06):= ci_instr16_i(7);
93
    imm20_v(07):= ci_instr16_i(6);
94
    imm20_v(08):= ci_instr16_i(9);
95
    imm20_v(09):= ci_instr16_i(10);
96
    imm20_v(10):= ci_instr16_i(8);
97
    imm20_v(11):= ci_instr16_i(12);
98
 
99
    -- 12-bit sign-extended immediate for branches --
100
    imm12_v := (others => ci_instr16_i(12)); -- sign extension
101
    imm12_v(00):= '0';
102
    imm12_v(01):= ci_instr16_i(3);
103
    imm12_v(02):= ci_instr16_i(4);
104
    imm12_v(03):= ci_instr16_i(10);
105
    imm12_v(04):= ci_instr16_i(11);
106
    imm12_v(05):= ci_instr16_i(2);
107
    imm12_v(06):= ci_instr16_i(5);
108
    imm12_v(07):= ci_instr16_i(6);
109
    imm12_v(08):= ci_instr16_i(12);
110
 
111
    -- actual decoder --
112
    case ci_instr16_i(ci_opcode_msb_c downto ci_opcode_lsb_c) is
113
 
114
      when "00" => -- C0: Register-Based Loads and Stores
115
        case ci_instr16_i(ci_funct3_msb_c downto ci_funct3_lsb_c) is
116
 
117
          when "000" => -- Illegal_instruction, C.ADDI4SPN
118
          -- ----------------------------------------------------------------------------------------------------------
119 36 zero_gravi
            if (ci_instr16_i(12 downto 2) = "00000000000") then -- "official illegal instruction"
120 2 zero_gravi
              ci_illegal_o <= '1';
121 36 zero_gravi
            else
122
              -- C.ADDI4SPN
123 2 zero_gravi
              ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c;
124
              ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= "00010"; -- stack pointer
125
              ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= "01" & ci_instr16_i(ci_rd_3_msb_c downto ci_rd_3_lsb_c);
126
              ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_subadd_c;
127
              ci_instr32_o(instr_imm12_msb_c downto instr_imm12_lsb_c)   <= (others => '0'); -- zero extend
128
              ci_instr32_o(instr_imm12_lsb_c + 0)                        <= '0';
129
              ci_instr32_o(instr_imm12_lsb_c + 1)                        <= '0';
130
              ci_instr32_o(instr_imm12_lsb_c + 2)                        <= ci_instr16_i(6);
131
              ci_instr32_o(instr_imm12_lsb_c + 3)                        <= ci_instr16_i(5);
132
              ci_instr32_o(instr_imm12_lsb_c + 4)                        <= ci_instr16_i(11);
133
              ci_instr32_o(instr_imm12_lsb_c + 5)                        <= ci_instr16_i(12);
134
              ci_instr32_o(instr_imm12_lsb_c + 6)                        <= ci_instr16_i(7);
135
              ci_instr32_o(instr_imm12_lsb_c + 7)                        <= ci_instr16_i(8);
136
              ci_instr32_o(instr_imm12_lsb_c + 8)                        <= ci_instr16_i(9);
137
              ci_instr32_o(instr_imm12_lsb_c + 9)                        <= ci_instr16_i(10);
138
            end if;
139
 
140
          when "010" => -- C.LW
141
          -- ----------------------------------------------------------------------------------------------------------
142
            ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_load_c;
143
            ci_instr32_o(21 downto 20)                                 <= "00";
144
            ci_instr32_o(22)                                           <= ci_instr16_i(6);
145
            ci_instr32_o(23)                                           <= ci_instr16_i(10);
146
            ci_instr32_o(24)                                           <= ci_instr16_i(11);
147
            ci_instr32_o(25)                                           <= ci_instr16_i(12);
148
            ci_instr32_o(26)                                           <= ci_instr16_i(5);
149 6 zero_gravi
            ci_instr32_o(31 downto 27)                                 <= (others => '0');
150 2 zero_gravi
            ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_lw_c;
151
            ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c); -- x8 - x15
152
            ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= "01" & ci_instr16_i(ci_rd_3_msb_c downto ci_rd_3_lsb_c);   -- x8 - x15
153
 
154
          when "110" => -- C.SW
155
          -- ----------------------------------------------------------------------------------------------------------
156
            ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_store_c;
157
            ci_instr32_o(08 downto 07)                                 <= "00";
158
            ci_instr32_o(09)                                           <= ci_instr16_i(6);
159
            ci_instr32_o(10)                                           <= ci_instr16_i(10);
160
            ci_instr32_o(11)                                           <= ci_instr16_i(11);
161
            ci_instr32_o(25)                                           <= ci_instr16_i(12);
162
            ci_instr32_o(26)                                           <= ci_instr16_i(5);
163
            ci_instr32_o(31 downto 27)                                 <= (others => '0');
164
            ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_sw_c;
165
            ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c); -- x8 - x15
166
            ci_instr32_o(instr_rs2_msb_c downto instr_rs2_lsb_c)       <= "01" & ci_instr16_i(ci_rs2_3_msb_c downto ci_rs2_3_lsb_c); -- x8 - x15
167
 
168
          when others => -- undefined
169 49 zero_gravi
          -- ----------------------------------------------------------------------------------------------------------
170 2 zero_gravi
            ci_illegal_o <= '1';
171 49 zero_gravi
 
172 2 zero_gravi
        end case;
173
 
174
      when "01" => -- C1: Control Transfer Instructions, Integer Constant-Generation Instructions
175
 
176
        case ci_instr16_i(ci_funct3_msb_c downto ci_funct3_lsb_c) is
177
          when "101" => -- C.J
178
          -- ----------------------------------------------------------------------------------------------------------
179
            ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_jal_c;
180
            ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= "00000"; -- discard return address
181
            ci_instr32_o(19 downto 12)                                 <= imm20_v(19 downto 12);
182
            ci_instr32_o(20)                                           <= imm20_v(11);
183
            ci_instr32_o(30 downto 21)                                 <= imm20_v(10 downto 01);
184
            ci_instr32_o(31)                                           <= imm20_v(20);
185
 
186
          when "001" => -- C.JAL
187
          -- ----------------------------------------------------------------------------------------------------------
188
            ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_jal_c;
189
            ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= "00001"; -- save return address to link register
190
            ci_instr32_o(19 downto 12)                                 <= imm20_v(19 downto 12);
191
            ci_instr32_o(20)                                           <= imm20_v(11);
192
            ci_instr32_o(30 downto 21)                                 <= imm20_v(10 downto 01);
193
            ci_instr32_o(31)                                           <= imm20_v(20);
194
 
195
          when "110" => -- C.BEQ
196
          -- ----------------------------------------------------------------------------------------------------------
197
            ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_branch_c;
198
            ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_beq_c;
199
            ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c);
200
            ci_instr32_o(instr_rs2_msb_c downto instr_rs2_lsb_c)       <= "00000"; -- x0
201
            ci_instr32_o(07)                                           <= imm12_v(11);
202
            ci_instr32_o(11 downto 08)                                 <= imm12_v(04 downto 01);
203
            ci_instr32_o(30 downto 25)                                 <= imm12_v(10 downto 05);
204
            ci_instr32_o(31)                                           <= imm12_v(12);
205
 
206
          when "111" => -- C.BNEZ
207
          -- ----------------------------------------------------------------------------------------------------------
208
            ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_branch_c;
209
            ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_bne_c;
210
            ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c);
211
            ci_instr32_o(instr_rs2_msb_c downto instr_rs2_lsb_c)       <= "00000"; -- x0
212
            ci_instr32_o(07)                                           <= imm12_v(11);
213
            ci_instr32_o(11 downto 08)                                 <= imm12_v(04 downto 01);
214
            ci_instr32_o(30 downto 25)                                 <= imm12_v(10 downto 05);
215
            ci_instr32_o(31)                                           <= imm12_v(12);
216
 
217
          when "010" => -- C.LI
218
          -- ----------------------------------------------------------------------------------------------------------
219
            ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c;
220
            ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_subadd_c;
221
            ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= "00000"; -- x0
222
            ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= ci_instr16_i(ci_rd_5_msb_c downto ci_rd_5_lsb_c);
223
            ci_instr32_o(instr_imm12_msb_c downto instr_imm12_lsb_c)   <= (others => ci_instr16_i(12)); -- sign extend
224
            ci_instr32_o(instr_imm12_lsb_c + 0)                        <= ci_instr16_i(2);
225
            ci_instr32_o(instr_imm12_lsb_c + 1)                        <= ci_instr16_i(3);
226
            ci_instr32_o(instr_imm12_lsb_c + 2)                        <= ci_instr16_i(4);
227
            ci_instr32_o(instr_imm12_lsb_c + 3)                        <= ci_instr16_i(5);
228
            ci_instr32_o(instr_imm12_lsb_c + 4)                        <= ci_instr16_i(6);
229
            ci_instr32_o(instr_imm12_lsb_c + 5)                        <= ci_instr16_i(12);
230
            if (ci_instr16_i(ci_rd_5_msb_c downto ci_rd_5_lsb_c) = "00000") then -- HINT
231
              ci_illegal_o <= '1';
232
            end if;
233
 
234
          when "011" => -- C.LUI / C.ADDI16SP
235
          -- ----------------------------------------------------------------------------------------------------------
236
            if (ci_instr16_i(ci_rd_5_msb_c downto ci_rd_5_lsb_c) = "00010") then -- C.ADDI16SP
237
              ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c;
238
              ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_subadd_c;
239
              ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= ci_instr16_i(ci_rd_5_msb_c downto ci_rd_5_lsb_c);
240
              ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= "00010"; -- stack pointer
241
              ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= "00010"; -- stack pointer
242
              ci_instr32_o(instr_imm12_msb_c downto instr_imm12_lsb_c)   <= (others => ci_instr16_i(12)); -- sign extend
243 41 zero_gravi
              ci_instr32_o(instr_imm12_lsb_c + 0)                        <= '0';
244
              ci_instr32_o(instr_imm12_lsb_c + 1)                        <= '0';
245
              ci_instr32_o(instr_imm12_lsb_c + 2)                        <= '0';
246
              ci_instr32_o(instr_imm12_lsb_c + 3)                        <= '0';
247
              ci_instr32_o(instr_imm12_lsb_c + 4)                        <= ci_instr16_i(6);
248
              ci_instr32_o(instr_imm12_lsb_c + 5)                        <= ci_instr16_i(2);
249
              ci_instr32_o(instr_imm12_lsb_c + 6)                        <= ci_instr16_i(5);
250
              ci_instr32_o(instr_imm12_lsb_c + 7)                        <= ci_instr16_i(3);
251
              ci_instr32_o(instr_imm12_lsb_c + 8)                        <= ci_instr16_i(4);
252
              ci_instr32_o(instr_imm12_lsb_c + 9)                        <= ci_instr16_i(12);
253 2 zero_gravi
 
254
            else -- C.LUI
255
              ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_lui_c;
256
              ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= ci_instr16_i(ci_rd_5_msb_c downto ci_rd_5_lsb_c);
257
              ci_instr32_o(instr_imm20_msb_c downto instr_imm20_lsb_c)   <= (others => ci_instr16_i(12)); -- sign extend
258
              ci_instr32_o(instr_imm20_lsb_c + 0)                        <= ci_instr16_i(2);
259
              ci_instr32_o(instr_imm20_lsb_c + 1)                        <= ci_instr16_i(3);
260
              ci_instr32_o(instr_imm20_lsb_c + 2)                        <= ci_instr16_i(4);
261
              ci_instr32_o(instr_imm20_lsb_c + 3)                        <= ci_instr16_i(5);
262
              ci_instr32_o(instr_imm20_lsb_c + 4)                        <= ci_instr16_i(6);
263
              ci_instr32_o(instr_imm20_lsb_c + 5)                        <= ci_instr16_i(12);
264
            end if;
265
            if (ci_instr16_i(6 downto 2) = "00000") and (ci_instr16_i(12) = '0') then -- reserved
266
              ci_illegal_o <= '1';
267
            end if;
268
 
269
          when "000" => -- C.NOP (rd=0) / C.ADDI
270
          -- ----------------------------------------------------------------------------------------------------------
271
            ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c;
272
            ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_subadd_c;
273
            ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= ci_instr16_i(ci_rs1_5_msb_c downto ci_rs1_5_lsb_c);
274
            ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= ci_instr16_i(ci_rd_5_msb_c downto ci_rd_5_lsb_c);
275
            ci_instr32_o(instr_imm12_msb_c downto instr_imm12_lsb_c)   <= (others => ci_instr16_i(12)); -- sign extend
276
            ci_instr32_o(instr_imm12_lsb_c + 0)                        <= ci_instr16_i(2);
277
            ci_instr32_o(instr_imm12_lsb_c + 1)                        <= ci_instr16_i(3);
278
            ci_instr32_o(instr_imm12_lsb_c + 2)                        <= ci_instr16_i(4);
279
            ci_instr32_o(instr_imm12_lsb_c + 3)                        <= ci_instr16_i(5);
280
            ci_instr32_o(instr_imm12_lsb_c + 4)                        <= ci_instr16_i(6);
281
            ci_instr32_o(instr_imm12_lsb_c + 5)                        <= ci_instr16_i(12);
282
 
283
          when "100" => -- C.SRLI, C.SRAI, C.ANDI, C.SUB, C.XOR, C.OR, C.AND, reserved
284
          -- ----------------------------------------------------------------------------------------------------------
285
            ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c) <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c);
286
            ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)   <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c);
287
            if (ci_instr16_i(11 downto 10) = "11") then -- register-register operation
288
              ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alu_c;
289
              ci_instr32_o(instr_rs2_msb_c downto instr_rs2_lsb_c) <= "01" & ci_instr16_i(ci_rs2_3_msb_c downto ci_rs2_3_lsb_c);
290
              case ci_instr16_i(6 downto 5) is
291
                when "00" => -- C.SUB
292
                  ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_subadd_c;
293
                  ci_instr32_o(instr_funct7_msb_c downto instr_funct7_lsb_c) <= "0100000";
294
                when "01" => -- C.XOR
295
                  ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_xor_c;
296
                  ci_instr32_o(instr_funct7_msb_c downto instr_funct7_lsb_c) <= "0000000";
297
                when "10" => -- C.OR
298
                  ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_or_c;
299
                  ci_instr32_o(instr_funct7_msb_c downto instr_funct7_lsb_c) <= "0000000";
300
                when others => -- C.AND
301
                  ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_and_c;
302
                  ci_instr32_o(instr_funct7_msb_c downto instr_funct7_lsb_c) <= "0000000";
303
              end case;
304
            else -- register-immediate operation
305
              ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c;
306
              case ci_instr16_i(11 downto 10) is
307
                when "00" => -- C.SRLI
308
                  ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_sr_c;
309
                  ci_instr32_o(instr_funct7_msb_c downto instr_funct7_lsb_c) <= "0000000";
310
                  ci_instr32_o(instr_imm12_lsb_c + 0)                        <= ci_instr16_i(2);
311
                  ci_instr32_o(instr_imm12_lsb_c + 1)                        <= ci_instr16_i(3);
312
                  ci_instr32_o(instr_imm12_lsb_c + 2)                        <= ci_instr16_i(4);
313
                  ci_instr32_o(instr_imm12_lsb_c + 3)                        <= ci_instr16_i(5);
314
                  ci_instr32_o(instr_imm12_lsb_c + 4)                        <= ci_instr16_i(6);
315
                  ci_illegal_o <= ci_instr16_i(12);
316
                when "01" => -- C.SRAI
317
                  ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_sr_c;
318
                  ci_instr32_o(instr_funct7_msb_c downto instr_funct7_lsb_c) <= "0100000";
319
                  ci_instr32_o(instr_imm12_lsb_c + 0)                        <= ci_instr16_i(2);
320
                  ci_instr32_o(instr_imm12_lsb_c + 1)                        <= ci_instr16_i(3);
321
                  ci_instr32_o(instr_imm12_lsb_c + 2)                        <= ci_instr16_i(4);
322
                  ci_instr32_o(instr_imm12_lsb_c + 3)                        <= ci_instr16_i(5);
323
                  ci_instr32_o(instr_imm12_lsb_c + 4)                        <= ci_instr16_i(6);
324
                  ci_illegal_o <= ci_instr16_i(12);
325
                when "10" => -- C.ANDI
326
                  ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_and_c;
327
                  ci_instr32_o(instr_imm12_msb_c downto instr_imm12_lsb_c)   <= (others => ci_instr16_i(12)); -- sign extend
328
                  ci_instr32_o(instr_imm12_lsb_c + 0)                        <= ci_instr16_i(2);
329
                  ci_instr32_o(instr_imm12_lsb_c + 1)                        <= ci_instr16_i(3);
330
                  ci_instr32_o(instr_imm12_lsb_c + 2)                        <= ci_instr16_i(4);
331
                  ci_instr32_o(instr_imm12_lsb_c + 3)                        <= ci_instr16_i(5);
332
                  ci_instr32_o(instr_imm12_lsb_c + 4)                        <= ci_instr16_i(6);
333
                  ci_instr32_o(instr_imm12_lsb_c + 5)                        <= ci_instr16_i(12);
334
                when others => -- register-register operation
335
                  NULL;
336
              end case;
337
            end if;
338
            if (ci_instr16_i(12 downto 10) = "111") then -- reserved / undefined
339
              ci_illegal_o <= '1';
340
            end if;
341
 
342
          when others => -- undefined
343 49 zero_gravi
          -- ----------------------------------------------------------------------------------------------------------
344 2 zero_gravi
            ci_illegal_o <= '1';
345 49 zero_gravi
 
346 2 zero_gravi
        end case;
347
 
348
      when "10" => -- C2: Stack-Pointer-Based Loads and Stores, Control Transfer Instructions
349
        case ci_instr16_i(ci_funct3_msb_c downto ci_funct3_lsb_c) is
350
 
351
          when "000" => -- C.SLLI
352
          -- ----------------------------------------------------------------------------------------------------------
353
            ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c;
354
            ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= ci_instr16_i(ci_rs1_5_msb_c downto ci_rs1_5_lsb_c);
355
            ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= ci_instr16_i(ci_rs1_5_msb_c downto ci_rs1_5_lsb_c);
356
            ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_sll_c;
357
            ci_instr32_o(instr_funct7_msb_c downto instr_funct7_lsb_c) <= "0000000";
358
            ci_instr32_o(instr_imm12_lsb_c + 0)                        <= ci_instr16_i(2);
359
            ci_instr32_o(instr_imm12_lsb_c + 1)                        <= ci_instr16_i(3);
360
            ci_instr32_o(instr_imm12_lsb_c + 2)                        <= ci_instr16_i(4);
361
            ci_instr32_o(instr_imm12_lsb_c + 3)                        <= ci_instr16_i(5);
362
            ci_instr32_o(instr_imm12_lsb_c + 4)                        <= ci_instr16_i(6);
363
            ci_illegal_o <= ci_instr16_i(12);
364
 
365
          when "010" => -- C.LWSP
366
          -- ----------------------------------------------------------------------------------------------------------
367
            ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_load_c;
368
            ci_instr32_o(21 downto 20)                                 <= "00";
369
            ci_instr32_o(22)                                           <= ci_instr16_i(4);
370
            ci_instr32_o(23)                                           <= ci_instr16_i(5);
371
            ci_instr32_o(24)                                           <= ci_instr16_i(6);
372
            ci_instr32_o(25)                                           <= ci_instr16_i(12);
373
            ci_instr32_o(26)                                           <= ci_instr16_i(2);
374
            ci_instr32_o(27)                                           <= ci_instr16_i(3);
375
            ci_instr32_o(31 downto 28)                                 <= (others => '0');
376
            ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_lw_c;
377
            ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= "00010"; -- stack pointer
378
            ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= ci_instr16_i(ci_rd_5_msb_c downto ci_rd_5_lsb_c);
379
 
380
          when "110" => -- C.SWSP
381
          -- ----------------------------------------------------------------------------------------------------------
382
            ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_store_c;
383
            ci_instr32_o(08 downto 07)                                 <= "00";
384
            ci_instr32_o(09)                                           <= ci_instr16_i(9);
385
            ci_instr32_o(10)                                           <= ci_instr16_i(10);
386
            ci_instr32_o(11)                                           <= ci_instr16_i(11);
387
            ci_instr32_o(25)                                           <= ci_instr16_i(12);
388
            ci_instr32_o(26)                                           <= ci_instr16_i(7);
389
            ci_instr32_o(27)                                           <= ci_instr16_i(8);
390
            ci_instr32_o(31 downto 28)                                 <= (others => '0');
391
            ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_sw_c;
392
            ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= "00010"; -- stack pointer
393
            ci_instr32_o(instr_rs2_msb_c downto instr_rs2_lsb_c)       <= ci_instr16_i(ci_rs2_5_msb_c downto ci_rs2_5_lsb_c);
394
 
395
          when "100" => -- C.JR, C.JALR, C.MV, C.EBREAK, C.ADD
396
          -- ----------------------------------------------------------------------------------------------------------
397
            if (ci_instr16_i(12) = '0') then -- C.JR, C.MV
398
              if (ci_instr16_i(6 downto 2) = "00000") then -- C.JR
399
                ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_jalr_c;
400
                ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= ci_instr16_i(ci_rs1_5_msb_c downto ci_rs1_5_lsb_c);
401
                ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= "00000"; -- discard return address
402
              else -- C.MV
403
                ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alu_c;
404
                ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= "000";
405
                ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= ci_instr16_i(ci_rd_5_msb_c downto ci_rd_5_lsb_c);
406
                ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= "00000"; -- x0
407
                ci_instr32_o(instr_rs2_msb_c downto instr_rs2_lsb_c)       <= ci_instr16_i(ci_rs2_5_msb_c downto ci_rs2_5_lsb_c);
408
              end if;
409
            else -- C.EBREAK, C.JALR, C.ADD
410
              if (ci_instr16_i(6 downto 2) = "00000") then -- C.EBREAK, C.JALR
411
                if (ci_instr16_i(11 downto 7) = "00000") then -- C.EBREAK
412
                  ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c)   <= opcode_syscsr_c;
413
                  ci_instr32_o(instr_funct12_msb_c downto instr_funct12_lsb_c) <= "000000000001";
414
                else -- C.JALR
415
                  ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_jalr_c;
416
                  ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= ci_instr16_i(ci_rs1_5_msb_c downto ci_rs1_5_lsb_c);
417
                  ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= "00001"; -- save return address to link register
418
                end if;
419
              else -- C.ADD
420
                ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alu_c;
421
                ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= "000";
422
                ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c)         <= ci_instr16_i(ci_rd_5_msb_c downto ci_rd_5_lsb_c);
423
                ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c)       <= ci_instr16_i(ci_rd_5_msb_c downto ci_rd_5_lsb_c);
424
                ci_instr32_o(instr_rs2_msb_c downto instr_rs2_lsb_c)       <= ci_instr16_i(ci_rs2_5_msb_c downto ci_rs2_5_lsb_c);
425
              end if;
426
            end if;
427
 
428
          when others => -- undefined
429 49 zero_gravi
          -- ----------------------------------------------------------------------------------------------------------
430 2 zero_gravi
            ci_illegal_o <= '1';
431 49 zero_gravi
 
432 2 zero_gravi
        end case;
433
 
434
      when others => -- not a compressed instruction
435 49 zero_gravi
      -- ----------------------------------------------------------------------------------------------------------
436 2 zero_gravi
        NULL;
437
 
438
    end case;
439
  end process decompressor;
440
 
441
 
442
end neorv32_cpu_decompressor_rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.