- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I'm pretty newto VHDL and I'm trying to implement a Dual Clock Synchronous FIFO but I'm getting loads of error mainly things like:- Error (10822): HDL error at FIFO.vhd(57): couldn't implement registers for assignments on this clock edge
- Error (10820): Netlist error at FIFO.vhd(85): can't infer register for fifo_proc:Head
- Error (10821): HDL error at FIFO.vhd(86): can't infer register for "fifo_proc:Head
library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
entity FIFO is
Generic (
constant DATA_WIDTH : positive := 8;
constant FIFO_DEPTH : positive := 256
);
Port (
-- CLK : in STD_LOGIC;
WriteCLK : in STD_LOGIC;
ReadCLK : in STD_LOGIC;
RST : in STD_LOGIC;
WriteEn : in STD_LOGIC;
DataIn : in STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
ReadEn : in STD_LOGIC;
DataOut : out STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
Empty : out STD_LOGIC;
Full : out STD_LOGIC
);
end FIFO;
architecture Behavioral of FIFO is
begin
-- Memory Pointer Process
fifo_proc : process (WriteCLK, ReadCLK, RST, ReadEn, WriteEn)
type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
variable Memory : FIFO_Memory;
variable Head : natural range 0 to FIFO_DEPTH - 1;
variable Tail : natural range 0 to FIFO_DEPTH - 1;
variable Looped : boolean;
--Read_proc : process(ReadCLK)
begin
--Reset device on ReadCLK only
if rising_edge(ReadCLK) then
if RST = '1' then
Head := 0;
Tail := 0;
Looped := false;
Full <= '0';
Empty <= '1';
elsif ReadEn = '1' then
--Read Functionality
--if (ReadEn = '1') then
if ((Looped = true) or (Head /= Tail)) then
-- Update data output
DataOut <= Memory(Tail);
-- Update Tail pointer as needed
if (Tail = FIFO_DEPTH - 1) then
Tail := 0;
Looped := false;
else
Tail := Tail + 1;
end if;
end if;
end if;
end if;
if rising_edge(WriteCLK) then
if (WriteEn = '1') then
if ((Looped = false) or (Head /= Tail)) then
-- Write Data to Memory
Memory(Head) := DataIn;
-- Increment Head pointer as needed
if (Head = FIFO_DEPTH - 1) then
Head := 0;
Looped := true;
else
Head := Head + 1;
end if;
end if;
end if;
end if;
-- Update Empty and Full flags
if (Head = Tail) then
if Looped then
Full <= '1';
else
Empty <= '1';
end if;
else
Empty <= '0';
Full <= '0';
end if;
end process;
end Behavioral;
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This looks very much like a software approach to digital electronics - it will not work. You cannot have a register that is clocked from two clocks in FPGAs. And reading registers in one clock domain that is registered in another clock domain is very poor practice unless you're doing safe clock domain crossing.
Altera already provides a dual clock FIFO for free - check out the IP catalog.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
there are a lot of peculiarities about your code; nothing out of the common when you say you're new with VHDL, though. The following changes are recommended, some even necessary:- use signals instead of variables
- make sure each signal is only accessed by a single clock
- only use one clock/reset-sensitive IF per process
process(rst, clk) is
begin
if(rst = '1') then
-- reset code
elsif(rising_edge(clk)) then
-- synchronous code
end if;
end process;
This is the pattern that you will find almost anywhere, and everybody familiar with VHDL will understand it. Multiple clocks per process just lead to confusion. Also, the sensitivity list of your process is wrong. It should contain the reset and the clock, and only those. Your code won't simulate correctly. Finally, since you're going to implement a dual-clock FIFO, you need to learn about synchronization between crossing clock domains. I can't see any. Such FIFOs are typically built with gray counters, to avoid problems, and proper synchronization is a must. Just google about "VHDL clock domain crossing". Or just google for dual clock FIFOs and see how they do it. Without that understanding, your FIFO will work perfectly in simulation, and most of the time perfectly in reality, but sometimes just mess up your data. Best regards, GooGooCluster
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I'm not 100% sure, but I think variables don't map to physical wires or registers, but I could be wrong (I never use variables for the purpose you use it for). Use a variable as a "helper" only, not for things that must be remembered between clocks. All of your variables should map to signals. --- Quote End --- Variables can map to anything that signals can map to. But it can be less obvious what that may be. Hence why it is highly recommended that you use signals for everything. There is nothing you cant do with a signal (for logic implementation).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the information guys, sorry for the late reply.
All of this is very useful, I'll see what I can do with it.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page