我很困惑为什么我的VHDL设计不起作用。我将创建一个top.vhd文件,该文件将编程FPGA板以显示地址0到15以及每个地址的相应值。当我模拟我的设计时,所有时钟和重置都有效。我遇到的问题是我的FSM流程和地址流程。我知道这里有很多事情,所以如果你需要澄清我可以回答你的问题。
library IEEE;
use IEEE.std_logic_1164.ALL;
use IEEE.numeric_std.all;
entity top is
port(Clock : in std_logic;
Reset : in std_logic;
SW : in std_logic_vector (1 downto 0);
HEX2, HEX4: out std_logic_vector ( 6 downto 0);
KEY0: in std_logic);
end entity;
architecture top_arch of top is
component char_decoder is
port(BIN_IN : in std_logic_vector (3 downto 0);
HEX_OUT : out std_logic_vector (6 downto 0));
end component;
component rom_16x4_sync is
port (clock: in std_logic;
address: in std_logic_vector (3 downto 0);
rom_en: in std_logic;
data_out: out std_logic_vector(3 downto 0));
end component;
type state_type is (start, read_rom, clear_addr, done);
signal current_state, next_state : state_type;
signal Rom_en, addr_count_clr, addr_count_en : std_logic;
signal address_counter : integer range 0 to 15;
signal address_uns : unsigned (3 downto 0);
signal clock_slow : std_logic;
signal rom_out : std_logic_vector (3 downto 0);
begin
char : char_decoder port map (BIN_IN => rom_out, HEX_OUT => HEX2);
char1 : char_decoder port map (BIN_IN => std_logic_vector(address_uns), HEX_OUT => HEX4);
clock_slow <= Clock;
rom : rom_16x4_sync port map (clock => clock_slow, address => std_logic_vector(address_uns), rom_en => Rom_en, data_out => rom_out);
State_Memory : process (clock_slow, Reset)
begin
if (Reset = '0') then
current_state <= start;
elsif (clock_slow'event and clock_slow = '1') then
current_state <= next_state;
end if;
end process;
NEXT_STATE_LOGIC : process (current_state)
begin
case (current_state) is
when start => if (KEY0 = '0') then
next_state <= read_rom;
else next_state <= start;
end if;
when read_rom => if (address_counter = 15) then
next_state <= clear_addr;
else
address_counter <= address_counter + 1;
end if;
when clear_addr => next_state <= done;
address_counter <= 0;
when done => next_state <= done;
end case;
end process;
OUTPUT_LOGIC : process (current_state)
begin
case (current_state) is
when start => Rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
when read_rom => Rom_en <= '1';
addr_count_en <= '1';
addr_count_clr <= '0';
when clear_addr => Rom_en <= '0';
addr_count_en <= '1';
addr_count_clr <= '1';
when done => Rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
end case;
end process;
Address_Count : process (addr_count_en, addr_count_clr, clock_slow)
begin
if (clock_slow'event and clock_slow = '1') then
if (addr_count_en = '1') then
if (addr_count_clr = '1') then
address_uns <= "0000";
else
address_uns <= address_uns + 1;
end if;
end if;
end if;
end process;
address_uns <= to_unsigned(address_counter,4);
end architecture;
答案 0 :(得分:0)
我评论了我的代码错误:
address_counter
没有时钟并且是多余的。在过程address_uns
中删除分配并将比较更改为NEXT_STATE_LOGIC
(也应该进入敏感性列表)。在进程Address_Counter
之后删除对address_uns的并发信号分配。如果进程Address_Count
和OUTPUT_LOGIC
以及rom_16x4_sync是正确的,那么你应该有一些有用的东西。
好吧,我把大部分的点点滴滴从其他问题围绕着一个完整的MCVE,一点点努力,主要是复制和粘贴,这给了:
正如您所看到的那样无效,原因是address_uns
需要重置(它的默认值都是'U')。
添加重置可以:
因此,要点是你的状态机几乎是正确的,它在灵敏度列表中缺少地址计数器并且有两个地址计数器。将其限制为一个并重置它,这样您就不会在所有'U'中添加1表示您的状态机正在运行。
包含所有修复的代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity char_decoder is
port (
bin_in: in std_logic_vector (3 downto 0);
hex_out: out std_logic_vector (6 downto 0)
);
end entity;
architecture dummy of char_decoder is
-- seven segment display
--
-- a
-- f b
-- g
-- e c
-- d
--
-- SEGMENT is defined (g downto a)
--
type segment7 is array (integer range 0 to 15) of
std_logic_vector (6 downto 0);
constant hex_to_segment: segment7 := (
"1000000", -- 0
"1111001", -- 1
"0100100", -- 2
"0110000", -- 3
"0011001", -- 4
"0010010", -- 5
"0000010", -- 6
"1111000", -- 7
"0000000", -- 8
"0011000", -- 9
"0001000", -- A
"0000011", -- b
"0111001", -- C
"0100001", -- d
"0000110", -- E
"0001110" -- F
);
begin
process (bin_in)
variable seg7_val: integer range 0 to 15;
begin
seg7_val := to_integer(unsigned(bin_in));
hex_out <= hex_to_segment(seg7_val);
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity rom_16x4_sync is
port (
clock: in std_logic;
address: in std_logic_vector (3 downto 0);
rom_en: in std_logic;
data_out: out std_logic_vector(3 downto 0)
);
end entity;
architecture dummy of rom_16x4_sync is
type rom_array is array (0 to 15) of std_logic_vector(3 downto 0);
function fill_rom return rom_array is
variable ret_val: rom_array;
begin
for i in rom_array'reverse_range loop -- backward to i
ret_val(i) := std_logic_vector(to_unsigned(i,4));
end loop;
return ret_val;
end function;
constant rom: rom_array := fill_rom;
begin
process (clock)
begin
if rising_edge(clock) and rom_en = '1' then -- NO RESET
data_out <= rom(to_integer(unsigned(address)));
end if;
end process;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity top is
port (
clock: in std_logic;
reset: in std_logic;
sw: in std_logic_vector (1 downto 0); -- not used?
hex2, hex4: out std_logic_vector ( 6 downto 0);
key0: in std_logic
);
end entity;
architecture top_arch of top is
component char_decoder is
port (
bin_in: in std_logic_vector (3 downto 0);
hex_out: out std_logic_vector (6 downto 0)
);
end component;
component rom_16x4_sync is
port (
clock: in std_logic;
address: in std_logic_vector (3 downto 0);
rom_en: in std_logic;
data_out: out std_logic_vector(3 downto 0)
);
end component;
type state_type is (start, read_rom, clear_addr, done);
signal current_state,
next_state: state_type;
signal rom_en,
addr_count_clr,
addr_count_en: std_logic;
-- signal address_counter: integer range 0 to 15;
signal address_uns: unsigned (3 downto 0);
signal clock_slow: std_logic;
signal rom_out: std_logic_vector (3 downto 0);
begin
char:
char_decoder
port map (
bin_in => rom_out,
hex_out => hex2
);
char1:
char_decoder
port map (
bin_in => std_logic_vector(address_uns),
hex_out => hex4
);
clock_slow <= clock;
rom:
rom_16x4_sync
port map (
clock => clock_slow,
address => std_logic_vector(address_uns),
rom_en => rom_en, data_out => rom_out
);
state_memory:
process (clock_slow, reset)
begin
if reset = '0' then
current_state <= start;
elsif clock_slow'event and clock_slow = '1' then
current_state <= next_state;
end if;
end process;
next_state_logic:
-- process (current_state)
process (current_state, address_uns)
begin
case (current_state) is
when start =>
if key0 = '0' then
next_state <= read_rom;
else
next_state <= start;
end if;
when read_rom =>
if address_uns = 15 then
next_state <= clear_addr;
-- else
-- address_counter <= address_counter + 1;
end if;
when clear_addr => -- not a defined sequential logic inference
next_state <= done;
-- address_counter <= 0;
when done =>
next_state <= done;
end case;
end process;
output_logic:
process (current_state)
begin
case (current_state) is
when start =>
rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
when read_rom =>
rom_en <= '1';
addr_count_en <= '1';
addr_count_clr <= '0';
when clear_addr =>
rom_en <= '0';
addr_count_en <= '1';
addr_count_clr <= '1';
when done =>
rom_en <= '0';
addr_count_en <= '0';
addr_count_clr <= '0';
end case;
end process;
address_count:
process (addr_count_en, addr_count_clr, clock_slow)
begin
if reset = '0' then -- added reset
address_uns <= (others =>'0');
elsif clock_slow'event and clock_slow = '1' then
if addr_count_en = '1' then
if addr_count_clr = '1' then
address_uns <= "0000";
else
address_uns <= address_uns + 1;
end if;
end if;
end if;
end process;
-- address_uns <= to_unsigned(address_counter, 4);
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity top_tb is
end entity;
architecture foo of top_tb is
signal clock: std_logic := '0';
signal reset: std_logic := '1';
signal sw: std_logic_vector (1 downto 0) := "00";
signal hex2, hex4: std_logic_vector ( 6 downto 0);
signal key0: std_logic := '0';
begin
DUT:
entity work.top
port map (
clock => clock,
reset => reset,
sw => sw,
hex2 => hex2,
hex4 => hex4,
key0 => key0
);
CLK:
process
begin
wait for 5 ns;
clock <= not clock;
if now > 200 ns then
wait;
end if;
end process;
STIMULIS:
process
begin
wait for 1 ns;
reset <= '0';
wait for 10 ns;
reset <= '1';
wait for 10 ns;
wait;
end process;
end architecture;
我使用的char_decoder
应该是完全正常的。 ROM内容简直就是傻瓜了。