11-19-2018 02:41 PM
Hello,
I have a question regarding FIFOs. I have a FIFO RAM containing 256x 24bit data, which I add from one parallel stream, sample by sample (FIFO to FIFO data shifting). Process reading FIFO reads data twice and concatenates them into 48 bit wide word (external interface streaming).
The problem that occurs is that the data are only even or odd duplicated samples: 1st, 1st, 3rd, 3rd etc. I added 1 or 2 clock cycles between readouts, tried higher latencies, different address generation, but nothing helped. During previous project, with similar problems, only using two FIFOs, separate for even and odd samples helped, but this is not a correct solution, I guess. Device is XC7A200T clocked at 80 MHz. What am I doing wrong?
Process writing to FIFO:
p_FIFO_Writer : process(Clock, f_DDCDataFrameValid, f_WriteEn, WriteData, WriteChannelNumber, FIFO_WritePointer_int) begin if (Clock'Event and Clock = '1') then case StateFIFOWriter is when Idle => f_WriteDone <= '0'; if (f_WriteEn = '1') then FIFO_WriteEn <= (others => '1'); FIFO_WriteData <= WriteData; FIFO_WriteAddr <= FIFO_WritePointer_int & WriteChannelNumber; StateFIFOWriter <= StateWrite; else FIFO_WriteEn <= (others => '0'); FIFO_WriteData <= (others => '0'); FIFO_WriteAddr <= (others => '0'); StateFIFOWriter <= Idle; end if; when StateWrite => f_WriteDone <= '0'; FIFO_WriteEn <= (others => '1'); FIFO_WriteData <= WriteData; FIFO_WriteAddr <= FIFO_WritePointer_int & WriteChannelNumber; StateFIFOWriter <= StateWriteDone; when StateWriteDone => f_WriteDone <= '1'; FIFO_WriteEn <= (others => '0'); FIFO_WriteData <= WriteData; FIFO_WriteAddr <= FIFO_WritePointer_int & WriteChannelNumber; StateFIFOWriter <= Idle; when others => f_WriteDone <= '0'; FIFO_WriteEn <= (others => '0'); FIFO_WriteData <= (others => '0'); FIFO_WriteAddr <= (others => '0'); StateFIFOWriter <= Idle; end case; end if; end process p_FIFO_Writer;
Process reading FIFO:
p_FIFO_Reader : process(Clock, StateFIFOReader, f_ReadStart, f_ReadEn, FIFO_ReadData, ReadChannelNumber, FIFO_ReadPointer_int) begin if (Clock'Event and Clock = '1') then case StateFIFOReader is when Idle => f_ReadDone <= '0'; if (f_ReadStart = '1') then ReadData_int <= (others => '0'); FIFO_ReadAddr <= FIFO_ReadPointer_int & ReadChannelNumber & '0'; StateFIFOReader <= StateRead1; else ReadData_int <= (others => '0'); FIFO_ReadAddr <= (others => '0'); StateFIFOReader <= Idle; end if; when StateRead1 => if (f_ReadEn = '1') then f_ReadDone <= '0'; ReadData_int <= x"0" & FIFO_ReadData(23 downto 4) & x"000000"; FIFO_ReadAddr <= FIFO_ReadPointer_int & ReadChannelNumber & '0'; StateFIFOReader <= StateRead1Wait0; else f_ReadDone <= '0'; ReadData_int <= (others => '0'); FIFO_ReadAddr <= (others => '0'); StateFIFOReader <= Idle; end if; when StateRead1Wait0 => f_ReadDone <= '0'; ReadData_int <= x"0" & FIFO_ReadData(23 downto 4) & x"000000"; FIFO_ReadAddr <= FIFO_ReadPointer_int & ReadChannelNumber & '0'; StateFIFOReader <= StateRead1Wait1; when StateRead1Wait1 => f_ReadDone <= '0'; ReadData_int <= x"0" & FIFO_ReadData(23 downto 4) & x"000000"; FIFO_ReadAddr <= FIFO_ReadPointer_int & ReadChannelNumber & '0'; StateFIFOReader <= StateRead2; when StateRead2 => f_ReadDone <= '0'; ReadData_int <= ReadData_int; & '1'; FIFO_ReadAddr <= FIFO_ReadPointer_int & ReadChannelNumber & '1'; StateFIFOReader <= StateRead2Wait0; when StateRead2Wait0 => f_ReadDone <= '0'; ReadData_int <= ReadData_int(47 downto 24) & x"0" & FIFO_ReadData(23 downto 4); FIFO_ReadAddr <= FIFO_ReadPointer_int & ReadChannelNumber & '1'; StateFIFOReader <= StateRead2Wait1; when StateRead2Wait1 => f_ReadDone <= '0'; ReadData_int <= ReadData_int(47 downto 24) & x"0" & FIFO_ReadData(23 downto 4); FIFO_ReadAddr <= FIFO_ReadPointer_int & ReadChannelNumber & '1'; StateFIFOReader <= StateReadAcknowledge; when StateReadAcknowledge => f_ReadDone <= '0'; ReadData_int <= ReadData_int; FIFO_ReadAddr <= (others => '0'); StateFIFOReader <= StateReadDone; when StateReadDone => f_ReadDone <= '1'; ReadData_int <= ReadData_int; FIFO_ReadAddr <= (others => '0'); StateFIFOReader <= Idle; when others => f_ReadDone <= '0'; ReadData_int <= (others => '0'); FIFO_ReadAddr <= (others => '0'); StateFIFOReader <= Idle; end case; end if; end process p_FIFO_Reader;
11-25-2018 07:46 AM
It would be helpful if you can share few snapshots along with a testbench and full FIFO code.
Thanks
Anusheel