我正在参加 vhdl 在线课程。其中一项实验室工作是:“基于分频器和8位循环移位寄存器实现移位周期为1 s的环形计数器”。
任务说计数器的最高位不能作为移位寄存器的时钟信号(即在ifrising_edge(移位器(MSB))结构中。需要形成使能信号作为选通。
我做了这项工作。结果被接受。
我有一个关于启用移位寄存器的问题。
shift_reg_proc : process(clk)
begin
if (rising_edge(clk)) then
if (srst = '1') then
shift_reg <= "10000000";
elsif (en = '1') then
shift_reg <= shift_reg(0) & shift_reg(7 downto 1);
end if;
end if;
end process shift_reg_proc
如果使能信号的持续时间为 1 个周期 clk,那么在上升沿 (clk) 时刻,en 信号电平有可能没有时间变为 = 1。如果是这种情况,则不能保证寄存器移位将在下一秒发生。有没有“正确”的方法来完成这项任务?是这样吗?我的决定正确吗?实验室线索是否具有误导性?
我附上了实现代码、测试台和波形图。
ring_counter.vhd
--------------------------------------------------------------------------------
-- Based on frequency divider and 8-bit cyclic shift register implement a ring
-- counter with a shift period of 1 s.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity ring_counter is
port(clk : in std_logic;
srst : in std_logic;
dout : out std_logic_vector(7 downto 0);
en_o : out std_logic
);
end entity ring_counter;
architecture behave of ring_counter is
signal cntr : std_logic_vector(26 downto 0) := (others => '0');
signal cntr_msb_delayed : std_logic;
signal shift_reg : std_logic_vector(7 downto 0);
signal en : std_logic;
constant cntr_msb_num : integer := 4; -- 26 for DE board, 4 for test bench
begin
-- signal for test bench
en_o <= en;
--------------------------------------------------------------------------------
-- Counter implementation
--------------------------------------------------------------------------------
cntr_proc : process(clk)
begin
if (rising_edge(clk)) then
if (srst = '1') then
cntr <= (others => '0');
else
cntr <= unsigned(cntr) + 1;
end if;
end if;
end process cntr_proc;
----------------------------------------------------------------------------
-- Shift register implementation
----------------------------------------------------------------------------
shift_reg_proc : process(clk)
begin
if (rising_edge(clk)) then
if (srst = '1') then
shift_reg <= "10000000";
elsif (en = '1') then
shift_reg <= shift_reg(0) & shift_reg(7 downto 1);
end if;
end if;
end process shift_reg_proc;
dout <= shift_reg;
----------------------------------------------------------------------------
-- Enable signal generation
----------------------------------------------------------------------------
-- Counter MSB delay for 1 period of clk
delay_proc : process(clk)
begin
if (rising_edge(clk)) then
cntr_msb_delayed <= cntr(cntr_msb_num);
end if;
end process delay_proc;
en <= cntr(cntr_msb_num) and not cntr_msb_delayed;
end architecture behave;
ring_counter_tb.vhd
library ieee;
use ieee.std_logic_1164.all;
entity ring_counter_tb is
end entity ring_counter_tb;
architecture behave of ring_counter_tb is
component ring_counter is
port(clk : in std_logic;
srst : in std_logic;
dout : out std_logic_vector(7 downto 0);
en_o : out std_logic
);
end component ring_counter;
signal clk : std_logic;
signal srst : std_logic;
signal dout : std_logic_vector(7 downto 0);
signal en_o : std_logic;
constant clk_period : time := 4 ns;
begin
dut : ring_counter
port map (
clk => clk,
srst => srst,
dout => dout,
en_o => en_o
);
clk_gen : process
begin
clk <= '0';
wait for clk_period;
loop
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end loop;
end process clk_gen;
srst <= '0',
'1' after 100 ns,
'0' after 150 ns;
end architecture behave;