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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_cp_bitmanip.vhd] - Blame information for rev 63

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

Line No. Rev Author Line
1 63 zero_gravi
-- #################################################################################################
2
-- # << NEORV32 - CPU Co-Processor: Bit-Manipulation Co-Processor Unit (RISC-V "B" Extension) >>   #
3
-- # ********************************************************************************************* #
4
-- # The bit manipulation unit is implemented as co-processor that has a processing latency of 1   #
5
-- # cycle for logic/arithmetic operations and 3+shamt (=shift amount) cycles for shift(-related)  #
6
-- # operations. Use the FAST_SHIFT_EN option to reduce shift-related instruction's latency to a   #
7
-- # fixed value of 3 cycles latency (using barrel shifters).                                      #
8
-- #                                                                                               #
9
-- # Supported sub-extensions (Zb*):                                                               #
10
-- # - Zbb: Basic bit-manipulation instructions                                                    #
11
-- # ********************************************************************************************* #
12
-- # BSD 3-Clause License                                                                          #
13
-- #                                                                                               #
14
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved.                                     #
15
-- #                                                                                               #
16
-- # Redistribution and use in source and binary forms, with or without modification, are          #
17
-- # permitted provided that the following conditions are met:                                     #
18
-- #                                                                                               #
19
-- # 1. Redistributions of source code must retain the above copyright notice, this list of        #
20
-- #    conditions and the following disclaimer.                                                   #
21
-- #                                                                                               #
22
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
23
-- #    conditions and the following disclaimer in the documentation and/or other materials        #
24
-- #    provided with the distribution.                                                            #
25
-- #                                                                                               #
26
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
27
-- #    endorse or promote products derived from this software without specific prior written      #
28
-- #    permission.                                                                                #
29
-- #                                                                                               #
30
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
31
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
32
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
33
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
34
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
35
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
36
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
37
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
38
-- # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
39
-- # ********************************************************************************************* #
40
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
41
-- #################################################################################################
42
 
43
library ieee;
44
use ieee.std_logic_1164.all;
45
use ieee.numeric_std.all;
46
 
47
library neorv32;
48
use neorv32.neorv32_package.all;
49
 
50
entity neorv32_cpu_cp_bitmanip is
51
  generic (
52
    FAST_SHIFT_EN : boolean -- use barrel shifter for shift operations
53
  );
54
  port (
55
    -- global control --
56
    clk_i   : in  std_ulogic; -- global clock, rising edge
57
    rstn_i  : in  std_ulogic; -- global reset, low-active, async
58
    ctrl_i  : in  std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
59
    start_i : in  std_ulogic; -- trigger operation
60
    -- data input --
61
    cmp_i   : in  std_ulogic_vector(1 downto 0); -- comparator status
62
    rs1_i   : in  std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
63
    rs2_i   : in  std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
64
    -- result and status --
65
    res_o   : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result
66
    valid_o : out std_ulogic -- data output valid
67
  );
68
end neorv32_cpu_cp_bitmanip;
69
 
70
architecture neorv32_cpu_cp_bitmanip_rtl of neorv32_cpu_cp_bitmanip is
71
 
72
  -- commands: logic with negate --
73
  constant op_andn_c  : natural := 0;
74
  constant op_orn_c   : natural := 1;
75
  constant op_xnor_c  : natural := 2;
76
  -- commands: count leading/trailing zero bits --
77
  constant op_clz_c   : natural := 3;
78
  constant op_ctz_c   : natural := 4;
79
  -- commands: count population --
80
  constant op_cpop_c  : natural := 5;
81
  -- commands: integer minimum/maximum --
82
  constant op_max_c   : natural := 6; -- signed/unsigned
83
  constant op_min_c   : natural := 7; -- signed/unsigned
84
  -- commands: sign- and zero-extension --
85
  constant op_sextb_c : natural := 8;
86
  constant op_sexth_c : natural := 9;
