组合电路的ⅤHDL设计 优先编码器 编码器( encoder)也属于码制转换器一类 (BCD-1-out-of-10)(p49表2-9) 优先编码器属于多对1转换关系,没有一一对应关系,难 以采用上述方式描述 74148优先编码器真值表见p278表5-23,表中含有大 量‘x’项,目前ⅤHDL还不能直接对其进行运算处理; 在p.384表5-26中,显示了行为设计的一种形式:采用 for-loop语句 也可以采用数据流设计中的条件代入语句实现 例:简化74148优先编码器的数据流设计 数据输入订[7.0]低电平有效控制输入e低电平有效 数据输出a[2.0]反函数输出 library ieee use ieee std logic 1164. all; entity encoder is port(i: in std logic vector(7 downto 0) el: in std logic a: out std logic vector(2 downto O)) end encoder: architecture rtl of encoder is signal al std logic vector(2 downto O)
组合电路的 VHDL 设计 优先编码器 编码器(encoder)也属于码制转换器一类 (BCD—1-out-of-10) ( p.49 表 2-9 ) 优先编码器属于多对 1 转换关系,没有一一对应关系,难 以采用上述方式描述; 74148 优先编码器真值表 见 p.278 表 5-23,表中含有大 量‘x’项,目前 VHDL 还不能直接对其进行运算处理; 在 p.384 表 5-26 中,显示了行为设计的一种形式:采用 for-loop 语句; 也可以采用数据流设计中的条件代入语句实现: 例: 简化 74148 优先编码器的数据流设计 数据输入 i[7..0] 低电平有效 控制输入 el 低电平有效 数据输出 a[2..0] 反函数输出 library ieee; use ieee.std_logic_1164.all; entity kencoder is port (i: in std_logic_vector (7 downto 0); el: in std_logic; a: out std_logic_vector(2 downto 0)); end kencoder; architecture rtl of kencoder is signal a1:std_logic_vector(2 downto 0);
al <=000"when i(7)='0 else 001"when i(7 downto 6-10" else 010"when i(7 downto 5)110"else 0ll"when i(7 downto 4=1110" else 100"when i(7 downto 3)=11110"else 101"when i(7 downto 2)111110" else 110"when i(7 downto 11111110"else 111 a<=al when el=o' else"111 奇偶校验电路 parity checker 奇偶校验电路是实现数据错误检验的一种基本电路,其方 式是检测在9位输入数据中‘1’的个数是奇数还是偶数 3输入端异或门可以看作3位奇偶校验电路: 1’的个数为奇数时输出为‘1’,为偶数时输出为“0’ 利用该电路可以构成9位奇偶校验电路 p.418表5-479位奇偶校验电路的行为设计 p419表5-489位奇偶校验电路的结构设计 例9位奇偶校验电路的数据流设计 library ieee use ieee std logic 1164 all
begin a1 <="000" when i(7)= '0' else "001" when i(7 downto 6)="10" else "010" when i(7 downto 5)="110" else "011" when i(7 downto 4)="1110" else "100" when i(7 downto 3)="11110" else "101" when i(7 downto 2)="111110" else "110" when i(7 downto 1)="1111110" else "111"; a<=a1 when el='0' else "111"; end rtl; 奇偶校验电路 parity checker 奇偶校验电路是实现数据错误检验的一种基本电路,其方 式是检测在 9 位输入数据中‘1’的个数是奇数还是偶数; 3 输入端异或门可以看作 3 位奇偶校验电路: ‘1’的个数为奇数时输出为‘1’,为偶数时输出为‘0’; 利用该电路可以构成 9 位奇偶校验电路; p.418 表 5-47 9 位奇偶校验电路的行为设计 p.419 表 5-48 9 位奇偶校验电路的结构设计 例 9 位奇偶校验电路的数据流设计 library ieee; use ieee.std_logic_1164.all;
enti port(i: in std logic vector( 1 to 9) even, odd: out std logic) end parity architecture rtl of kparity 9 i signal yl, y2, y3, y: std logic, yl<=i(1) xor i(2)xor i(3) y2<=1(4)xor i(5)xor i(6) y3<=i(7) xor i( 8)xor 1(9); yI xor y2 xor y3 odd<=y; even<= not y end rtI 运算电路 运算电路主要包括比较器( comparator)、加法器(add) 乘法器( multipliers)和算术逻辑单元(ALU)等电路。 在运算电路中,运算量经常需要进行算术运算; 在VHDL中,算术运算不能对bt、 std logic d logic vector等类型进行 此外,二进制的数值表达方式本身也存在符号表达方式 问题,不同表达方式的运算规则不同 为了解决类型与运算的相容问题,统一符号运算问题, 在包集合 IEEE std logic arith中,定义了 signed和 unsinged 两种类型,以及与这两种类型相应的转换函数和对这些类型 进行的运算,其规则如下(针对加减运算)
entity kparity9 is port (i: in std_logic_vector ( 1 to 9); even,odd : out std_logic); end kparity9 ; architecture rtl of kparity9 is signal y1,y2,y3,y: std_logic; begin y1<= i(1) xor i(2) xor i(3) ; y2<= i(4) xor i(5) xor i(6) ; y3<= i(7) xor i(8) xor i(9) ; y<= y1 xor y2 xor y3 ; odd<= y ; even<= not y; end rtl; 运算电路 运算电路主要包括比较器(comparator)、加法器(add)、 乘法器(multipliers)和算术逻辑单元(ALU)等电路。 在运算电路中,运算量经常需要进行算术运算; 在 VHDL 中,算术运算不能对 bit 、 std_logic 、 std_logic_vector 等类型进行; 此外,二进制的数值表达方式本身也存在符号表达方式 问题,不同表达方式的运算规则不同; 为了解决类型与运算的相容问题,统一符号运算问题, 在包集合 IEEE.std_logic_arith 中,定义了 signed 和 unsinged 两种类型,以及与这两种类型相应的转换函数和对这些类型 进行的运算,其规则如下(针对加/减运算):
若运算量中存在 signed类型,结果就为 signed类型;否 则为 unsinged类型 若结果被指定为 std logic、 std logic vector等类型,则 signed或 unsigned类型的结果自动转为指定类型; 运算结果的长度为最长运算量的长度,但若 型与 signed类型运算,会自动变为后一类型,其长度会增加 以在最高位增加符号位"O 对于通常所用的 sdt logic vector类型的数据d,需要进 行算术运算时,可以采用函数 signed(d将其转换为 signed类 型,或采用函数 unsigned(d)将其转换为 unsigned类型,运算 完毕后,通过代入语句将结果直接赋值给 sdt logic vector类 型的信号,即可恢复通用的类型; 例P445表5-55各种运算结果的类型 8位不同类型数据的加/减法器 数据流设计 library ieee use ieee std logic 1164. all; use ieee std logic arith.all vadd Is port(a, b: in unsigned( 7 downto0); c: in signed(7 downton); d: in std logic vector( 7 downto0 ); s: out unsigned 8 downto O) t: out signed( 8 downto 0) u:out signed (7 downto 0); v: out std logic vector( 8 downto O)) end vac
若运算量中存在 signed 类型,结果就为 signed 类型;否 则为 unsinged 类型; 若结果被指定为 std_logic、std_logic_vector 等类型,则 signed 或 unsigned 类型的结果自动转为指定类型; 运算结果的长度为最长运算量的长度,但若 unsigned 类 型与 signed 类型运算,会自动变为后一类型,其长度会增加 1 以在最高位增加符号位'0'; 对于通常所用的 sdt_logic_vector 类型的数据 d,需要进 行算术运算时,可以采用函数 signed(d)将其转换为 signed 类 型,或采用函数 unsigned(d)将其转换为 unsigned 类型,运算 完毕后,通过代入语句将结果直接赋值给 sdt_logic_vector 类 型的信号,即可恢复通用的类型; 例 P.445 表 5-55 各种运算结果的类型 8 位不同类型数据的加/减法器 数据流设计 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity vadd is port (a,b: in unsigned( 7 downto 0 ); c : in signed ( 7 downto 0 ); d : in std_logic_vector( 7 downto 0 ); s : out unsigned (8 downto 0); t : out signed (8 downto 0); u : out signed (7 downto 0); v : out std_logic_vector(8 downto 0)); end vadd;
architecture rtl of vadd is s<=(0&a)+(0&b) t<=a+C V<=C-unsigned(d) d rtl 例p446表5 可选输入的加法器 数据流设计,采用条件代入语句 std logic arith. all entity vaddshr port(a, b, c, d: in signed( 7 downto 0) sel: in std logic s: out signed (7 downto O)); end vaddshr: architecture rtl of vaddshr s<=a+b when sel='l' else c+d d rtl 以上输入和输出均采用 signed类型;在实际应用中,数 据传递采用统一的 std logic类型比较方便,因此在端口信号 中最好全都采用 std logic类型,由此会要求程序进行相应改 变 例采用 std logic类型端口的8位加法器
architecture rtl of vadd is begin s <= ('0' & a)+('0' & b); t <= a+c; u <= c+signed(d); v <= c-unsigned(d); end rtl; 例 p.446 表 5-56 可选输入的加法器 数据流设计,采用条件代入语句 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity vaddshr is port (a,b,c,d: in signed( 7 downto 0 ); sel : in std_logic; s : out signed (7 downto 0)); end vaddshr; architecture rtl of vaddshr is begin s <= a+b when sel='1' else c+d; end rtl; 以上输入和输出均采用 signed 类型;在实际应用中,数 据传递采用统一的 std_logic 类型比较方便,因此在端口信号 中最好全都采用 std_logic 类型,由此会要求程序进行相应改 变。 例 采用 std_logic 类型端口的 8 位加法器 library ieee;
use ieee std logic arith all entity vadd is port(a, b: in std logic vector( 7 downto 0); c: in std lo s: out std logic vector(8 downto 0)); end vadd: architecture rtl of vadd is signal d: std logic vector(0 to O); d(0<=c; s<=(O'& unsigned(a))+unsigned(b)+unsigned(d) end rtI 注意:由于 unsigned()函数只针对数组,因此不能将c直 接变化,必须先将其写为数组信号;此外,为了使s的数据 宽度能够与右端运算匹配,应先将a的宽度扩展到8位 例p453表5-608位乘法器的设计 数据流设计 use ieee std logic 1164. all; use ieee std logic arith. all entity vmul8x8i is port(x,y: in std logic vector( 7 downto 0) p: out std logic vector(15 downto O)) end vmul8x8i architecture rtl of vmul 8i is p<=unsigned(x)*unsigned(y); nd rtI
use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity vadd is port (a,b: in std_logic_vector( 7 downto 0 ); c : in std_logic; s : out std_logic_vector(8 downto 0)); end vadd; architecture rtl of vadd is signal d: std_logic_vector(0 to 0); begin d(0)<= c; s <= ('0' & unsigned(a)) +unsigned(b)+unsigned(d); end rtl; 注意:由于 unsigned()函数只针对数组,因此不能将 c 直 接变化,必须先将其写为数组信号;此外,为了使 s 的数据 宽度能够与右端运算匹配,应先将 a 的宽度扩展到 8 位。 例 p.453 表 5-60 8 位乘法器的设计 数据流设计 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity vmul8x8i is port (x,y: in std_logic_vector( 7 downto 0 ); p : out std_logic_vector (15 downto 0)); end vmul8x8i; architecture rtl of vmul8x8i is begin p <= unsigned(x)*unsigned(y); end rtl;
例p428表5-50 8位无符号数比较器的行为设计 library ieee use Ieee entity compare is port(a, b: in std logic vector( 7 downto 0); eq, ne, gt,ge,It, le: out std logic) nd architecture beh of compare is process(a, b) eqb then gt =b then ge <='1 if a<b then It <=l' end if if a<=b then le <='I end if d end beh. 算术逻辑单元ALU 通过控制变量的选择,可以对输入的两组数据进行不同的算 术算或逻辑运算 设计思想:将每一种运算设计为一个小程序块,通过选择语 句来选择实现 例带进位四位算术逻辑单元ALU设计
例 p.428 表 5-50 8 位无符号数比较器的行为设计 library ieee; use ieee.std_logic_1164.all; entity vcompare is port (a,b: in std_logic_vector( 7 downto 0 ); eq,ne,gt,ge,lt,le: out std_logic); end vcompare; architecture beh of vcompare is begin process(a,b) begin eq b then gt =b then ge <= '1'; end if; if a<b then lt <= '1'; end if; if a<=b then le <= '1'; end if; end process; end beh; 算术逻辑单元 ALU 通过控制变量的选择,可以对输入的两组数据进行不同的算 术算或逻辑运算; 设计思想:将每一种运算设计为一个小程序块,通过选择语 句来选择实现; 例 带进位四位算术逻辑单元 ALU 设计
具有3位选择输入,可以实现8种不同的运算 ALU1 a[B··g1 c1 n cout library ieee use ieee std logic 1164. all use ieee std logic arith. all port(a, b: in unsigned(3 downto 0) cin: in std logic sel: in std logic vector(2 downto O); y: out std logic vector(3 downto 0) cout: out std logic); end alul architecture beh of alul is signal c: std logic vector(3 downto O) process(a, b, cin, sel) when"000"=> y(0)<=a(0)xorb() Xor cin;-实现a+b+cin c(O=(a(0)and b(o)or(a0)and cin)or(cin and b(o)) genl: for i in I to 3 loop y(i=a(i) xor b(i) xor c(i-1); c(i<=(a(i) and b(i) or(a(i)and c(i-1)or(c(i-1)and b() end loop
具有 3 位选择输入,可以实现 8 种不同的运算; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity alu1 is port(a,b: in unsigned(3 downto 0); cin: in std_logic; sel: in std_logic_vector(2 downto 0); y: out std_logic_vector(3 downto 0); cout: out std_logic); end alu1; architecture beh of alu1 is signal c: std_logic_vector(3 downto 0); begin process(a,b,cin,sel) begin case sel is when "000" => y(0)<= a(0) xor b(0) xor cin; --实现 a+b+cin; c(0)<= (a(0) and b(0)) or (a(0) and cin) or (cin and b(0)); gen1:for i in 1 to 3 loop y(i)<= a(i) xor b(i) xor c(i-1); c(i)<= (a(i) and b(i)) or (a(i) and c(i-1)) or (c(i-1) and b(i)); end loop;
hen"00l"=> y(0) if cin='0 then y if cin= then y 3)<=a(3)andb(3)y(2)=a(2)andb(2)-实现andb; y(1)=a(1)andb(1)y(0)<=a(0)andb(0 y(3)<=a(3)orb(3)y(2)=a(2)orb(2),一实现aorb; y(1)<=a(1)orb(1)y(0)<=a(0)orb(0) cout<=o
cout y(0) if cin='0' then y if cin='0' then y y(3) y(3)<=a(3) or b(3);y(2)<=a(2) or b(2); --实现 a or b; y(1)<=a(1) or b(1);y(0)<=a(0) or b(0); cout<='0';
when "110"=> y(3)y<=0000 cout<=O end process end beh a和b是 unsigned的数组类型,进行算术运算后结果可 以直接赋给 std logic vector类型(默认类型转换),不经过 运算或经过逻辑运算后不能直接赋值给 std logic vector类 型;但一位的 unsigned类型进行逻辑运算后结果可以直接赋 给 std logic类型(默认类型转换)。 作业 设计p441表5-53所示的算术逻辑单元的结构体:已知实体 为 entity kalu port( a, b: in std logic vector(3 downto 0)
when "110" => y(3) y(3)y<= "0000"; cout<='0'; end case; end process; end beh; a 和 b 是 unsigned 的数组类型,进行算术运算后结果可 以直接赋给 std_logic_vector 类型(默认类型转换),不经过 运算或经过逻辑运算后不能直接赋值给 std_logic_vector 类 型;但一位的 unsigned 类型进行逻辑运算后结果可以直接赋 给 std_logic 类型(默认类型转换)。 作业: 设计 p.441 表 5-53 所示的算术逻辑单元的结构体;已知实体 为: entity kalu is port( a, b : in std_logic_vector(3 downto 0);