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

Subversion Repositories cordic

[/] [cordic/] [trunk/] [polar2rect/] [p2r_CordicPipe.vhd] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 rherveille
--
2
-- file: p2r_CordicPipe.vhd
3
-- author: Richard Herveille
4
-- rev. 1.0 initial release
5
 
6
library ieee;
7
use ieee.std_logic_1164.all;
8
use ieee.std_logic_arith.all;
9
 
10
entity p2r_CordicPipe is
11
        generic(
12
                WIDTH   : natural := 16;
13
                PIPEID  : natural := 1
14
        );
15
        port(
16
                clk             : in std_logic;
17
                ena             : in std_logic;
18
 
19
                Xi              : in signed(WIDTH -1 downto 0);
20
                Yi              : in signed(WIDTH -1 downto 0);
21
                Zi              : in signed(19 downto 0);
22
 
23
                Xo              : out signed(WIDTH -1 downto 0);
24
                Yo              : out signed(WIDTH -1 downto 0);
25
                Zo              : out signed(19 downto 0)
26
        );
27
end entity p2r_CordicPipe;
28
 
29
architecture dataflow of p2r_CordicPipe is
30
 
31
        --
32
        -- functions
33
        --
34
 
35
        -- Function CATAN (constante arc-tangent).
36
        -- This is a lookup table containing pre-calculated arc-tangents.
37
        -- 'n' is the number of the pipe, returned is a 20bit arc-tangent value.
38
        -- The numbers are calculated as follows: Z(n) = atan(1/2^n)
39
        -- examples:
40
        -- 20bit values => 2^20 = 2pi(rad)
41
        --                 1(rad) = 2^20/2pi = 166886.053....
42
        -- n:0, atan(1/1) = 0.7853...(rad)
43
        --      0.7853... * 166886.053... = 131072(dec) = 20000(hex)
44
        -- n:1, atan(1/2) = 0.4636...(rad)
45
        --      0.4636... * 166886.053... = 77376.32(dec) = 12E40(hex)
46
        -- n:2, atan(1/4) = 0.2449...(rad)
47
        --      0.2449... * 166886.053... = 40883.52(dec) = 9FB3(hex)
48
        -- n:3, atan(1/8) = 0.1243...(rad)
49
        --      0.1243... * 166886.053... = 20753.11(dec) = 5111(hex)
50
        --
51
        function CATAN(n :natural) return integer is
52
        variable result :integer;
53
        begin
54
                case n is
55
                        when 0 => result := 16#020000#;
56
                        when 1 => result := 16#012E40#;
57
                        when 2 => result := 16#09FB4#;
58
                        when 3 => result := 16#05111#;
59
                        when 4 => result := 16#028B1#;
60
                        when 5 => result := 16#0145D#;
61
                        when 6 => result := 16#0A2F#;
62
                        when 7 => result := 16#0518#;
63
                        when 8 => result := 16#028C#;
64
                        when 9 => result := 16#0146#;
65
                        when 10 => result := 16#0A3#;
66
                        when 11 => result := 16#051#;
67
                        when 12 => result := 16#029#;
68
                        when 13 => result := 16#014#;
69
                        when 14 => result := 16#0A#;
70
                        when 15 => result := 16#05#;
71
                        when 16 => result := 16#03#;
72
                        when 17 => result := 16#01#;
73
                        when others => result := 16#0#;
74
                end case;
75
                return result;
76
        end CATAN;
77
 
78
        -- function Delta is actually an arithmatic shift right
79
        -- This strange construction is needed for compatibility with Xilinx WebPack
80
        function Delta(Arg : signed; Cnt : natural) return signed is
81
                variable tmp : signed(Arg'range);
82
                constant lo : integer := Arg'high -cnt +1;
83
        begin
84
                for n in Arg'high downto lo loop
85
                        tmp(n) := Arg(Arg'high);
86
                end loop;
87
                for n in Arg'high -cnt downto 0 loop
88
                        tmp(n) := Arg(n +cnt);
89
                end loop;
90
                return tmp;
91
        end function Delta;
92
 
93
        function AddSub(dataa, datab : in signed; add_sub : in std_logic) return signed is
94
        begin
95
                if (add_sub = '1') then
96
                        return dataa + datab;
97
                else
98
                        return dataa - datab;
99
                end if;
100
        end;
101
 
102
        --
103
        --      ARCHITECTURE BODY
104
        --
105
        signal dX, Xresult      : signed(WIDTH -1 downto 0);
106
        signal dY, Yresult      : signed(WIDTH -1 downto 0);
107
        signal atan, Zresult    : signed(19 downto 0);
108
 
109
        signal Zneg, Zpos       : std_logic;
110
 
111
begin
112
 
113
        dX <= Delta(Xi, PIPEID);
114
        dY <= Delta(Yi, PIPEID);
115
        atan <= conv_signed( catan(PIPEID), 20);
116
 
117
        -- generate adder structures
118
        Zneg <= Zi(19);
119
        Zpos <= not Zi(19);
120
 
121
        -- xadd
122
  Xresult <= AddSub(Xi, dY, Zneg);
123
 
124
        -- yadd 
125
        Yresult <= AddSub(Yi, dX, Zpos);
126
 
127
        -- zadd
128
        Zresult <= AddSub(Zi, atan, Zneg);
129
 
130
        gen_regs: process(clk)
131
        begin
132
                if(clk'event and clk='1') then
133
                        if (ena = '1') then
134
                                Xo <= Xresult;
135
                                Yo <= Yresult;
136
                                Zo <= Zresult;
137
                        end if;
138
                end if;
139
        end process;
140
 
141
end architecture dataflow;

powered by: WebSVN 2.1.0

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