87
  constant op_zexth_c : natural := 10;
88
  -- commands: bitwise rotation --
89
  constant op_rol_c   : natural := 11;
90
  constant op_ror_c   : natural := 12; -- rori
91
  -- commands: or-combine --
92
  constant op_orcb_c  : natural := 13;
93
  -- commands: byte-reverse --
94
  constant op_rev8_c  : natural := 14;
95
  --
96
  constant op_width_c : natural := 15;
97
 
98
  -- controller --
99
  type ctrl_state_t is (S_IDLE, S_START_SHIFT, S_BUSY_SHIFT);
100
  signal ctrl_state   : ctrl_state_t;
101
  signal cmd, cmd_buf : std_ulogic_vector(op_width_c-1 downto 0);
102
  signal valid        : std_ulogic;
103
 
104
  -- operand buffers --
105
  signal rs1_reg : std_ulogic_vector(data_width_c-1 downto 0);
106
  signal rs2_reg : std_ulogic_vector(data_width_c-1 downto 0);
107
  signal less_ff : std_ulogic;
108
 
109
  -- shift amount (immediate or register) --
110
  signal shamt : std_ulogic_vector(index_size_f(data_width_c)-1 downto 0);
111
 
112
  -- serial shifter --
113
  type shifter_t is record
114
    start   : std_ulogic;
115
    run     : std_ulogic;
116
    bcnt    : std_ulogic_vector(index_size_f(data_width_c) downto 0); -- bit counter
117
    cnt     : std_ulogic_vector(index_size_f(data_width_c) downto 0); -- iteration counter
118
    cnt_max : std_ulogic_vector(index_size_f(data_width_c) downto 0);
119
    sreg    : std_ulogic_vector(data_width_c-1 downto 0);
120
  end record;
121
  signal shifter : shifter_t;
122
 
123
  -- barrel shifter --
124
  type bs_level_t is array (index_size_f(data_width_c) downto 0) of std_ulogic_vector(data_width_c-1 downto 0);
125
  signal bs_level : bs_level_t;
126
 
127
  -- operation results --
128
  type res_t is array (0 to op_width_c-1) of std_ulogic_vector(data_width_c-1 downto 0);
129
  signal res_int, res_out : res_t;
130
 
131
begin
132
 
133
  -- Instruction Decoding (One-Hot) ---------------------------------------------------------
134
  -- -------------------------------------------------------------------------------------------
135
  -- a minimal decoding logic is used here -> just to distinguish between B.Zbb instructions
136
  -- a more specific decoding and instruction check is done by the CPU control unit
137
 
138
  -- Zbb - Basic bit-manipulation instructions --
139
  cmd(op_andn_c)  <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "11") else '0';
140
  cmd(op_orn_c)   <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "10") else '0';
141
  cmd(op_xnor_c)  <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "10") and (ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c) = "00") else '0';
142
  --
143
  cmd(op_max_c)   <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '1') else '0';
144
  cmd(op_min_c)   <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '1') and (ctrl_i(ctrl_ir_funct3_1_c) = '0') else '0';
145
  cmd(op_zexth_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "00") and (ctrl_i(ctrl_ir_funct12_5_c) = '0') else '0';
146
  --
147
  cmd(op_orcb_c)  <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "01") else '0';
148
  --
149
  cmd(op_clz_c)   <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "000") else '0';
150
  cmd(op_ctz_c)   <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "001") else '0';
151
  cmd(op_cpop_c)  <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "010") else '0';
152
  cmd(op_sextb_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "100") else '0';
153
  cmd(op_sexth_c) <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c) = '0') and (ctrl_i(ctrl_ir_funct12_2_c downto ctrl_ir_funct12_0_c) = "101") else '0';
154
  cmd(op_rol_c)   <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "001") and (ctrl_i(ctrl_ir_opcode7_5_c) = '1') else '0';
155
  cmd(op_ror_c)   <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '0') and (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "101") else '0';
