本文主要参考b站视频:【考研】EDA技术(vhdl技术),建议有时间的跟着听一下,从第8节开始,一直到31节都是讲VHDL,讲的很全面,赶时间的可以直接看我这个笔记。
文章目录
1.5 VHDL并发语句(Concurrent)
结构体中所有的语句都是并发的,并发语句和并发语句之间需要进行信息的传递,即信号。
常用的并发描述语句有:
进程(process)语句、块(block)语句、顺序描述语句的并行版本、并行过程调用语句、元件例化语句、生成语句。
1.5.1 进程(process)语句
进程(process)语句最具VHDL语言特色(既具有顺序语句的特点又具有并行语句的特点)。提供了一种用算法描述硬件行为的方法。
特点:
1、进程与进程,或其它并发语句之间的并发性;
2、进程内部的顺序性;
3、进程的启动与挂起;
4、进程与进程,或其它并发语句之间的通信。
[标记:]process[(敏感信号表)]
{进程说明项}
begin
{顺序描述语句}
end process [标记];
敏感信号表:进程内要读取的所有敏感信号(包括端口)的列表。每一个敏感信号的变化,都将启动进程。
格式:信号名称{,信号名称}
敏感信号表的特点:
- 同步进程的敏感信号表中只有时钟信号。
如:
process(clk)
begin
if(clk'event and clk=‘1’)then
if reset='1'then
data<="00";
else
data<=in_data;
end if;
end if;
end process;
- 异步进程敏感信号表中除时钟信号外,还有其它信号。
例:
process(clk,reset)
begin
if reset=‘1’ then
data=“00";
elsif (clk'event and clk='1') then
data<=in_data;
end if;
end process;
- 如果有wait 语句,则不允许有敏感信号表。
PROCESS(a,b)
BEGIN
–sequential statements
END PROCESS;
PROCESS
BEGIN
–sequential statements
WAIT ON(a,b);
END PROCESS;
用进程实现组合逻辑:
entity counter is
port(clear:in bit;
in_count:in integer range 0 to 9;
out_count:out integer range 0 to 9);
end counter;
architecture rtl of counter is
begin
process(in_count, clear)
begin
if(clear='1' or in_count=9) then
out_count<=0;
else
out_count<=in_count+1;
end if;
end process;
end rtl;
用进程实现时序逻辑:
entity counter is
port(clear:in bit;
clock:in bit;
count:butfer integer range 0 to9);
end counter;
architecture rtl of counter is
begin
process
begin
wait until(clock'event and clock='1');
if (clear='1'or count >=9) then
count <=0;
else
count <=count+1;
end if;
end process;
end rtl;
时序电路(计数器)仿真结果:
三态缓冲器总线结构与多驱动信号:
定义:
给一个信号赋值,即为该信号创建一个驱动器(驱动信号)。多个进程或并发语句给同一个信号赋值,则该信号为多信号源驱动。
例:
a_out<=a when enable_a else 'Z';
b out<=b when enable_b else 'Z’;
process(a_out)
begin
sig<=a_out;
end process;
process(b_out)
begin
sig<=b_out;
end process:
1.5.2 块语句
块语句将一系列并行描述语句进行组合,目的是改善并行语句及其结构的可读性。可使结构体层次鲜明,结构明确。
语法如下:
标记:block[(块保护表达式)]
{块说明项}
begin
{并行语句}
end block[标记];
process内部是顺序语句,block内部是并行语句。
1、块语句的使用不影响逻辑功能
以下两种描述结果相同:
描述一:
a1:out1<=‘1'after 2 ns;
a2:out2<=‘1'after 2 ns;
a3:out3<=‘1’after 2ns;
描述二:
al:outl<='1'after 2 ns;
blk1:block
begin
a2:out2<=1'after 2 ns;
a3:out3<=1'after 2 ns;
end block blk1;
- 嵌套块
子块声明与父块声明的对象同名时,子块声明将忽略掉父块声明。
-- 两个独立的2输入与门
B1:block
signal s:bit;--define s in B1
begin s<=a and b;--s in B1
B2:block
signal s:bit;--define s a in B2
begin
s<=c and d; --s in B2
B3:block
begin
z<=s; --s in B2
end block B3;
end block B2;
y<=s; --s in B1
end block B1;
- 卫式(Guarded)块
由保护表达式值的真、假决定块语句的执行与否。综合不支持。
entity eg1 is
port(a:in bit;
z:out bit);
end eg1;
architecture rtl of eg1 is
begin
guarded_block:block(a='1')
begin
z<='1' when guard else '0';
end block;
end rl;
1.5.3 并行信号赋值语句
包括三种:
简单并行信号赋值;条件信号赋值;选择信号赋值。
共同特点:
1、赋值目标必须是信号,与其它并行语句同时执行,与书写顺序及是否在块语句中无关。
2、每一信号赋值语句等效于一个进程语句。所有输入信号的变化都将启动该语句的执行。
- 简单并行信号赋值语句
即:信号<=表达式
例:以下两种描述等价
architecture behav of a_var is
begin
output<=a(i);
end behav;
architecture behav of a_var is
begin
process(a,i)
begin
output<=a(i);
end process;
end behav;
一个简单并行信号赋值语句是一个进程的缩写。
等效:
LIBRARY ieee;
USE ieee. std_logic_1164. all;
ENTITY ex1 IS
PORT(a,b: IN STD_LOGIC;
y: OUT STD_LOGIC);
END ex1;
ARCHITECTURE rtI OF ex1 IS
SIGNALc: STD_LOGIC;
BEGIN
c<=a and b;
y<=c;
END rtl;
LIBRARY ieee;
USE ieee. std_logic_1164. all;
ENTITY ex2 IS
PORT(a,b: IN STD_LOGIC;
y: OUT STD_LOGIC);
END ex1;
ARCHITECTURE rtI OF ex2 IS
SIGNAL c: STD_LOGIC;
BEGIN
process1:PROCESS(a,b)
BEGIN
c<=a and b;
END PROCESS process1;
process2:PROCESS(c)
BEGIN
y<=c;
END PROCESS process2;
END rtl;
不等效:
LIBRARY ieee;
USE ieee. std_logic_1164. all;
ENTITY ex1 IS
PORT(a,b: IN STD_LOGIC;
y: OUT STD_LOGIC);
END ex1;
ARCHITECTURE rtI OF ex1 IS
SIGNALc: STD_LOGIC;
BEGIN
c<=a and b;
y<=c;
END rtl;
LIBRARY ieee;
USE ieee. std_logic_1164. all;
ENTITY ex2 IS
PORT(a,b: IN STD_LOGIC;
y: OUT STD_LOGIC);
END ex1;
ARCHITECTURE rtI OF ex2 IS
SIGNAL c: STD_LOGIC;
BEGIN
PROCESS(a,b,c)
BEGIN
--顺序关系
c<=a and b;
y<=c;
END PROCESS;
END rtl;
- 条件信号赋值语句
格式:
目的信号量<=表达式1 when 条件1 else
表达式2 when 条件2 else
表达式3 when 条件3 else
表达式n;
例:用条件信号赋值语句描述四选一电路
entity mux4 is
port(i0,i1,i2,i3,a,b;in std_logic;
q:out std logic);
end mux4;
architecture rtl of mux4 is
signal sel:std_logic_vector(1 downto 0);
begin
sel<=b&a;
q<=i0 when sel="00" else
i1 when sel="01" else
i2 when sel="10" else
i3 when sel="11";
end rtl;
条件信号赋值语句(并行语句,必须在结构体内部使用)与进程中的多选择if语句(顺序语句,必须在进程中使用)等价:
q<=a WHEN sela='1' ELSE
b WHEN selb='1' ELSE
c;
PROCESS(sela,selb,a,b,c)
BEGIN
IF sela='1' THEN
q<=a;
ELSIF selb='1' THEN
q<=b;
ELSE
q<=c;
END IF;
END PROCESS;
- 选择信号赋值语句
格式:
with 表达式 select
目的信号量 <= 表达式1 when条件1,
表达式2 when条件2,
表达式n when条件n;
注:1)不能有重叠的条件分支。
2)最后条件可为others。否则,其它条件必须能包含表达式的所有可能值。
3)选择信号赋值语句与进程中的case 语句
等价。
例:用选择信号赋值语句描述四选一电路
entity mux4 is
port(i0,i1,i2,i3,a,b;in std_logic;
q:out std logic);
end mux4;
architecture rtl of mux4 is
signal sel:std_logic_vector(1 downto 0);
begin
sel<=b&a;
q<=i0 when sel="00",
i1 when sel="01",
i2 when sel="10" ,
i3 when sel="11",
'X' when others;
end rtl;
选择信号赋值语句与进程中的case语句等价:
WITH sel SELECT
q<=a WHEN "00",
b WHEN "01".
c WHEN "10",
d WHEN OTHERS;
PROCESS(sel,a,b,c,d)
BEGIN
CASE sel IS
WHEN,"00"=>
q<=a;
WHEN"01"=>
q<=b;
WHEN"10"=>
q<=C;
WHEN OTHERS=>
q<=d;
END CASE;
END PROCESS;
简单的指令译码器:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic unsigned.all;
entity decoder is
port(a,b.c:in std_logic;
data1,data2:in std_logic;
dataout:out std_logic);
end decoder;
architecture art of decoder is
signal instruction:std_logic_vector(2 downto 0);
begin
instruction=c&b&a;
with instruction select
dataout<=datal and data2 when"000",
dataout<=datal or data2 when "001",
dataout<=datal nand data2 when "010",
dataout<=datal nor data2 when"011",
dataout<=datal xor data2 when"100",
dataout<=datal nxor data2 when"101,
'Z' when others;
end art;
1.5.4并行过程调用语句
用过程名在结构体或块语句中可实现并行过程调用。其作用与一个进程等价。
格式:
过程名 [([参数名=>]表达式{,
[参数名=>]表达式})]
例:并行过程调用与串行过程调用
...
procedure adder(signal a,b:in std_logic;
signal sum:out std_logic);
...
adder(a1,b1,sum1);
...
process(c1,c2)
begin
adder(c1,c2,s1);
end process;
例:利用并行过程调用完成不同位宽信号的检测。检测位矢信号中是否有只有一个‘1’的过程:
procedure check(signal a:in std_logie_vector;
signal error:out boolean) is
variable found_one:boolean:=false;
begin
for i in a'range loop
if a(i)='1' then
if found_one then
error<=ture; return;
end if;
found_one:=true;
end if;
end loop;
error<=not found_one;
end procedure check;
例:并行调用上述过程完成对不同位宽信号的检测
chblk:block
signal s1:std_logic_vector(0 to 0);
signal s2:std_logic_vector(0 to 1);
signal s3:std_logic_vector(0 to 2);
signal s4:std _logie_vector(0 to 3);
signal e1,e2,e3,e4:boolean;
begin
check(s1,e1);
check(s2,e2);
check(s3,e3);
check(s4,e4);
end block;
并行调用实现的电路:
1.5.5 VHDL的层次化设计与元件声明(component)及元件例化(instantial)语句
- 层次化设计
VHDL层次化设计示意:
- 元件声明
定义:对所调用的较低层次的实体模块(元件)的名称、类属参数、端口类型、数据类型的声明。
语法:
component 元件名 [is]
[generic(类属声明);]
[port(端口声明);]
end component [元件名];
元件声明类似实体声明(entity)
例:元件声明
component and2
port(i1,i2: in bit;
o1:out bit);
end component;
component add
generic(n:positive);
port(x,y:in bit_vector(n-1 downto 0);
z:out bit_vector(n-1 downto 0);
carry:out bit);
end component;
可在以下部分声明元件:
结构体(Architecture)程序包(Packaige)块(Block)
被声明元件的来源:
VHDL设计实体;其它HDL设计实体;另外一种标准格式的文件,如EDF或XNF;厂商提供的工艺库中的元件、IP核。
停更: 22集17:18,最近忙于学业,来不及更新了,请大家去看原视频