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

Subversion Repositories mkjpeg

[/] [mkjpeg/] [trunk/] [design/] [quantizer/] [s_divider.vhd] - Blame information for rev 61

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

Line No. Rev Author Line
1 25 mikel262
--------------------------------------------------------------------------------
2
--                                                                            --
3
--                          V H D L    F I L E                                --
4
--                          COPYRIGHT (C) 2006-2009                           --
5
--                                                                            --
6
--------------------------------------------------------------------------------
7
--                                                                            --
8
-- Title       : DIVIDER                                                      --
9
-- Design      : Signed Pipelined Divider core                                --
10
-- Author      : Michal Krepa                                                 --
11
--                                                                            --
12
--------------------------------------------------------------------------------
13
--                                                                            --
14
-- File        : S_DIVIDER.VHD                                                --
15
-- Created     : Sat Aug 26 2006                                              --
16
-- Modified    : Thu Mar 12 2009                                              --
17
--                                                                            --
18
--------------------------------------------------------------------------------
19
--                                                                            --
20
--  Description : Signed Pipelined Divider                                    --
21
--                                                                            --
22
-- dividend allowable range of -2**SIZE_C to 2**SIZE_C-1 [SIGNED number]      --
23
-- divisor allowable range of 1 to (2**SIZE_C)/2-1 [UNSIGNED number]          --
24
-- pipeline latency is 2*SIZE_C+2 (time from latching input to result ready)  --
25
-- when pipeline is full new result is generated every clock cycle            --
26
-- Non-Restoring division algorithm                                           --
27
-- Use SIZE_C constant in divider entity to adjust bit width                  --
28
--------------------------------------------------------------------------------
29
 
30
--------------------------------------------------------------------------------
31
-- MAIN DIVIDER top level
32
--------------------------------------------------------------------------------
33
library IEEE;
34
  use IEEE.STD_LOGIC_1164.All;
35
  use IEEE.NUMERIC_STD.all;
36
 
37
entity s_divider is
38
  generic
39
  (
40
       SIZE_C          : INTEGER := 32
41
  ) ;            -- SIZE_C: Number of bits
42
  port
43
  (
44
       rst   : in  STD_LOGIC;
45
       clk   : in  STD_LOGIC;
46
       a     : in  STD_LOGIC_VECTOR(SIZE_C-1 downto 0) ;
47
       d     : in  STD_LOGIC_VECTOR(SIZE_C-1 downto 0) ;
48
 
49
       q     : out STD_LOGIC_VECTOR(SIZE_C-1 downto 0) ;
50
       r     : out STD_LOGIC_VECTOR(SIZE_C-1 downto 0) ;
51
       round : out STD_LOGIC
52
  ) ;
53
end s_divider ;
54
 
55
architecture str of s_divider is
56
 
57
  type S_ARRAY  is array(0 to SIZE_C+3) of unsigned(SIZE_C-1 downto 0);
58
  type S2_ARRAY is array(0 to SIZE_C+1) of unsigned(2*SIZE_C-1 downto 0);
59
 
60
  signal d_s          : S_ARRAY;
61
  signal q_s          : S_ARRAY;
62
  signal r_s          : S2_ARRAY;
63
  signal diff         : S_ARRAY;
64
  signal qu_s         : STD_LOGIC_VECTOR(SIZE_C-1 downto 0);
65
  signal ru_s         : unsigned(SIZE_C-1 downto 0);
66
  signal qu_s2        : STD_LOGIC_VECTOR(SIZE_C-1 downto 0);
67
  signal ru_s2        : unsigned(SIZE_C-1 downto 0);
68
  signal d_reg        : STD_LOGIC_VECTOR(SIZE_C-1 downto 0);
69
  signal pipeline_reg : STD_LOGIC_VECTOR(SIZE_C+3-1 downto 0);
70
  signal r_reg        : STD_LOGIC_VECTOR(SIZE_C-1 downto 0);
71
 
72
begin
73
 
74
 pipeline : process(clk,rst)
75
 begin
76
   if rst = '1' then
77
     for k in 0 to SIZE_C loop
78
       r_s(k) <= (others => '0');
79
       q_s(k) <= (others => '0');
80
       d_s(k) <= (others => '0');
81
     end loop;
82
     pipeline_reg <= (others => '0');