156
  cmd(op_rev8_c)  <= '1' when (ctrl_i(ctrl_ir_funct12_10_c downto ctrl_ir_funct12_9_c) = "11") and (ctrl_i(ctrl_ir_funct12_7_c) = '1') else '0';
157
 
158
 
159
  -- Co-Processor Controller ----------------------------------------------------------------
160
  -- -------------------------------------------------------------------------------------------
161
  coprocessor_ctrl: process(rstn_i, clk_i)
162
  begin
163
    if (rstn_i = '0') then
164
      ctrl_state    <= S_IDLE;
165
      cmd_buf       <= (others => def_rst_val_c);
166
      rs1_reg       <= (others => def_rst_val_c);
167
      rs2_reg       <= (others => def_rst_val_c);
168
      less_ff       <= def_rst_val_c;
169
      shifter.start <= '0';
170
      valid         <= '0';
171
    elsif rising_edge(clk_i) then
172
      -- defaults --
173
      shifter.start <= '0';
174
      valid         <= '0';
175
 
176
      -- fsm --
177
      case ctrl_state is
178
 
179
        when S_IDLE => -- wait for operation trigger
180
        -- ------------------------------------------------------------
181
          if (start_i = '1') then
182
            less_ff <= cmp_i(cmp_less_c);
183
            cmd_buf <= cmd;
184
            rs1_reg <= rs1_i;
185
            rs2_reg <= rs2_i;
186
            if ((cmd(op_clz_c) or cmd(op_ctz_c) or cmd(op_cpop_c) or cmd(op_ror_c) or cmd(op_rol_c)) = '1') then -- multi-cycle shift operation
187
              if (FAST_SHIFT_EN = false) then -- default: iterative computation
188
                shifter.start <= '1';
189
                ctrl_state <= S_START_SHIFT;
190
              else -- full-parallel computation
191
                ctrl_state <= S_BUSY_SHIFT;
192
              end if;
193
            else
194
              valid      <= '1';
195
              ctrl_state <= S_IDLE;
196
            end if;
197
          end if;
198
 
199
        when S_START_SHIFT => -- one cycle delay to start shift operation
200
        -- ------------------------------------------------------------
201
          ctrl_state <= S_BUSY_SHIFT;
202
 
203
        when S_BUSY_SHIFT => -- wait for multi-cycle shift operation to finish
204
        -- ------------------------------------------------------------
205
          if (shifter.run = '0') then
206
            valid      <= '1';
207
            ctrl_state <= S_IDLE;
208
          end if;
209
 
210
        when others => -- undefined
211
        -- ------------------------------------------------------------
212
          ctrl_state <= S_IDLE;
213
 
214
      end case;
215
    end if;
216
  end process coprocessor_ctrl;
217
 
218
 
219
  -- Shift Amount ---------------------------------------------------------------------------
220
  -- -------------------------------------------------------------------------------------------
221
  -- we could also use ALU's internal operand B - but we are having a local version here in order to allow
222
  -- better logic combination inside the ALU (since that is the critical path of the CPU)
223
  shamt <= ctrl_i(ctrl_ir_funct12_0_c+shamt'left downto ctrl_ir_funct12_0_c) when (ctrl_i(ctrl_ir_opcode7_5_c) = '0') else rs2_reg(shamt'left downto 0);
224
 
225
 
226
  -- Shifter Function Core (iterative: small but slow) --------------------------------------
227
  -- -------------------------------------------------------------------------------------------
228
  serial_shifter:
229
  if (FAST_SHIFT_EN = false) generate
230
    shifter_unit: process(rstn_i, clk_i)
231
      variable new_bit_v : std_ulogic;
232
    begin
233
      if (rstn_i = '0') then
234
        shifter.cnt     <= (others => def_rst_val_c);
235
        shifter.sreg    <= (others => def_rst_val_c);
236
        shifter.cnt_max <= (others => def_rst_val_c);
