通过VHDL中的查找表使用sin和cos

时间:2015-05-22 09:36:35

标签: vhdl

我在VHDL中使用sin / cos查找表称为sincos_lut.vhd,并且在使用我的代码时遇到错误。我正在实现我的数据路径,我需要在整数值上执行sin和cos。我不知道我的问题在哪里,但这里是代码和错误:

library IEEE;
use  IEEE.STD_LOGIC_1164.all;
use  IEEE.STD_LOGIC_ARITH.all;
use  IEEE.STD_LOGIC_UNSIGNED.all;
use  IEEE.MATH_REAL.all;



entity DFT is
port(
        clk_en, clk, reset, Clock: std_logic;
        t_sel,K_sel,sr_sel,si_sel,ld_t,ld_K,ld_sumreal,ld_sumimag,ld_angle: in std_logic;
        N: in integer;
        e: in std_logic_vector(3 downto 0);
        outreal, outimag: out integer;
        sig1, sig2: out std_logic
        );

    end DFT;

architecture str of DFT is

component Adder
Port(     a, b: in integer;
          f: out integer
          );
end component;

component Reg
    Port(
    Clk: in std_logic;
          ld: in std_logic;
          a: in integer;
          f: out integer
          );
end component;


component Mul
    Port( 
          a, b: in integer;
          f: out integer
          );
end component;

component LT 
    Port(
          a, b: in integer;
          sig: out std_logic
          );
end component;

component Div
Port( 
          a, b: in integer;
          f: out integer
          );
end component;


component Mux 
    Port( 
          sel: in std_logic;
          a, b: in integer;
          f: out integer
          );
end component;

component Mem
port(   Clock:      in std_logic;   
    Read:       in std_logic;
    Write:      in std_logic;
    Address:    in integer;
    Data_in:    in integer;
    Data_out:   out integer
);
end component;



component sincos_lut Port
(
   reset           : in  std_logic;
   clk             : in  std_logic;
   clk_en          : in  std_logic;
   theta           : in  integer;
   sin_data        : out signed(integer);
   cos_data        : out signed(integer)
);
end component;


signal s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s20,s21,s22,s23,s24,s25,s26,s30,s31,s32,s33 : integer; 
constant  MATH_PI :  real := 3.14159_26535_89793_23846; 

begin
G1: Mux port map(K_sel,0,s1,s2);
G2: Mux port map(t_sel,0,s3,s4);
G3: Reg port map(Clk,ld_K,s2,s5);
G4: Reg port map(Clk,ld_t,s4,s6);
G5: LT port map(s5,N,sig1);
G6: LT port map(s6,N,sig2);
G7: Adder port map(s5,1,s1);
G8: Adder port map(s6,1,s3);
G9: Div port map(s5,N,s7);
G10: Mul port map(s7,s6,s8);
G11: Mul port map(s8,integer(MATH_PI),s9);
G12: Mul port map(s9,2,s10);
G13: Reg port map(Clk, ld_angle,s10,s11);
G14: Mem port map(Clock,'1','0',s6,0,s12);
G15: Mem port map(Clock,'1','0',s6,0,s13);
G16: Mul port map(s12,s33,s14);
G17: Mul port map(s13,s30,s15);
G18: Adder port map(s14,s15,s16);
G19: Mux port map(sr_sel,0,s17,s18);
G20: Reg port map(Clk, ld_sumreal,s18,s19);
G21: Adder port map(s16,s19,s17);
G22: Mul port map(s12, -1,s20);
G31: sincos_lut port map(reset, clk, clk_en, s11, s30, s31);
G32: sincos_lut port map(reset, clk, clk_en, s11, s32, s33);
G23: Mul port map(s20, s30, s21);
G24: Mul port map(s13, s33, s22);
G25: Adder port map(s21, s22,s23);
G26: Mux port map(si_sel,0,s24,s25);
G27: Reg port map(Clk, ld_sumimag,s25,s26);
G28: Adder port map(s23,s26,s24);
G29: Mem port map(Clock, '0','1',s5,outimag);
G30: Mem port map(Clk, '0','1',s5,outreal);

sincos_lut

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity sincos_lut is
port
(
   reset           : in  std_logic;
   clk             : in  std_logic;
   clk_en          : in  std_logic;
   theta           : in  integer;
   sin_data        : out signed(integer);
   cos_data        : out signed(integer)
);
end sincos_lut;


architecture rtl of sincos_lut is

   signal theta_int      : integer range 0 to 4095 := 0;
   signal sin_data_int   : signed(integer);
   signal cos_data_int   : signed(integer);

begin


theta_int <= theta;


process(reset,clk)
begin
   if(reset = '1')then
       sin_data_int <= to_signed(0,12); 
       cos_data_int <= to_signed(0,12);
   elsif(rising_edge(clk)) then
      if clk_en = '1' then

         sin_data <= sin_data_int;
         cos_data <= cos_data_int;

         case theta_int is


    end str;

