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 2

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

Line No. Rev Author Line
1 2 danv
-------------------------------------------------------------------------------
2
--
3
-- Copyright (C) 2009
4
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
5
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
6
--
7
-- This program is free software: you can redistribute it and/or modify
8
-- it under the terms of the GNU General Public License as published by
9
-- the Free Software Foundation, either version 3 of the License, or
10
-- (at your option) any later version.
11
--
12
-- This program is distributed in the hope that it will be useful,
13
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
14
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
-- GNU General Public License for more details.
16
--
17
-- You should have received a copy of the GNU General Public License
18
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
--
20
-------------------------------------------------------------------------------
21
 
22
LIBRARY ieee, common_pkg_lib, common_components_lib;
23
USE ieee.std_logic_1164.ALL;
24
USE ieee.numeric_std.ALL;
25
USE common_pkg_lib.common_pkg.ALL;
26
 
27
ENTITY common_resize IS
28
  GENERIC (
29
    g_representation  : STRING  := "SIGNED";  -- SIGNED or UNSIGNED resizing
30
    g_clip            : BOOLEAN := FALSE;     -- when TRUE clip input if it is outside the output range, else wrap
31
    g_clip_symmetric  : BOOLEAN := FALSE;     -- when TRUE clip signed symmetric to +c_smax and -c_smax, else to +c_smax and c_smin_symm
32
                                              -- for wrapping when g_clip=FALSE the g_clip_symmetric is ignored, so signed wrapping is done asymmetric
33
    g_pipeline_input  : NATURAL := 0;         -- >= 0
34
    g_pipeline_output : NATURAL := 1;         -- >= 0
35
    g_in_dat_w        : INTEGER := 36;
36
    g_out_dat_w       : INTEGER := 18
37
  );
38
  PORT (
39
    clk        : IN  STD_LOGIC;
40
    clken      : IN  STD_LOGIC := '1';
41
    in_dat     : IN  STD_LOGIC_VECTOR(g_in_dat_w-1 DOWNTO 0);
42
    out_dat    : OUT STD_LOGIC_VECTOR(g_out_dat_w-1 DOWNTO 0);
43
    out_ovr    : OUT STD_LOGIC
44
  );
45
END;
46
 
47
 
48
ARCHITECTURE rtl OF common_resize IS
49
 
50
  -- Clipping is only necessary when g_out_dat_w<g_in_dat_w.
51
  CONSTANT c_clip      : BOOLEAN := g_clip AND (g_out_dat_w<g_in_dat_w);
52
 
53
  -- Use SIGNED, UNSIGNED to avoid NATURAL (32 bit range) overflow error
54
  CONSTANT c_umax      : UNSIGNED(out_dat'RANGE) := UNSIGNED(      c_slv1(g_out_dat_w-1 DOWNTO 0));  -- =  2** g_out_dat_w   -1
55
  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
56
  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)
57
  CONSTANT c_smin_symm :   SIGNED(out_dat'RANGE) := -c_smax;                                         -- = -2**(c_in_dat_w-1)+1
58
  CONSTANT c_smin      :   SIGNED(out_dat'RANGE) := sel_a_b(g_clip_symmetric, c_smin_symm, c_smin_most);
59
 
60
  SIGNAL reg_dat     : STD_LOGIC_VECTOR(in_dat'RANGE);
61
  SIGNAL wrap        : STD_LOGIC;
62
  SIGNAL clip        : STD_LOGIC;
63
  SIGNAL sign        : STD_LOGIC;
64
  SIGNAL res_ovr     : STD_LOGIC;
65
  SIGNAL res_dat     : STD_LOGIC_VECTOR(out_dat'RANGE);
66
  SIGNAL res_vec     : STD_LOGIC_VECTOR(g_out_dat_w DOWNTO 0);
67
  SIGNAL out_vec     : STD_LOGIC_VECTOR(g_out_dat_w DOWNTO 0);
68
 
69
BEGIN
70
 
71
  u_input_pipe : ENTITY common_components_lib.common_pipeline  -- pipeline input
72
  GENERIC MAP (
73
    g_representation => "SIGNED",
74
    g_pipeline       => g_pipeline_input,
75
    g_in_dat_w       => g_in_dat_w,
76
    g_out_dat_w      => g_in_dat_w
77
  )
78
  PORT MAP (
79
    clk     => clk,
80
    clken   => clken,
81
    in_dat  => in_dat,
82
    out_dat => reg_dat
83
  );
84
 
85
  no_clip : IF c_clip=FALSE GENERATE
86
    -- Note that g_pipeline_input=0 AND g_clip=FALSE is equivalent to using RESIZE_SVEC or RESIZE_UVEC directly.
87
    gen_s : IF g_representation="SIGNED" GENERATE
88
      -- If g_out_dat_w>g_in_dat_w then IEEE resize extends the sign bit,
89
      -- else IEEE resize preserves the sign bit and keeps the low part.
90
      wrap <= '1' WHEN SIGNED(reg_dat)>c_smax OR SIGNED(reg_dat)< c_smin_most ELSE '0';
91
      res_dat <= RESIZE_SVEC(reg_dat, g_out_dat_w);
92
      res_ovr <= wrap;
93
    END GENERATE;
94
 
95
    gen_u : IF g_representation="UNSIGNED" GENERATE
96
      -- If g_out_dat_w>g_in_dat_w then IEEE resize sign extends with '0',
97
      -- else IEEE resize keeps the low part.
98
      wrap <= '1' WHEN UNSIGNED(reg_dat)>c_umax ELSE '0';
99
      res_dat <= RESIZE_UVEC(reg_dat, g_out_dat_w);
100
      res_ovr <= wrap;
101
    END GENERATE;
102
  END GENERATE;
103
 
104
  gen_clip : IF c_clip=TRUE GENERATE
105
    gen_s_clip : IF g_representation="SIGNED" GENERATE
106
      clip <= '1' WHEN SIGNED(reg_dat)>c_smax OR SIGNED(reg_dat)< c_smin ELSE '0';
107
      sign <= reg_dat(reg_dat'HIGH);
108
      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);
109
      res_ovr <= clip;
110
    END GENERATE;
111
 
112
    gen_u_clip : IF g_representation="UNSIGNED" GENERATE
113
      clip <= '1' WHEN UNSIGNED(reg_dat)>c_umax ELSE '0';
114
      res_dat <= reg_dat(out_dat'RANGE) WHEN clip='0' ELSE STD_LOGIC_VECTOR(c_umax);
115
      res_ovr <= clip;
116
    END GENERATE;
117
  END GENERATE;
118
 
119
  res_vec <= res_ovr & res_dat;
120
 
121
  u_output_pipe : ENTITY common_components_lib.common_pipeline  -- pipeline output
122
  GENERIC MAP (
123
    g_representation => "SIGNED",
124
    g_pipeline       => g_pipeline_output,
125
    g_in_dat_w       => g_out_dat_w+1,
126
    g_out_dat_w      => g_out_dat_w+1
127
  )
128
  PORT MAP (
129
    clk     => clk,
130
    clken   => clken,
131
    in_dat  => res_vec,
132
    out_dat => out_vec
133
  );
134
 
135
  out_ovr <= out_vec(g_out_dat_w);
136
  out_dat <= out_vec(g_out_dat_w-1 DOWNTO 0);
137
 
138
END rtl;

powered by: WebSVN 2.1.0

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