⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 新建 文本文档.txt

📁 用vhdl实现一个fir滤波器 设计要求: 1.最小阻带衰减-30db。 2.带内波动小于1db. 3.用MATLIB与MAXPLUS2联合设计与仿真
💻 TXT
字号:

程序一:
1.	移位寄存器:
   

library ieee;
use ieee.std_logic_1164.all;
entity reg is
  port(clk,reset:in std_logic;
       data:in std_logic_vector(7 downto 0);--输入的数据
       outdata:out std_logic_vector(7 downto 0)); --输出的数据
   end entity;
architecture arch of reg is
signal s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17:std_logic_vector(7 downto 0);        --共用18个8位的寄存器
   begin
    process(clk,reset) is
     begin
       if reset='0' then           --当复位端置零时没有数据输入
         s0<=(others =>'0');       --则把寄存器里面的值全部置零 
         s1<=(others =>'0');       --相当于没有输入值
         s2<=(others =>'0'); s3<=(others =>'0');
         s4<=(others =>'0'); s5<=(others =>'0');
         s6<=(others =>'0'); s7<=(others =>'0');
         s8<=(others =>'0'); s9<=(others =>'0');
         s10<=(others =>'0'); s11<=(others =>'0');
         s12<=(others =>'0'); s13<=(others =>'0');
         s14<=(others =>'0'); s15<=(others =>'0');
           
	  elsif rising_edge(clk) then  --当复位端置1并且上升沿时
                                  --开始接收数据 
         s0<=data;                --并且将先前的数据往后保存
         s1<=s0; s2<=s1; s3<=s2; s4<=s3; s5<=s4; s6<=s5;
         s7<=s6; s8<=s7; s9<=s8; s10<=s9; s11<=s10;
         s12<=s11; s12<=s12; s14<=s13; s15<=s14; 
         outdata<=s15;       --按时钟周期将接收数据一步一步移出去
         end if;
         end process;
         end ;



2.	常数芯片定义:

entity const is
port(clk,reset:in std_logic; --时钟和复位控制
outdata:out std_logic_vector(7 downto 0)); --输出常数位8位数
end entity ;                                   --是固定阶数的系数
architecture arch of const is
signal n: integer range 0 to 17;    --信号n来计算接收数据个数
begin                               --以等到输出相应的系数
process(clk,reset) is

 begin
     if reset='1' then 
       if n=0 then outdata<=" 00011000";n<=n+1; --用n来计算输入值个
       elsif n=1 then outdata<=" 00011000";n<=n+1; --数,以便输出相
       elsif n=2 then outdata<=" 00100000";n<=n+1;  --应的系数常数值
       elsif n=3 then outdata<=" 00101001";n<=n+1;
       elsif n=4 then outdata<=" 00010100";n<=n+1;
       elsif n=5 then outdata<=" 01000000";n<=n+1;
       elsif n=6 then outdata<=" 01101110";n<=n+1;
       elsif n=7 then outdata<=" 00100000";n<=n+1;
       elsif n=8 then outdata<=" 00110110";n<=n+1;
       elsif n=9 then outdata<=" 00110110";n<=n+1;
       elsif n=10 then outdata<=" 00100000";n<=n+1;
       elsif n=11 then outdata<=" 01101110";n<=n+1;
       elsif n=12 then outdata<=" 01000000";n<=n+1;
       elsif n=13 then outdata<=" 00010100";n<=n+1;
       elsif n=14 then outdata<=" 00101001";n<=n+1;
       elsif n=15 then outdata<=" 00100000";n<=n+1;
       elsif n=16 then outdata<=" 00011000";n<=n+1;
       else  outdata<=" 00011000";n<=0;
       end if; end if; end process;
end architecture ;

3.	8位乘法器
                
     library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity mul8 is
     port (clock,reset:in std_logic;  --复位端和时钟控制
           data1,data2:in std_logic_vector(7 downto 0); -- 输入两个数据相乘
           outdata: out std_logic_vector(15 downto 0));--输出相乘后的16位数
    end;
architecture test of mul8 is
begin
    multi:process(clock,reset) is
         type state_type is (s0,s1,s2,s3,s4);
         variable state:state_type;  --变量state当作状态
         variable regx:std_logic_vector(15 downto 0); --变量做乘值
         variable regy:std_logic_vector(7 downto 0); --输入数据
         variable acc:std_logic_vector(15 downto 0); --加法器
         variable i:integer range 0 to 9;  
 begin
         if (reset='1') then
         state:=s0;
         elsif (rising_edge(clock)) then
         case state is
         when s0=>
                  regx:="0000000000000000";
                  regy:="00000000";
                  acc:="0000000000000000";
                  i:=0;   
                  state:=s1;
                           
         when s1=>
                  regx(7 downto 0):=data1;
                  regy:=data2;
                  i:=0;
                  if (regy(0)='1') then
                  state:=s2;
                  else 
                  state:=s3;
                  end if;
         when s2=>
                  acc:=acc+regx;
                  regx:=regx(14 downto 0)&'0';
                  regy:='0'&regy(7 downto 1);
                  i:=i+1;
                  if (i=9) then
                  state:=s4;
                  elsif (regy(0)='1') then
                  state:=s2;
                  elsif (regy(0)='0') then
                  state:=s3; 
                  end if;

         when s3=>
                  regx:=regx(14 downto 0)&'0';
                  regy:='0'&regy(7 downto 1);
                  i:=i+1;
                  if (i=9) then
                  state:=s4;
                  elsif (regy(0)='1') then
                  state:=s2;
                  elsif (regy(0)='0') then
                  state:=s3; 
                  end if;
         when s4=>
                  outdata<=acc;
         end case;
         end if;