错误:

  

错误(10476):DFT.vhd(119)处的VHDL错误:标识符的类型&#34; s30&#34;不同意其用法&#34; SIGNED&#34;键入
  错误(10558):DFT.vhd(119)处的VHDL错误:无法关联正式端口&#34; sin_data&#34;模式&#34; out&#34;用表达式   错误(10476):DFT.vhd(119)处的VHDL错误:标识符的类型&#34; s31&#34;不同意其用法&#34; SIGNED&#34;键入
  错误(10558):DFT.vhd(119)处的VHDL错误:无法关联正式端口&#34; cos_data&#34;模式&#34; out&#34;用表达式

第119行是:

G31: sincos_lut port map(reset, clk, clk_en, s11, s30, s31);

3 个答案:

答案 0 :(得分:0)

您的错误是因为s30和s31是整数,您将它们连接到已签名的端口。

凯文。

答案 1 :(得分:0)

 type of identifier "s30" does not agree with its usage as "SIGNED" type

此错误是由混合不同类型引起的。 s30的类型是整数,但您尝试将其映射到signed的类型的端口。

cannot associate formal port "sin_data" of mode "out" with an expression

此错误通常是由“读取”逻辑中的输出端口引起的,但我没有看到此错误的明确原因。可能这与您的类型端口有关:signed(整数)。 Signed()用于类型转换。

答案 2 :(得分:0)

您的代码不是Minimal, Complete, and Verifiable example。请注意,你的sincos_lut也不会分析。

signal s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s20,s21,s22,s23,s24,s25,s26,s30,s31,s32,s33 : integer; 
constant  MATH_PI :  real := 3.14159_26535_89793_23846; 

    signal signed_s30:  signed (11 downto 0);
    signal signed_s31:  signed (11 downto 0);
    signal signed_s32:  signed (11 downto 0);
    signal signed_s33:  signed (11 downto 0);

begin

    s30 <= to_integer(signed_s30);
    s31 <= to_integer(signed_s31);
    s32 <= to_integer(signed_s32);    
    s33 <= to_integer(signed_s33);

您可以创建s30,s31,s32和s33的签名版本并进行转换 并将它们分配给s30,s31,s32,s33。

另请注意,sincos_lut中存在相关错误,包括端口声明和信号声明。类型名称不表示范围约束。这些已经修复:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity sincos_lut is
port
(
   reset           : in  std_logic;
   clk             : in  std_logic;
   clk_en          : in  std_logic;
   theta           : in  integer;
   sin_data        : out signed(11 downto 0); -- integer);
   cos_data        : out signed(11 downto 0) -- integer)
);
end sincos_lut;


architecture rtl of sincos_lut is

   signal theta_int      : integer range 0 to 4095 := 0;
   signal sin_data_int   : signed(11 downto 0); -- integer);
   signal cos_data_int   : signed(11 downto 0); -- integer);

签名值的范围(实际上是长度)由流程中的to_signed函数调用确定。

注意使用包numeric_std函数to_integer,以及dft

library ieee;
use  ieee.std_logic_1164.all;
-- use  ieee.std_logic_arith.all;
-- use  ieee.std_logic_unsigned.all;
-- use  ieee.math_real.all;
use ieee.numeric_std.all;  -- never, never mix std_logic_arith/numeric_std
                           -- (see sincos_lut)

两个不同包中的类型声明是唯一的,无论它们是否具有相同的名称和基本类型。它们不兼容。如果你的工具让你不符合VHDL标准。

G31: sincos_lut port map(reset, clk, clk_en, s11, signed_s30, signed_s31);
G32: sincos_lut port map(reset, clk, clk_en, s11, signed_s32, signed_s33);

那些错误,但又揭示了两个错误:

G29: Mem port map(Clock, '0','1',s5,outimag);
G30: Mem port map(Clk, '0','1',s5,outreal);

如果你查看你的mem组件和实例端口映射中的位置关联列表,你会发现你缺少一个表示Address的这两个整数参数。

我认为你没有从某人那里透露出足够的“宝贵”知识产权来告诉我们应该在这里连接什么。这是寻求帮助的价格的一部分,显示你得到了什么。当有人告诉你这不是一个最小的例子时,在这种情况下,它会丢弃组件实例化和与实际错误报告无关的信号。

还要注意混合使用无约束整数,最终可能在合成中隐含32位值。你应该小心并限制你所能做的一切。

例如,定义到Mem组件的整数地址的范围约束定义了内存的大小。

虚拟信号地址,整数并将其插入组件允许dft完成分析:

G29: Mem port map(Clock, '0','1',Address,s5,outimag);
G30: Mem port map(Clk, '0','1',Address,s5,outreal);

如果没有为所有实例化组件假设实体和体系结构对或者消除它们(这将导致您稍后提出第二个问题),则无法详细说明您的设计。

(并且您可以从sincos_lut实体/体系结构对生成整数,但没有可能是32位值的范围约束。)