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

Subversion Repositories astron_requantizer

[/] [astron_requantizer/] [trunk/] [common_resize.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3 3 danv
-- Copyright 2020
4 2 danv
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6 3 danv
-- 
7
-- Licensed under the Apache License, Version 2.0 (the "License");
8
-- you may not use this file except in compliance with the License.
9
-- You may obtain a copy of the License at
10
-- 
11
--     http://www.apache.org/licenses/LICENSE-2.0
12
-- 
13
-- Unless required by applicable law or agreed to in writing, software
14
-- distributed under the License is distributed on an "AS IS" BASIS,
15
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
-- See the License for the specific language governing permissions and
17
-- limitations under the License.
18 2 danv
--
19
-------------------------------------------------------------------------------
20
 
21
LIBRARY ieee, common_pkg_lib, common_components_lib;
22
USE ieee.std_logic_1164.ALL;
23
USE ieee.numeric_std.ALL;
24
USE common_pkg_lib.common_pkg.ALL;
25
 
26
ENTITY common_resize IS
27
  GENERIC (
28
    g_representation  : STRING  := "SIGNED";  -- SIGNED or UNSIGNED resizing
29
    g_clip            : BOOLEAN := FALSE;     -- when TRUE clip input if it is outside the output range, else wrap
30
    g_clip_symmetric  : BOOLEAN := FALSE;     -- when TRUE clip signed symmetric to +c_smax and -c_smax, else to +c_smax and c_smin_symm
31
                                              -- for wrapping when g_clip=FALSE the g_clip_symmetric is ignored, so signed wrapping is done asymmetric
32
    g_pipeline_input  : NATURAL := 0;         -- >= 0
33
    g_pipeline_output : NATURAL := 1;         -- >= 0
34
    g_in_dat_w        : INTEGER := 36;
35
    g_out_dat_w       : INTEGER := 18
36
  );
37
  PORT (
38
    clk        : IN  STD_LOGIC;
39
    clken      : IN  STD_LOGIC := '1';
40
    in_dat     : IN  STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
41
    out_dat    : OUT STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
42
    out_ovr    : OUT STD_LOGIC
43
  );
44
END;
45
 
46
 
47
ARCHITECTURE rtl OF common_resize IS
48
 
49
  -- Clipping is only necessary when g_out_dat_w<g_in_dat_w.
50
  CONSTANT c_clip      : BOOLEAN := g_clip AND (g_out_dat_w<g_in_dat_w);
51
 
52
  -- Use SIGNED, UNSIGNED to avoid NATURAL (32 bit range) overflow error
53
  CONSTANT c_umax      : UNSIGNED(out_dat'RANGE) := UNSIGNED(      c_slv1(g_out_dat_w-1 DOWNTO 0));  -- =  2** g_out_dat_w   -1
54
  CONSTANT c_smax      :   SIGNED(out_dat'RANGE) :=   SIGNED('0' & c_slv1(g_out_dat_w-2 DOWNTO 0));  -- =  2**(g_out_dat_w-1)-1
55
  CONSTANT c_smin_most :   SIGNED(out_dat'RANGE) :=   SIGNED('1' & c_slv0(g_out_dat_w-2 DOWNTO 0));  -- = -2**(c_in_dat_w-1)
56
  CONSTANT c_smin_symm :   SIGNED(out_dat'RANGE) := -c_smax;                                         -- = -2**(c_in_dat_w-1)+1
57
  CONSTANT c_smin      :   SIGNED(out_dat'RANGE) := sel_a_b(g_clip_symmetric, c_smin_symm, c_smin_most);
58
 
59
  SIGNAL reg_dat     : STD_LOGIC_VECTOR(in_dat'RANGE);
60
  SIGNAL wrap        : STD_LOGIC;
61
  SIGNAL clip        : STD_LOGIC;
62
  SIGNAL sign        : STD_LOGIC;
63
  SIGNAL res_ovr     : STD_LOGIC;
64
  SIGNAL res_dat     : STD_LOGIC_VECTOR(out_dat'RANGE);
65
  SIGNAL res_vec     : STD_LOGIC_VECTOR(g_out_dat_w DOWNTO 0);
66
  SIGNAL out_vec     : STD_LOGIC_VECTOR(g_out_dat_w DOWNTO 0);
67
 
68
BEGIN
69
 
70
  u_input_pipe : ENTITY common_components_lib.common_pipeline  -- pipeline input
71
  GENERIC MAP (
72
    g_representation => "SIGNED",
73
    g_pipeline       => g_pipeline_input,
74
    g_in_dat_w       => g_in_dat_w,
75
    g_out_dat_w      => g_in_dat_w
76
  )
77
  PORT MAP (
78
    clk     => clk,
79
    clken   => clken,
80
    in_dat  => in_dat,
81
    out_dat => reg_dat
82
  );
83
 
84
  no_clip : IF c_clip=FALSE GENERATE
85
    -- Note that g_pipeline_input=0 AND g_clip=FALSE is equivalent to using RESIZE_SVEC or RESIZE_UVEC directly.
86
    gen_s : IF g_representation="SIGNED" GENERATE
87
      -- If g_out_dat_w>g_in_dat_w then IEEE resize extends the sign bit,
88
      -- else IEEE resize preserves the sign bit and keeps the low part.
89
      wrap <= '1' WHEN SIGNED(reg_dat)>c_smax OR SIGNED(reg_dat)< c_smin_most ELSE '0';
90
      res_dat <= RESIZE_SVEC(reg_dat, g_out_dat_w);
91
      res_ovr <= wrap;
92
    END GENERATE;
93
 
94
    gen_u : IF g_representation="UNSIGNED" GENERATE
95
      -- If g_out_dat_w>g_in_dat_w then IEEE resize sign extends with '0',
96
      -- else IEEE resize keeps the low part.
97
      wrap <= '1' WHEN UNSIGNED(reg_dat)>c_umax ELSE '0';
98
      res_dat <= RESIZE_UVEC(reg_dat, g_out_dat_w);
99
      res_ovr <= wrap;
100
    END GENERATE;
101
  END GENERATE;
102
 
103
  gen_clip : IF c_clip=TRUE GENERATE
104
    gen_s_clip : IF g_representation="SIGNED" GENERATE
105
      clip <= '1' WHEN SIGNED(reg_dat)>c_smax OR SIGNED(reg_dat)< c_smin ELSE '0';
106
      sign <= reg_dat(reg_dat'HIGH);
107
      res_dat <= reg_dat(out_dat'RANGE) WHEN clip='0' ELSE STD_LOGIC_VECTOR( c_smax) WHEN sign='0' ELSE STD_LOGIC_VECTOR(c_smin);
108
      res_ovr <= clip;
109
    END GENERATE;
110
 
111
    gen_u_clip : IF g_representation="UNSIGNED" GENERATE
112
      clip <= '1' WHEN UNSIGNED(reg_dat)>c_umax ELSE '0';
113
      res_dat <= reg_dat(out_dat'RANGE) WHEN clip='0' ELSE STD_LOGIC_VECTOR(c_umax);
114
      res_ovr <= clip;
115
    END GENERATE;
116
  END GENERATE;
117
 
118
  res_vec <= res_ovr & res_dat;
119
 
120
  u_output_pipe : ENTITY common_components_lib.common_pipeline  -- pipeline output
121
  GENERIC MAP (
122
    g_representation => "SIGNED",
123
    g_pipeline       => g_pipeline_output,
124
    g_in_dat_w       => g_out_dat_w+1,
125
    g_out_dat_w      => g_out_dat_w+1
126
  )
127
  PORT MAP (
128
    clk     => clk,
129
    clken   => clken,
130
    in_dat  => res_vec,
131
    out_dat => out_vec
132
  );
133
 
134
  out_ovr <= out_vec(g_out_dat_w);
135
  out_dat <= out_vec(g_out_dat_w-1 DOWNTO 0);
136
 
137
END rtl;

powered by: WebSVN 2.1.0

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