end process multi;
end architecture test;


4.	控制器
 library ieee;
use ieee.std_logic_1164.all;
entity controller is
 port(clock,reset:in std_logic;
      data:in std_logic_vector(7 downto 0); --输入数据
      acc,taout:out std_logic_vector(15 downto 0)); --输出和叠加器
    end;
architecture arch of controller is
   component reg is           --调用移位寄存器芯片
     port(clk,reset:in std_logic;  --以下端口和移位寄存器一样
          data:in std_logic_vector(7 downto 0);
          outdata:out std_logic_vector(7 downto 0));
     end component;
     component const is   --调用常数芯片
     port(clk,reset:in std_logic; --以下端口和常数芯片一样
         outdata:out std_logic_vector(7 downto 0));
     end component;
     component mul8 is       --调用乘法器芯片
     port(clock,reset:in std_logic; --以下和乘法器端口一样
           dataina,datainb:in std_logic_vector(7 downto 0);
           dataout: out std_logic_vector(15 downto 0));
         end component;
         signal a,b:std_logic_vector(7 downto 0);
         signal c:std_logic_vector(16 downto 0);
          begin       --将三个芯片和控制器连接起来使用
           com1:reg port map (clock,reset,a); 
           com2:const port map(clock,reset,b);
           com3:mul8 port map (clock,reset,a,b,acc);
           c<=acc; --输出的相乘值累加起来
          taout<=acc+c;  --累加的结果赋给输出
          end; 

  仿真结果:
    
输入为00000001的时候,可得结果为:taout=24*1=18H

 
              
输入继续为2的时候,可得结果为:taout=24×1+24×2=72=48H
可见设计的输出结果正确。 明显,这个程序设计是符合要求的!

 

程序二:
1.	调用上面所写的乘法器包,将其定义为包(在这里省略不打印出来)
2.	主程序:
    library ieee;
use ieee.std_logic_1164.all;
use work.signed_arith.all;
use work.mul8.all;            --调用乘法器包
entity fir is
 port(clk,reset:in std_logic;   --时钟和复位端
     data:in std_logic_vector(7 downto 0); --输入8位的数据
     outdata:out std_logic_vector(15 downto 0)); --输出16位数据
    end;
architecture arch of fir is
constant com:std_logic_vector(143 downto 0)  --定义一个常数系数, 
:=("0001100000011000001000000010100100010  --总共18阶×8=
1000100000001101110001000000011011000  --144位。
11011000100000011011100100000014000101001");
 begin 
    process(clk,reset) is
    variable s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17:std_logic_vector(7 downto 0); --定义变量当作数据和系数相乘
                             --的数值做存储器来叠加        
    variable a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18:std_logic_vector(15 downto 0); --定义变量当作叠加器 
     begin
        
if reset='0' then     --如果复位端位0,则全部将寄存器清零
s0:=(others =>'0'); s1:=(others =>'0'); s2:=(others =>'0');
s3:=(others =>'0'); s4:=(others =>'0'); s5:=(others =>'0');
s6:=(others =>'0'); s7:=(others =>'0'); s8:=(others =>'0');
s9:=(others =>'0'); s10:=(others =>'0');s11:=(others =>'0');
s12:=(others =>'0'); s13:=(others =>'0'); s14:=(others =>'0');
s15:=(others =>'0'); s16:=(others =>'0'); s17:=(others =>'0');
elsif rising_edge(clk) then --如果复位端位1并且时钟上升沿,移位存数据
s17:=s16; s16:=s15; s15:=s14; s14:=s13; s13:=s12; s12:=s11;
s11:=s10; s10:=s9; s9:=s8; s8:=s7; s7:=s6; s6:=s5; s5:=s4;
s4:=s3; s3:=s2; s2:=s1; s1:=s0; s0:=data;
      --常数系数按时钟移位,以得到对应的系数和数据相乘  
a1:=s0*com(7 downto 0); a2:=s1*com(15 downto 8);
a3:=s2*com(23 downto 16); a4:=s3*com(31 downto 24);
 a5:=s4*com(39 downto 32); a6:=s5*com(47 downto 40);
 a7:=s6*com(55 downto 48); a8:=s7*com(63 downto 56);
 a9:=s8*com(71 downto 64); a10:=s9*com(79 downto 72);
 a11:=s10*com(87 downto 80); a12:=s11*com(95 downto 88);
 a13:=s12*com(103 downto 96); a14:=s13*com(111 downto 104);
 a15:=s14*com(119 downto 112); a16:=s15*com(127 downto 120);
 a17:=s16*com(135 downto 128); a18:=s17*com(143 downto 136);
        outdata<=a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15+a16+a17+a18;   --将得到的数据叠加起来输出
          end if;
          end process;  end;
  仿真结果:
 
  当输入每个时钟为1时:结果为24=24×1,48=24+24, 80=24+24+32……可见,当输入为1时是正确的。
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -