我试图设计和构建一个VHDL SPI从接口,它接受串行数据,并行化,响应,然后根据给定的命令输出。现在我的模拟运行就像它应该的那样,但是当我合成它时,register_file或register_address会导致几百个错误。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
USE ieee.numeric_std.ALL;
ENTITY STATE IS
PORT(
D_SI : in STD_LOGIC;
CS : IN STD_LOGIC;
CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
STATE_SO : out std_logic
);
END STATE;
ARCHITECTURE BEHAVIOR OF STATE IS
constant NUM_REG_ADDR_BITS : integer := 8;
constant NUM_INTERFACE_REGISTERS : integer := (2**NUM_REG_ADDR_BITS);
type interface_register_file is array(((2**NUM_REG_ADDR_BITS) - 1) downto 0) of std_logic_vector(7 downto 0);
signal register_address : std_logic_vector(NUM_REG_ADDR_BITS - 1 downto 0);
signal register_file : interface_register_file;
SIGNAL ready : STD_LOGIC := '0';
signal COUNT : STD_LOGIC_VECTOR(2 downto 0);
SIGNAL OUTS : STD_LOGIC_VECTOR(7 DOWNTO 0);
CONSTANT READS : std_logic_vector(7 downto 0) := "11110000"; -- CONSTANTS FOR READ AND WRITE COMMANDS
CONSTANT WRITES : std_logic_vector(7 downto 0) := "00001111";
signal DSEND : std_logic_vector(7 downto 0);
signal CNT : std_logic_vector(2 downto 0);
signal EN : std_logic;
signal D_PO : STD_LOGIC_VECTOR(7 downto 0);
type state_type is (IDLE,REA,WRI,RD_ADDRESS,WR_ADDRESS); --type of state machine.
signal current_s,next_s: state_type; --current and next state declaration.
type mode_type is (ADD,DATA); --type of state machine.
signal current_mode,next_mode: mode_type; --current and next state declaration.
type RD_type is (RD,WAI); --This allows for an initial input of address and then an incrementing address
signal current_RD,next_RD: RD_type; --current and next RD declaration.
BEGIN
process(DSEND,CS,RESET,EN)
begin
IF CS = '1' or RESET = '1' then
D_PO <= "ZZZZZZZZ";
else
IF EN = '1' then
D_PO <= DSEND;
end if;
end if;
end process;
Data_out:PROCESS(CLK,D_SI)
BEGIN
IF rising_edge(CLK) then
DSEND(0) <= D_SI;
DSEND(7 downto 1) <= DSEND(6 downto 0);
END IF;
END PROCESS;
Bit_Counter:PROCESS(CLK,RESET,CNT,CS,EN)
BEGIN
IF CS ='1' THEN
CNT <= "000";
EN <= '0';
ELSE
IF Reset = '1' then
CNT <= "000";
EN <= '0';
ELSE
IF rising_edge(CLK) then
CNT <= CNT + '1';
IF CNT = "111" then
EN <= '1';
ELSE
EN <= '0';
END IF;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS (CLK, reset, EN, CS) --Change State of IDLE write or read
begin
if (reset='1') or CS = '1' then
current_s <= IDLE; --default state on reset.
elsif falling_edge(clk) and EN = '1' then
current_s <= next_s; --state change.
END IF;
END PROCESS;
PROCESS (CLK, reset, CS) --Change mode of writing and reading memory
begin
if (reset='1') or CS = '1' then
current_mode <= ADD; --default state on reset.
elsif clk'event then
current_mode <= next_mode; --state change.
END IF;
END PROCESS;
PROCESS (CLK, reset, EN, CS) --Change Waiting state for address processing
begin
if (reset='1') or CS = '1' then
current_RD <= WAI; --default state on reset.
elsif rising_edge(en) then
current_RD <= next_RD; --state change.
END IF;
END PROCESS;
process(RESET)
begin
end process;
--state machine process.
PROCESS (current_s,D_PO, EN, CLK, CS,current_rd)
BEGIN
if CS = '1' then
outs <= "ZZZZZZZZ";
register_address <= "ZZZZZZZZ";
next_mode <= add;
next_rd <= wai;
next_s <= IDLE;
STATE_SO <= 'Z';
else
case current_s is
when IDLE =>--when current state is "IDLE"
register_address <= "ZZZZZZZZ";
if(D_PO = READS) then
next_s <= REA;
elsif(D_PO = WRITES) then
next_s <= WRI;
ELSE
next_s <= IDLE;
END IF;
when REA => --when current state is Read
next_s <= RD_ADDRESS;
when RD_ADDRESS =>
if current_rd = WAI then
register_address <= D_PO;
next_rd <= rd;
end if;
if rising_edge(clk) THEN
STATE_SO <= register_file(to_integer(unsigned(register_address)))(7);
register_file(to_integer(unsigned(register_address)))(7 downto 1) <= register_file(to_integer(unsigned(register_address)))(6 downto 0);
register_file(to_integer(unsigned(register_address)))(0) <= '0';
outs <= register_address;
End if;
if rising_edge(en) then
register_address <= register_address + 1;
end if;
case current_rd is
when wai =>
when rd =>
next_rd <= rd;
end case;
when WRI => -- Current state is Write
next_s <= WR_ADDRESS;
when WR_ADDRESS =>
if current_rd = WAI then
if rising_edge(clk) and En = '1' then
register_address <= D_PO;
end if;
next_rd <= rd;
elsif current_rd = RD then
if falling_edge(clk) and EN = '1' THEN
register_file(to_integer(unsigned(register_address)))<= D_PO;
register_address <= register_address+1;
outs <= register_address;
End if;
end if;
case current_rd is
when wai =>
when rd =>
next_rd <= rd;
end case;
END CASE;
END IF;
END PROCESS;
PROCESS(CLK, reset, CS) -- Counter For READY
BEGIN
if CS = '1' then
count <= (others=>'0');
ready <= '0';
elsif (rising_edge(CLK)) then
count <= count + 1;
END IF;
if count = "111" and clk = '1' then
READY <= '1';
else
READY <= '0';
END IF;
END PROCESS;
END behavior;
错误总是类似
Asynchronous load of non-constant data for register_file_0_cl(7) is not supported
This is the picture of my simulation and it works fine here but I guess my code is very much non-synthesizable.
我会对这个错误以及我的代码提出任何反馈意见。我现在只使用VHDL大约一个星期了,我仍然习惯于习惯语法和编程风格。