习题10
10-1 试用VHDL描述一个一位全加器电路。
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
entity my_adder is
port
(
a,b,cin : in bit;
cout,sum : out bit
);
end my_adder;
architecture behave of my_adder is
begin
sum <= a xor b xor cin;
cout <= ((a xor b) and cin) or (a and b);
end behave;
10-2 试编写两个四位二进制相减的VHDL程序。
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity my_sub4 is
port
(
a : in std_logic_vector(3 downto 0);
b : in std_logic_vector(3 downto 0);
ci : in std_logic;
co : out std_logic;
result : out std_logic_vector(3 downto 0) );
end my_sub4;
architecture behave of my_sub4 is
signal s: std_logic_vector(4 downto 0);
begin
s <= ('0'&a )+('0'&b)+("0000"&ci);
result <= s(3 downto 0);
co <= s(4);
end behave;
10-3 试用VHDL描述一个3-8译码器。
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
entity my_3to8decoder is
port
(
sel : in std_logic_vector(2 downto 0);
adr : out std_logic_vector(7 downto 0) );
end my_3to8decoder;
architecture behave of my_3to8decoder is begin
process(sel)
begin
case sel is
when "000" => adr <= "11111110";
when "001" => adr <= "11111101";
when "010" => adr <= "11111011";
when "011" => adr <= "11110111";
when "100" => adr <= "11101111";
when "101" => adr <= "11011111";
when "110" => adr <= "10111111";
when "111" => adr <= "01111111";
when others => adr <= null;
end case;
end process;
end behave;
10-4 试用VHDL描述一个8421BCD优先编码器。
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
entity encoder83 is
port(d:in std_logic_vector(9 downto 0);
y:out std_logic_vector(3 downto 0));
end encoder83;
architecture arc of encoder83 is
begin
process(d)
begin
if d(9)='0' then
y<="1001";
elsif d(8)='0' then
y<="1000";
elsif d(7)='0' then
y<="0111";
elsif d(6)='0' then
y<="0110";
elsif d(5)='0' then
y<="0101";
elsif d(4)='0' then
y<="0100";
elsif d(3)='0' then
y<="0011";
elsif d(2)='0' then
y<="0010";
elsif d(1)='0' then
y<="0001";
else
y<="0000";
end if;
end process;
end arc;
10-5 试用if语句描述一个4选1数据选择器。
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
entity my_mux4_1 is
port(d:in std_logic_vector(3 downto 0);
s:in std_logic_vector(1 downto 0);
y:out std_logic
);
end my_mux4_1;
architecture behavior of my_mux4_1 is
begin
process(s,d)
variable muxval : std_logic;
begin
muxval :='0';
if s="00" then
muxval := d(0);
elsif s="01" then
muxval := d(1);
elsif s="10" then
muxval := d(2);
elsif s="11" then
muxval := d(3);
else null;
end if;
y <= muxval;
end process;
end behavior;
10-6 用VHDL描述时序电路时,时钟和复位信号的描述有哪几种方法?它们各有什么特点?
解:时钟信号的描述有两种,边沿触发和电平触发,针对不同的器件选择不同的触发方式。复位信号的描述也有两种,同步复位和异步复位,故名思意,就是复位信号是否受时钟信号的控制,在描述时,异步复位电路的复位信号要放在process的敏感列表中。
10-7 用VHDL描述任意模值二进制计数器和任意模值十进制计数器有何区别?
解:因为位权不同,二进制计数器与十进制计数器的主要区别是计数的输出设置不同
10-8 分频器和计数器有何区别?用VHDL描述分频器时应注意什么问题?
解:分频器的时钟脉冲CP一定是周期信号,则输出信号也是周期性,输出信号的周期是输入信号周期的M倍,反过来输出信号的频率是输入信号频率的M分之一。
计数器的时钟脉冲CP不一定是周期信号,可以是随机脉冲,称为计数脉冲,则输出信号也不一定是周期性。计数器工作目的是纪录计数脉冲个数(递加或递减)以及产生溢出(进位或借位)信号。
描述分频器时应注意分频后波形的占空比的设置。
10-9 试用VHDL描述一个具有异步复位、同步置数使能的8位二进制加/减法计数器。
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity my_8counter is
port
(
clk : in std_logic;
reset : in std_logic;
enable : in std_logic;
updown : in std_logic;
q : out std_logic_vector(7 downto 0) );
end my_8counter;
architecture rtl of my_8counter is
signal direction : integer;
begin
process (updown)
begin
-- Determine the increment/decrement of the counter
if (updown = '1') then
direction <= 1;
else
direction <= -1;
end if;
end process;
process (clk)
variable cnt : std_logic_vector(7 downto 0);
begin
-- Synchronously update counter
if (rising_edge(clk)) then
if reset = '1' then
-- Reset the counter to 0
cnt := (others => '0');
elsif enable = '1' then
-- Increment/decrement the counter
cnt := cnt + direction;
end if;
end if;
-- Output the current count
q <= cnt;
end process;
end rtl;
10-10 试用VHDL设计一个M=100的二进制加法计数器。
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity my_100counter is
port
(
clk : in std_logic;
reset : in std_logic;
enable : in std_logic;
q : out std_logic_vector(7 downto 0);
oc : out std_logic
);
end my_100counter;
architecture rtl of my_100counter is
signal cnt : std_logic_vector(7 downto 0); begin
process (clk)
begin
-- Synchronously update counter
if (rising_edge(clk)) then
if reset = '1' then
-- Reset the counter to 0
cnt <=(others => '0');
elsif enable = '1' then
cnt <= cnt + 1;
end if;
end if;
end process;
process(cnt)
begin
if cnt=99 then
oc <='1';
else
oc<='0';
end if;
end process;
-- Output the current count
q <= cnt;
end rtl;
10-11 试用VHDL设计一个M=78的十进制加法计数器。
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity my_78counter is
port
(
clk : in std_logic;
reset : in std_logic;
enable : in std_logic;
ql,qh : out std_logic_vector(3 downto 0);
oc : out std_logic
);
end my_78counter;
architecture rtl of my_78counter is
signal cntl,cnth : std_logic_vector(3 downto 0); begin
process (reset,clk)
begin
if reset='0' then
cntl<="0000";
cnth<="0000";
elsif clk'event and clk='1' then
if enable='1' then
if(cntl=7 and cnth=7) then
cntl<="0000";
cnth<="0000";
elsif cntl=9 then
cntl<="0000";
cnth<=cnth+1;
else
cntl<=cntl+1;
end if;
end if;
end if;
end process;
process(cntl,cnth)
begin
if (cntl=7 and cnth=7) then
oc <='1';
else
oc<='0';
end if;
end process;
-- Output the current count
ql <= cntl;
qh <= cnth;
end rtl;
10-12 试用VHDL设计一个M=56的十进制减法计数器
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity my_56counter is
port
(
clk : in std_logic;
reset : in std_logic;
enable : in std_logic;
ql,qh : out std_logic_vector(3 downto 0);
oc : out std_logic
);
end my_56counter;
architecture rtl of my_56counter is
signal cntl,cnth : std_logic_vector(3 downto 0);
begin
process (reset,clk)
begin
if reset='0' then
cntl<="0000";
cnth<="0000";
elsif clk'event and clk='1' then
if enable='1' then
if(cntl=5 and cnth=5) then
cntl<="0000";
cnth<="0000";
elsif cntl=9 then
cntl<="0000";
cnth<=cnth+1;
else
cntl<=cntl+1;
end if;
end if;
end if;
end process;
process(cntl,cnth)
begin
if (cntl=5 and cnth=5) then
oc <='1';
else
oc<='0';
end if;
end process;
-- Output the current count
ql <= cntl;
qh <= cnth;
end rtl;
10-13 试用VHDL设计一个分频电路,要求将4MHz输入信号变为1Hz输出。
解:程序设计如下:
分频系数:4000000,计数器从22位全0变为1111010000100011111111时,最高位输出1Hz 的脉冲。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity my_4m is
port
(
clk : in std_logic;
clkout : out std_logic
);
end my_4m;
architecture rtl of my_78counter is
signal cnt : std_logic_vector(21 downto 0);
begin
process
begin
wait until clk'event and clk='1';
if(cnt<3999999) then
cnt<=cnt+1;
clkout<='0';
else
cnt<=(others=>'0');
clkout<='1';
end if;
end process;
end rtl;
10-14试用VHDL设计一个16位串行输入→并行输出移位寄存器。
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity reg16_1 is
port
(
clk,ldn,clrn: in bit;
dsr: in std_logic;
d: in in std_logic _vector(15 downto 0);
q: out in std_logic _vector(15 downto 0)
);
end reg16_1;
architecture a1 of reg16_1 IS
signal sreg16: in std_logic _vector(15 downto 0);
begin
process(clrn,clk,ldn,d)
begin
if clrn='0' then
sreg16 <= "00000000";
else
if clk'event and clk='1' then
if ldn='0' then
sreg8<=d;
else
sreg16(14 downto 0)<=sreg16(15 downto 1);
sreg16(15)<=dsr;
end if;
end if;
end if;
q<=sreg16;
end process;
end a1
10-15 试用VHDL设计一个11010序列码发生器,循环产生11010序列。
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
entity my_serial is
port(
clk : in std_logic;
z : out std_logic
);
end my_serial;
architecture rtl of my_serial is
type state_type is (s0, s1, s2, s3, s4);
signal current_state , next_state : state_type;
begin
synch : process
begin
wait until clk'event and clk='1';
current_state<=next_state;
end process;
state_trans : process(current_state)
begin
case current_state is
when s0 =>
next_state <= s1;
z<='1';
when s1 =>
next_state <= s2;
z<='1';
when s2 =>
next_state <= s3;
z<='0';
when s3 =>
next_state <= s4;
z<='1';
when s4 =>
next_state <= s0;
z<='0';
end case;
end process;
end rtl;
10-16 试用VHDL设计串行序列检测电路,当检测到连续四个和四个以上的1时,输出“1”,否则输出“0”。
解:程序设计如下:
library ieee;
use ieee.std_logic_1164.all;
entity my_detector is
port(
d : in std_logic;
clk : in std_logic;
z : out std_logic
);
end my_detector;
architecture rtl of my_detector is
type state_type is (s0, s1, s2, s3, s4);
signal current_state , next_state : state_type;
begin
synch : process
begin
wait until clk'event and clk='1';
current_state<=next_state;
end process;
state_trans : process(current_state)
begin
next_state<=current_state;
case current_state is
when s0 =>
if d='0' then
next_state <= s0;
z<='0';
else
next_state <= s1;
z<='0';
end if;
when s1 =>
if d='0' then
next_state <= s0;
z<='0';
else
next_state <= s2;
z<='0';
end if;
when s2 =>
if d='0' then
next_state <= s0;
z<='0';
else
next_state <= s3;
z<='0';
end if;
when s3 =>
if d='0' then
next_state <= s0;
z<='0';
else
next_state <= s4;
z<='1';
end if;
when s4 =>
if d='0' then
next_state <= s0;
z<='0';
else
next_state <= s4;
z<='1';
end if;
end case;
end process;
end rtl;