📄 新建 文本文档.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'®y(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'®y(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 + -