zoukankan      html  css  js  c++  java
  • VHDL 例程

    以下程序未经仿真,仅供说明

    语法

    声明参考库ieee,使用ieee中的std_logic_1164包全部条目可见

    library ieee;  
    use ieee.std_logic_1164.all;
    

    程序框架

    要点是:

    1. 实体名和构造体名允许重复,都以“end 名字; ”结尾
    2. port 括号里最后一行没有分号。目前发现只有实体里的port括号、元件申明语句里面的port括号里面各条目间以“;”分隔,其他情况的括号里面各条目间以“,”分隔。
    3. 只有端口要标明信号方向如“in、out”,如实体里、元件声明里的port
    library ieee;  
    use ieee.std_logic_1164.all;
    
    entity mux is 
    	port(d0,d1,sel:in std_logic;
    	q:out std_logic);
    end mux; 
    
    architecture rtl of mux is	 
    begin						  
    	process(d0,d1,sel)
    	begin
    		if(sel='0')then 
    			q<=d0;
    		elsif(sel='1')then
    			q<=d1;
    		else
    			q<='Z';
    		end if;
    	end process;
    	
    end rtl;
    

    元件申明和调用

    要点:

    1. 元件属性放在实体里
    2. 元件申明component开头,不用is,以end component结尾。目前发现只有Type state_type is (S0,S1,S2);、实体和构造体和case中才有is,只有实体和构造体以end 自己定的名字;结尾
    3. 注意参数映射、端口映射间没有逗号、分号
    --被调用的元件
    library ieee;
    use ieee.std_logic_1164.all;
    
    entity and2_gate is 
    	generic(delay:time);
    	port (
    		in1,in2:in std_logic;
    		out1:out std_logic); 
    	
    end and2_gate;				  
    
    architecture beh of and2_gate is 
    begin
    	out1<=in1 and in2 after delay;
    end beh;
    
    --当前设计
    library ieee;
    use ieee.std_logic_1164.all;
    
    entity nand2 is	
    	port(a,b:in std_logic;
    		q:out std_logic);
    end nand2;				  
    
    architecture structure of nand2 is 
    	component and2_gate	  
    		generic(delay:time);
    		port (
    			in1,in2:in std_logic;
    			out1:out std_logic); 
    	end component;	
    	
    	signal pass_state:std_logic;
    begin		  
    	q<=not pass_state;
    	u1: and2_gate 
    	generic map(5 ns)
    	port map( a,b,pass_state);
    end structure;
    

    并行语句

    所谓并行是:本语句和其他语句并发执行没有先后
    并行赋值语句:条件信号赋值、选择信号赋值。process中只能有简单赋值和顺序描述语句
    只有条件信号赋值和if语句才有else

    	-----------条件信号赋值,有优先级
    	t<=a when sel='0' else
    	     b when sel='1' else
                 'X';	
    	-----------选择信号赋值,有优先级
    	with sel select
    		v<=a when '0',
    		      b when '1',	  
    		      'X' when others; 
    

    顺序语句

    顺序语句可以放在process里面,并行语句放在process外面
    if是顺序语句,可以用来实现有优先级的分支
    case 是顺序描述语句,各个分支没有优先级,各分支条件需穷举且不重复。

    		case sel is 
    			when "00"=>q<=a;
    			when "01"=>q<=b;
    			when "10"=>q<=c;
    			when others=>q<=d;
    		end case;
    

    组合电路

    基本逻辑门

    门名称 符号
    与门 and
    或门 or
    非门 not
    与非 nand
    或非 nor
    异或 xor

    编程方法一

    library ieee;
    use ieee.std_logic_1164.all;
    entity and2 is
    	port(
    	a,b:in std_logic;
    	y :out std_logic
    	);
    end and2; 
    architecture rtl of and2 is 
    begin
    	y<=a and b;
    end rtl;
    

    编程方法二

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity and2 is 
    	port(a,b:in std_logic;
    	y:out std_logic);
    end and2;			
    
    architecture rtl of and2 is 
    begin 
    	process(a,b)
    		variable comb:std_logic_vector(1 downto 0);
    	begin
    		comb:=a&b;
    		case comb is 
    			when "00"|"01"|"10"=>y<='0';
    			when "11"=>y<='1';
    			when others=>y<='X';
    		end case;
    	end process;
    end rtl;
    

    38译码器

    library	 ieee;
    use ieee.std_logic_1164.all;
    entity decoder38 is
    	port(a,b,c,g1,g2a,g2b:in std_logic;
    	y:out std_logic_vector(7 downto 0));
    end decoder38;
    
    architecture rtl of decoder38 is 
    signal indata:std_logic_vector(2 downto 0);
    begin 									  
    	indata<=a&b&c;
    	process(indata,g1,g2a,g2b)
    	begin		
    		if(g1='1' and g2a='0' and g2b='0')then
    			case indata is 
    				when "000"=>y<=B"1111_1110";
    				when "001"=>y<=B"1111_1101";
    				when "010"=>y<=B"1111_1011";
    				when "011"=>y<=B"1111_0111";		
    				when "100"=>y<=B"1110_1111";
    				when "101"=>y<=B"1101_1111";
    				when "110"=>y<=B"1011_1111";
    				when "111"=>y<=B"0111_1111";	
    				when others=>y<=B"1111_1111";
    			end case;
    		else
    			y<="11111111";
    		end if;
    	end process;
    end rtl;
    

    83优先级编码器

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    entity priorityencoder is
    	port(input:in std_logic_vector(7 downto 0);
    	y:out std_logic_vector(2 downto 0));
    end priorityencoder;					 
    
    architecture rtl of priorityencoder is
    begin	
    	process(input)
    	begin		
    		if(input(0)='0')then
    			y<="111";
    		elsif(input(1)='0')then
    			y<="110";
    		elsif(input(2)='0')then
    			y<="101";
    		elsif(input(3)='0')then
    			y<="100";
    		elsif(input(4)='0')then
    			y<="011";
    		elsif(input(5)='0')then
    			y<="010";
    		elsif(input(6)='0')then
    			y<="001";
    		else
    			y<="000";  
    		end if;	
    	end process;
    end rtl;
    
    

    选择器

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    
    entity mux4 is	
    	port(input:in std_logic_vector(3 downto 0);
    	a,b:in std_logic;
    	y:out std_logic);
    end mux4;
    
    architecture rtl of mux4 is
    signal sel:std_logic_vector(1 downto 0);
    begin				  					 
    	sel<=a&b;
    	process(sel,input) 
    	begin		
    		if(sel="00")then
    			y<=input(0)	;
    		elsif(sel="01")then
    			y<=input(1)	;
    		elsif(sel="10")then
    			y<=input(2)	;
    		elsif(sel="11")then
    			y<=input(3);
    		else 
    			y<='Z';	
    		end if;		
    	end process;
    
    end rtl;
    

    比较器

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    
    entity comp4 is		
    	port(a,b:in std_logic;
    	GT:out std_logic;
    	EQ:out std_logic;
    	LT:out std_logic);
    end comp4;
    
    architecture rtl of comp4 is 
    begin  
    	process(a,b)
    	begin
    		if(a>b)then
    			GT<='1';EQ<='0';LT<='0';
    		elsif(a=b)then
    			GT<='0';EQ<='1';LT<='0';
    		else
    			GT<='0';EQ<='0';LT<='1';
    		end if;
    	end process;
    end rtl;
    

    减法器

    library ieee;
    use ieee.std_logic_1164.all;
    entity subtracter is
    	port(x,y,cin:in std_logic;
    	sub,cout:out std_logic);
    end subtracter;
    architecture rtl of subtracter is
    begin	 
    	sub<=x xor y xor cin;
    	cout<=(not x and y)or (not x and cin)or (y and not cin);	
    end rtl;
    

    时序电路

    异步D触发器

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    entity dffAsync is
    	port(clk,d,clr_n:in std_logic;
    	q:out std_logic);
    end dffAsync;
    
    architecture rtl of dffAsync is
    begin
    	process(clk,clr_n)
    	begin		
    		if(clr_n='0')then
    			q<='0';
    		elsif (clk'EVENT and clk='1')then
    			q<=d;
    		end if;
    	end process;
    	
    end rtl;
    

    同步D触发器

    library ieee;
    use ieee.std_logic_1164.all;
    entity dffSync is 
    	port(d,clk,clr_n:in std_logic;
    	q:out std_logic);
    end dffSync;	
    architecture rtl of dffSync is
    begin	
    	process(clk)  --同步复位敏感信号表不需要复位信号
    	begin
    		if(clk'EVENT and clk='1')then
    			if (clr_n='0')then
    				q<='0';
    			else
    				q<=d;
    			end if;
    		end if;	  
    	end process;
    end rtl;
    

    T触发器

    library ieee;
    use ieee.std_logic_1164.all;
    entity tff is 
    	port(clk:in std_logic;
    	q:out std_logic);
    end tff;  
    
    architecture rtl of tff is 
    signal temp:std_logic:='0';
    begin 
    	process(clk)
    	begin	
    		if(clk'EVENT and clk='1')then
    			temp<=not temp;
    		end if;
    	end process;	
    	q<=temp;
    end rtl;
    

    RS触发器

    --rs触发器
    library ieee;
    use ieee.std_logic_1164.all;
    entity rsff is
    	port(r,s:in std_logic;
    	q,qn:out std_logic);
    end rsff;
    architecture rtl of rsff is	 
    signal qtemp,qntemp:std_logic;
    begin 	
    	qtemp<=r nor qntemp;
    	qntemp<=qtemp nor s;
    	q<=qtemp;
    	qn<=qntemp;
    end rtl;
    

    八位寄存器

    --8位锁存寄存器
    library ieee;
    use ieee.std_logic_1164.all;
    entity register8 is
    	port(clk,reset_n:in std_logic;
    	d:in std_logic_vector(7 downto 0);
    	q:out std_logic_vector(7 downto 0));
    end register8;
    
    architecture rtl of register8 is		 
    signal qtemp:std_logic_vector(7 downto 0);
    begin
    	process(clk,reset_n)
    	begin		
    		if(reset_n='0')then
    			qtemp<="00000000";
    		elsif (clk'EVENT and clk='1')then
    			q<=qtemp;
    		end if;
    	end process;
    	q<=qtemp;
    end rtl;
    

    6位串入串出移位寄存器

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity siso6 is 
    	port(d,clk:in std_logic;
    		q:out std_logic);
    end siso6;
    
    architecture rtl of siso6 is 
    	component dff	  
    		port(d,clk:in std_logic;
    			q:out std_logic);
    	end component;
    	signal z:std_logic_vector(0 to 6);
    begin  	 
    	z(0)<=d;
    	g:for i in 0 to 5 generate
    	    dff_map: dff
    		port map(
    		d=>z(i),
    		clk=>clk,
    		q=>z(i+1)
    		);
    	end generate;
    	q<=z(6);
    end rtl;
    

    上面的程序调用的D触发器写在下面

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity dff is
    	port(d,clk:in std_logic;
    		q:out std_logic);
    end dff;				  
    architecture rtl of dff is
    begin
    	process(clk)
    	begin	   
    		if clk'EVENT and clk='1' then
    			q<=d;
    		end if;
    	end process;
    end rtl;
    

    另一种行为级写法

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity siso6_v2 is
    	port(d,clk:in std_logic;   
    	
    	q,qn:out std_logic);
    end siso6_v2;	
    
    architecture rtl of siso6_v2 is	   
    signal temp:std_logic_vector(5 downto 0);  
    signal temp1:std_logic_vector(5 downto 0);
    begin
            --这一段是为了比较
    	process(clk)
    	begin		
    		if clk'EVENT and clk='1' then	
    			temp(4 downto 0)<=temp(5 downto 1);	
    			temp(5)<=d;				
    		end if;	
    	end process;  
            --保留下面这段即可
    	process(clk)
    	begin		
    		if clk'EVENT and clk='1' then	
    			temp1(5)<=d;
    			temp1(4 downto 0)<=temp1(5 downto 1);							
    		end if;	
    	end process;   
    	qn<=temp1(0);
    	q<=temp(0);
    end rtl;
    

    十进制计数器

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    entity count10en is
    	port(clk,clr,en:in std_logic;
    	qa,qb,qc,qd:out std_logic);
    end count10en;				  
    architecture rtl of count10en is	
    	signal count:std_logic_vector(3 downto 0)  ;
    begin 				
    	process(clk,clr)
    	begin 
    		if(clr='1')then
    			count<="0000"; 
    		elsif clk'EVENT and clk='1' then
    			if en='1' then
    				if(count="1001")then
    					count<="0000";
    				else 
    					count<=count+1;
    				end if;
    			end if;
    		end if;
    	end process;
    	qa<=count(0);
    	qb<=count(1);
    	qc<=count(2);
    	qd<=count(3);
    end rtl;
    

    可逆计数器

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    
    entity countReversible is
    port(clk,clr,updown:in std_logic;
    qa,qb,qc,qd:out std_logic);
    end countReversible;
    
    architecture rtl of countReversible is	
    signal count:std_logic_vector(3 downto 0);
    begin									   
    	process(clk)
    	begin
    		if(clr='1')then
    			count<="0000";
    		elsif(clk'EVENT and clk='1')then
    			if(updown='1')then
    				count<=count+1;
    			else
    				count<=count-1;
    			end if;
    		end if;
    		
    	end process;
    	
    	qa<=count(0);
    	qb<=count(1);
    	qc<=count(2);
    	qd<=count(3);
    end rtl;
    

    6分频器

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    
    entity clk_div6 is 
    	port(clk,clr:in std_logic;
    	clk_div6:out std_logic);
    end clk_div6;
    
    architecture rtl of clk_div6 is	 
    signal count:std_logic_vector(1downto 0);
    signal clk_temp:std_logic;
    
    begin				   
    	process(clk,clr)
    	begin
    		if(clr='1')then
    			count<="00";
    			clk_temp<='0';
    		elsif clk'EVENT and clk='1' then
    			if count="10" then
    				count<="00";
    				clk_temp<=not clk_temp;
    			else
    				count<=count+1;
    			end if;
    		end if;
    	end process;
    	clk_div6<=clk_temp;
    	
    end rtl;
    

    数控N分频

    library IEEE;
    use IEEE.STD_LOGIC_1164.all;
    use IEEE.STD_LOGIC_UNSIGNED.all;
    
    entity ClkDiv is
        port(
        clk_i:IN STD_LOGIC;
        N_i:  IN STD_LOGIC_VECTOR(9 DOWNTO 0);
        clk_o:OUT STD_LOGIC);
    end ClkDiv;
    
    architecture behavior of ClkDiv is
    signal count:STD_LOGIC_VECTOR(9 DOWNTO 0):="0000000001";
    signal clk_temp:STD_LOGIC:='0';
    begin
        process(clk_i)
        begin
            if(clk_i'EVENT and clk_i='1')then  
                if (count=N_i)then
                    count<="0000000001";
                    clk_temp<='1';
                else
                    count<=count+1;
                    clk_temp<='0';
                end if;
            end if;
        end process;    
        clk_o<=clk_temp;
    end behavior;
    

    状态机

    要点是:两定义三进程

    1. 状态寄存器描述:clk,rst
    2. 下一状态描述:current_state,X
    3. 输出描述:current_state
    	--引入状态编码的两定义
    	constant s0:std_logic_vector(1 downto 0):="00";
    	constant s1:std_logic_vector(1 downto 0):="01";
    	constant s2:std_logic_vector(1 downto 0):="11";
    	
    	signal current_state:std_logic_vector(1 downto 0);
    	signal next_state:std_logic_vector(1 downto 0);
            --一般的两定义
    	type state_type is (S0,S1,S2,S3,S4);
    	signal current_state,next_state:state_type;
    	
    

    moore机

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    
    entity moore is 
    	port(clk,rst,X:in std_logic;
    		Z:out std_logic);
    end moore;		   
    
    architecture behavior of moore is
    	type state_type is (S0,S1,S2,S3);
    	signal current_state,next_state:state_type;
    begin 
    	--状态寄存器描述
    	sync:process(clk,rst)
    	begin		
    		if clk'EVENT and clk='1' then 
    			if rst='1' then
    				current_state<=S1;
    			else
    				current_state<=next_state;
    			end if;
    		end if ;
    	end process; 
    	
    	--下一转态描述
    	state_trans:process(current_state,X)
    	begin		
    		case current_state is 
    			when S0=>
    				if X='0' then
    					next_state<=S0;
    				else 
    					next_state<=S2;	
    				end if;
    			when S1=>
    				if X='0' then
    					next_state<=S0;
    				else 
    					next_state<=S2;	
    				end if;	
    			when others=>
    				next_state<=S1;
    		end case;
    	end process; 
    	
    	--输出描述
    	output:process(current_state)
    	begin		
    		case current_state is 
    			when S0=>Z<='0';
    			when S1=>Z<='1';
    			when others=>Z<='0';
    		end case;
    	end process;
    	
    end behavior ;
    

    mealy机

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.std_logic_unsigned.all;
    
    entity mealy is
    	port(clk,clr,X:in std_logic;
    		Z:out std_logic);
    end mealy;			
    
    architecture rtl of mealy is 
    	type state_type is (S0,S1,S2,S3);
    	signal current_state,next_state:state_type;
    begin 
    	--寄存器描述
    	sync:process(clk,clr,next_state)
    	begin		
    		if clk'EVENT and clk='1' then
    			if clr='1' then
    				current_state<=S0;
    			else
    				current_state<=next_state;
    			end if;
    		end if;
    	end process;  
    	
    	--下一状态描述、输出描述
    	combin:process(current_state,X)
    	begin
    		case current_state is 
    			when S0=>
    				if X='0'then
    					next_state<=S0;
    					Z<='1';
    				else
    					next_state<=S1;
    					Z<='0';
    				end if;
    			
    			when others=>
    				next_state<=S0;
    				Z<='0';
    		end case;	
    	end process;
    end rtl;
    
    
    

    testbench

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity siso6_v2_tb is
    end siso6_v2_tb;
    
    architecture TB_ARCHITECTURE of siso6_v2_tb is
    	component siso6_v2
    	port(
    		d : in STD_LOGIC;
    		clk : in STD_LOGIC;
    		q,qn : out STD_LOGIC );
    	end component;
    
    	signal d : STD_LOGIC;
    	signal clk : STD_LOGIC;
    	signal q ,qn: STD_LOGIC;
    begin
    
    	UUT : siso6_v2
    		port map (
    			d => d,
    			clk => clk,
    			q => q ,
    			qn => qn
    		); 
    	
    --时钟	
    	process
    	begin 	   
    		clk<='1';
    		wait for 50ns;
    		clk<='0';
    		wait for 50ns ;
    	end process	;	   
    	
    	d<='1',
    	'0' after 1000ns,
    	'1' after 1200ns,
    	'0' after 1300ns,
    	'1' after 1500ns;
    							
    end TB_ARCHITECTURE;
    
  • 相关阅读:
    PHP $_SERVER变量
    Buddy system伙伴分配器实现
    Linux iconv使用
    内存管理(memory allocation内存分配)
    内存碎片
    《STL源码剖析》chapter2空间配置器allocator
    Effective C++学习笔记:初始化列表中成员列出的顺序和它们在类中声明的顺序相同
    c++ explicit
    《STL源码剖析》环境配置
    C++ STL的各种实现版本
  • 原文地址:https://www.cnblogs.com/uestcman/p/10202150.html
Copyright © 2011-2022 走看看