237
        shifter.bcnt    <= (others => def_rst_val_c);
238
      elsif rising_edge(clk_i) then
239
        if (shifter.start = '1') then -- trigger new shift
240
          shifter.cnt <= (others => '0');
241
          -- shift operand --
242
          if (cmd_buf(op_clz_c) = '1') or (cmd_buf(op_rol_c) = '1') then -- count LEADING zeros / rotate LEFT
243
            shifter.sreg <= bit_rev_f(rs1_reg); -- reverse - we can only do right shifts here
244
          else -- ctz, cpop, ror
245
            shifter.sreg <= rs1_reg;
246
          end if;
247
          -- max shift amount --
248
          if (cmd_buf(op_cpop_c) = '1') then -- population count
249
            shifter.cnt_max <= (others => '0');
250
            shifter.cnt_max(shifter.cnt_max'left) <= '1';
251
          else
252
            shifter.cnt_max <= '0' & shamt;
253
          end if;
254
          shifter.bcnt <= (others => '0');
255
        elsif (shifter.run = '1') then -- right shifts only
256
          new_bit_v := ((cmd_buf(op_ror_c) or cmd_buf(op_rol_c)) and shifter.sreg(0)) or (cmd_buf(op_clz_c) or cmd_buf(op_ctz_c));
257
          shifter.sreg <= new_bit_v & shifter.sreg(shifter.sreg'left downto 1); -- ro[r/l]/lsr(for counting)
258
          shifter.cnt  <= std_ulogic_vector(unsigned(shifter.cnt) + 1); -- iteration counter
259
          if (shifter.sreg(0) = '1') then
260
            shifter.bcnt <= std_ulogic_vector(unsigned(shifter.bcnt) + 1); -- bit counter
261
          end if;
262
        end if;
263
      end if;
264
    end process shifter_unit;
265
  end generate;
266
 
267
  -- run control --
268
  serial_shifter_ctrl:
269
  if (FAST_SHIFT_EN = false) generate
270
    shifter_unit_ctrl: process(cmd_buf, shifter)
271
    begin
272
      -- keep shifting until ... --
273
      if (cmd_buf(op_clz_c) = '1') or (cmd_buf(op_ctz_c) = '1') then -- count leading/trailing zeros
274
        shifter.run <= not shifter.sreg(0);
275
      else -- population count / rotate
276
        if (shifter.cnt = shifter.cnt_max) then
277
          shifter.run <= '0';
278
        else
279
          shifter.run <= '1';
280
        end if;
281
      end if;
282
    end process shifter_unit_ctrl;
283
  end generate;
284
 
285
 
286
  -- Shifter Function Core (parallel: fast but large) ---------------------------------------
287
  -- -------------------------------------------------------------------------------------------
288
  barrel_shifter_async_sync:
289
  if (FAST_SHIFT_EN = true) generate
290
    shifter_unit_fast: process(rstn_i, clk_i)
291
      variable new_bit_v : std_ulogic;
292
    begin
293
      if (rstn_i = '0') then
294
        shifter.cnt     <= (others => def_rst_val_c);
295
        shifter.sreg    <= (others => def_rst_val_c);
296
        shifter.bcnt    <= (others => def_rst_val_c);
297
      elsif rising_edge(clk_i) then
298
        -- population count --
299
        shifter.bcnt <= std_ulogic_vector(to_unsigned(popcount_f(rs1_reg), shifter.bcnt'length));
300
        -- count leading/trailing zeros --
301
        if cmd_buf(op_clz_c) = '1' then -- leading
302
          shifter.cnt <= std_ulogic_vector(to_unsigned(leading_zeros_f(rs1_reg), shifter.cnt'length));
303
        else -- trailing
304
          shifter.cnt <= std_ulogic_vector(to_unsigned(leading_zeros_f(bit_rev_f(rs1_reg)), shifter.cnt'length));
305
        end if;
306
        -- barrel shifter --
307
        shifter.sreg <= bs_level(0); -- rol/ror[i]
308
      end if;
309
    end process shifter_unit_fast;
310
    shifter.run <= '0'; -- we are done already!
311
  end generate;
312
 
313
  -- barrel shifter array --
314
  barrel_shifter_async:
315
  if (FAST_SHIFT_EN = true) generate
316
    shifter_unit_async: process(rs1_reg, shamt, cmd_buf, bs_level)
317
    begin
318
      -- input level: convert left shifts to right shifts --
319
      if (cmd_buf(op_rol_c) = '1') then -- is left shift?
320
        bs_level(index_size_f(data_width_c)) <= bit_rev_f(rs1_reg); -- reverse bit order of input operand
321
      else
322
        bs_level(index_size_f(data_width_c)) <= rs1_reg;
323
      end if;
324
 
325
      -- shifter array --
326
      for i in index_size_f(data_width_c)-1 downto 0 loop
327
        if (shamt(i) = '1') then
328
          bs_level(i)(data_width_c-1 downto data_width_c-(2**i)) <= bs_level(i+1)((2**i)-1 downto 0);
329
          bs_level(i)((data_width_c-(2**i))-1 downto 0) <= bs_level(i+1)(data_width_c-1 downto 2**i);
330
        else
331
          bs_level(i) <= bs_level(i+1);
332
        end if;
333
      end loop;
334
    end process shifter_unit_async;
335
  end generate;
336
 
337
 
338
  -- Operation Results ----------------------------------------------------------------------
339
  -- -------------------------------------------------------------------------------------------
340
  -- logic with negate --
341
  res_int(op_andn_c) <= rs1_reg and (not rs2_reg); -- logical and-not
342
  res_int(op_orn_c)  <= rs1_reg or  (not rs2_reg); -- logical or-not
343
  res_int(op_xnor_c) <= rs1_reg xor (not rs2_reg); -- logical xor-not
344
 
345
  -- count leading/trailing zeros --
346
  res_int(op_clz_c)(data_width_c-1 downto shifter.cnt'left+1) <= (others => '0');
347
  res_int(op_clz_c)(shifter.cnt'left downto 0) <= shifter.cnt;
348
  res_int(op_ctz_c) <= (others => '0'); -- unused/redundant
349
 
350
  -- count set bits --
351
  res_int(op_cpop_c)(data_width_c-1 downto shifter.bcnt'left+1) <= (others => '0');
352
  res_int(op_cpop_c)(shifter.bcnt'left downto 0) <= shifter.bcnt;
353
 
354
  -- min/max select --
355
  res_int(op_min_c) <= rs1_reg when ((less_ff xor cmd_buf(op_max_c)) = '1') else rs2_reg;
356
  res_int(op_max_c) <= (others => '0'); -- unused/redundant
357
 
358
  -- sign-extension --
359
  res_int(op_sextb_c)(data_width_c-1 downto 8) <= (others => rs1_reg(7));
360
  res_int(op_sextb_c)(7 downto 0) <= rs1_reg(7 downto 0); -- sign-extend byte
361
  res_int(op_sexth_c)(data_width_c-1 downto 16) <= (others => rs1_reg(15));
362
  res_int(op_sexth_c)(15 downto 0) <= rs1_reg(15 downto 0); -- sign-extend half-word
363
  res_int(op_zexth_c)(data_width_c-1 downto 16) <= (others => '0');
364
  res_int(op_zexth_c)(15 downto 0) <= rs1_reg(15 downto 0); -- zero-extend half-word
365
 
366
  -- rotate right/left --
367
  res_int(op_ror_c) <= shifter.sreg;
368
  res_int(op_rol_c) <= bit_rev_f(shifter.sreg); -- reverse to compensate internal right-only shifts
369
 
370
  -- or-combine.byte --
371
  or_combine_gen:
372
  for i in 0 to (data_width_c/8)-1 generate -- sub-byte loop
373
    res_int(op_orcb_c)(i*8+7 downto i*8) <= (others => or_reduce_f(rs1_reg(i*8+7 downto i*8)));
374
  end generate; -- i
375
 
376
  -- reversal.8 (byte swap) --
377
  res_int(op_rev8_c) <= bswap32_f(rs1_reg);
378
 
379
 
380
  -- Output Selector ------------------------------------------------------------------------
381
  -- -------------------------------------------------------------------------------------------
382
  res_out(op_andn_c)  <= res_int(op_andn_c)  when (cmd_buf(op_andn_c)  = '1') else (others => '0');
383
  res_out(op_orn_c)   <= res_int(op_orn_c)   when (cmd_buf(op_orn_c)   = '1') else (others => '0');
384
  res_out(op_xnor_c)  <= res_int(op_xnor_c)  when (cmd_buf(op_xnor_c)  = '1') else (others => '0');
385
  res_out(op_clz_c)   <= res_int(op_clz_c)   when ((cmd_buf(op_clz_c) or cmd_buf(op_ctz_c)) = '1') else (others => '0');
386
  res_out(op_ctz_c)   <= (others => '0'); -- unused/redundant
387
  res_out(op_cpop_c)  <= res_int(op_cpop_c)  when (cmd_buf(op_cpop_c)  = '1') else (others => '0');
388
  res_out(op_min_c)   <= res_int(op_min_c)   when ((cmd_buf(op_min_c) or cmd_buf(op_max_c)) = '1') else (others => '0');
389
  res_out(op_max_c)   <= (others => '0'); -- unused/redundant
390
  res_out(op_sextb_c) <= res_int(op_sextb_c) when (cmd_buf(op_sextb_c) = '1') else (others => '0');
391
  res_out(op_sexth_c) <= res_int(op_sexth_c) when (cmd_buf(op_sexth_c) = '1') else (others => '0');
392
  res_out(op_zexth_c) <= res_int(op_zexth_c) when (cmd_buf(op_zexth_c) = '1') else (others => '0');
393
  res_out(op_ror_c)   <= res_int(op_ror_c)   when (cmd_buf(op_ror_c)   = '1') else (others => '0');
394
  res_out(op_rol_c)   <= res_int(op_rol_c)   when (cmd_buf(op_rol_c)   = '1') else (others => '0');
395
  res_out(op_orcb_c)  <= res_int(op_orcb_c)  when (cmd_buf(op_orcb_c)  = '1') else (others => '0');
396
  res_out(op_rev8_c)  <= res_int(op_rev8_c)  when (cmd_buf(op_rev8_c)  = '1') else (others => '0');
397
 
398
 
399
  -- Output Gate ----------------------------------------------------------------------------
400
  -- -------------------------------------------------------------------------------------------
401
  output_gate: process(rstn_i, clk_i)
402
  begin
403
    if (rstn_i = '0') then
404
      res_o <= (others => def_rst_val_c);
405
    elsif rising_edge(clk_i) then
406
      res_o <= (others => '0');
407
      if (valid = '1') then
408
        res_o <= res_out(op_andn_c)  or res_out(op_orn_c)   or res_out(op_xnor_c) or
409
                 res_out(op_clz_c)   or res_out(op_cpop_c)  or -- res_out(op_ctz_c) is unused here
410
                 res_out(op_min_c)   or -- res_out(op_max_c) is unused here
411
                 res_out(op_sextb_c) or res_out(op_sexth_c) or res_out(op_zexth_c) or
412
                 res_out(op_ror_c)   or res_out(op_rol_c)   or
413
                 res_out(op_orcb_c)  or res_out(op_rev8_c);
414
      end if;
415
    end if;
416
  end process output_gate;
417
 
418
  -- valid output --
419
  valid_o <= valid;
420
 
421
 
422
end neorv32_cpu_cp_bitmanip_rtl;

powered by: WebSVN 2.1.0

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