83
   elsif clk = '1' and clk'event then
84
 
85
     -- negative number
86
     if a(SIZE_C-1) = '1' then
87
       -- negate negative number to create positive
88
       r_s(0)       <= unsigned(resize(unsigned(not(SIGNED(a)) + TO_SIGNED(1,SIZE_C)),2*SIZE_C));
89
       -- left shift
90
       pipeline_reg <= pipeline_reg(pipeline_reg'high-1 downto 0) & '1';
91
     else
92
       r_s(0)       <= resize(unsigned(a),2*SIZE_C);
93
       -- left shift
94
       pipeline_reg <= pipeline_reg(pipeline_reg'high-1 downto 0) & '0';
95
     end if;
96
     d_s(0) <= unsigned(d);
97
     q_s(0) <= (others => '0');
98
 
99
     -- pipeline
100
     for k in 0 to SIZE_C loop
101
       -- test remainder if positive/negative
102
       if r_s(k)(2*SIZE_C-1) = '0' then
103
         -- shift r_tmp one bit left and subtract d_tmp from upper part of r_tmp 
104
         r_s(k+1)(2*SIZE_C-1 downto SIZE_C) <= r_s(k)(2*SIZE_C-2 downto SIZE_C-1) - d_s(k);
105
       else
106
         r_s(k+1)(2*SIZE_C-1 downto SIZE_C) <= r_s(k)(2*SIZE_C-2 downto SIZE_C-1) + d_s(k);
107
       end if;
108
       -- shift r_tmp one bit left (lower part)
109
       r_s(k+1)(SIZE_C-1 downto 0) <= r_s(k)(SIZE_C-2 downto 0) & '0';
110
 
111
       if diff(k)(SIZE_C-1) = '0' then
112
         q_s(k+1) <= q_s(k)(SIZE_C-2 downto 0) & '1';
113
       else
114
         q_s(k+1) <= q_s(k)(SIZE_C-2 downto 0) & '0';
115
       end if;
116
 
117
       d_s(k+1) <= d_s(k);
118
     end loop;
119
   end if;
120
 end process;
121
 
122
 G_DIFF: for x in 0 to SIZE_C generate
123
   diff(x) <= r_s(x)(2*SIZE_C-2 downto SIZE_C-1) - d_s(x) when r_s(x)(2*SIZE_C-1) = '0'
124
              else r_s(x)(2*SIZE_C-2 downto SIZE_C-1) + d_s(x);
125
 end generate G_DIFF;
126
 
127
 qu_s <= STD_LOGIC_VECTOR( q_s(SIZE_C) );
128
 ru_s <= r_s(SIZE_C)(2*SIZE_C-1 downto SIZE_C);
129
 
130
 process(clk,rst)
131
 begin
132
   if rst = '1' then
133
     q     <= (others => '0');
134
     r_reg <= (others => '0');
135
     round <= '0';
136
   elsif clk = '1' and clk'event then
137
 
138
 
139
     if ru_s(SIZE_C-1) = '0' then
140
       ru_s2 <= (ru_s);
141
     else
142
       ru_s2 <= (unsigned(ru_s) + d_s(SIZE_C));
143
     end if;
144
     qu_s2 <= qu_s;
145
 
146
     -- negative number
147
     if pipeline_reg(SIZE_C+1) = '1' then
148
       -- negate positive number to create negative
149
       q <= STD_LOGIC_VECTOR(not(SIGNED(qu_s2)) + TO_SIGNED(1,SIZE_C));
150
       r_reg <= STD_LOGIC_VECTOR(not(SIGNED(ru_s2)) + TO_SIGNED(1,SIZE_C));
151
     else
152
       q <= STD_LOGIC_VECTOR(qu_s2);
153
       r_reg <= STD_LOGIC_VECTOR(ru_s2);
154
     end if;
155
 
156
     -- if 2*remainder >= divisor then add 1 to round to nearest integer
157
     if (ru_s2(SIZE_C-2 downto 0) & '0') >= d_s(SIZE_C+1) then
158
       round <= '1';
159
     else
160
       round <= '0';
161
     end if;
162
   end if;
163
 end process;
164
 
165
 -- remainder
166
 r <= r_reg;
167
 
168
end str;
169
 
170
 

powered by: WebSVN 2.1.0

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