-- ----------------------------------------------------------------------------- -- Copyright (c) 2013 Benjamin Krill -- -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal -- in the Software without restriction, including without limitation the rights -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -- copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be included in -- all copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -- THE SOFTWARE. -- ----------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.dvi_package.all; library UNISIM; use UNISIM.Vcomponents.all; entity chnlbond is port ( clk : in std_logic; rst_n : in std_logic; rawdata_i : in std_logic_vector(9 downto 0); psaligned_i : in std_logic; other_valid_i : in std_logic_vector(1 downto 0); other_ready_i : in std_logic_vector(1 downto 0); ready_o : out std_logic; sdata_o : out std_logic_vector(9 downto 0) ); end chnlbond; architecture chnlbond of chnlbond is signal rawdata_vld : std_logic; signal we : std_logic; signal wa, ra : unsigned(3 downto 0); signal dpfo_dout : std_logic_vector(9 downto 0); signal sdata : std_logic_vector(9 downto 0); signal rcvd_ctkn : std_logic; signal rcvd_ctkn_q : std_logic; signal blnkbgn : std_logic; signal skip_line : std_logic; signal next_blnkbgn : std_logic; signal ready : std_logic; signal rawdata_vld_q : std_logic; signal rawdata_vld_s : std_logic; signal ra_en : std_logic; begin sdata_o <= sdata; ready_o <= ready; rawdata_vld <= other_valid_i(0) and other_valid_i(1) and psaligned_i; -- ---------------------------------------------------------- -- FIFO Write Control Logic -- ---------------------------------------------------------- process (clk, rst_n) begin if rst_n = '0' then we <= '0'; sdata <= (others => '0'); wa <= (others => '0'); elsif rising_edge(clk) then we <= rawdata_vld; if rawdata_vld = '1' then wa <= wa + "1"; else wa <= (others => '0'); end if; sdata <= dpfo_dout; end if; end process; -- ---------------------------------------------------------- -- FIFO -- ---------------------------------------------------------- cbfifo_i: entity work.DRAM16XN generic map ( data_width => 10 ) port map ( DATA_IN => rawdata_i, ADDRESS => std_logic_vector(wa), ADDRESS_DP => std_logic_vector(ra), WRITE_EN => we, CLK => clk, O_DATA_OUT => open, O_DATA_OUT_DP => dpfo_dout ); -- ---------------------------------------------------------- -- FIFO read Control Logic -- ---------------------------------------------------------- next_blnkbgn <= skip_line and blnkbgn; process (clk, rst_n) begin if rst_n = '0' then rcvd_ctkn <= '0'; rcvd_ctkn_q <= '0'; ready <= '0'; skip_line <= '0'; rawdata_vld_q <= '0'; rawdata_vld_s <= '0'; elsif rising_edge(clk) then -- --------------------------- -- Use blank period beginning -- as a speical marker to -- align all channel together -- --------------------------- rcvd_ctkn <= '0'; if sdata = CTRLTOKEN0 or sdata = CTRLTOKEN1 or sdata = CTRLTOKEN2 or sdata = CTRLTOKEN3 then rcvd_ctkn <= '1'; end if; rcvd_ctkn_q <= rcvd_ctkn; blnkbgn <= rcvd_ctkn and not rcvd_ctkn_q; -- --------------------------- -- skip the current line -- --------------------------- if rawdata_vld = '0' then skip_line <= '0'; elsif blnkbgn = '1' then skip_line <= '1'; end if; -- --------------------------- -- Declare my own readiness -- --------------------------- if rawdata_vld = '0' then ready <= '0'; elsif next_blnkbgn = '1' then ready <= '1'; end if; rawdata_vld_q <= rawdata_vld; rawdata_vld_s <= rawdata_vld and not rawdata_vld_q; end if; end process; -- ---------------------------------------------------------- -- 1. FIFO flow through first when all channels are found valid(phase aligned) -- 2. When the speical marker on my channel is found, the fifo read is hold -- 3. Until the same markers are found across all three channels, the fifo read resumes -- ---------------------------------------------------------- process (clk, rst_n) begin if rst_n = '0' then ra_en <= '0'; ra <= (others => '0'); elsif rising_edge(clk) then if rawdata_vld_s = '1' or (other_ready_i(0) = '1' and other_ready_i(1) = '1' and ready = '1') then ra_en <= '1'; elsif next_blnkbgn = '1' and not (other_ready_i(0) = '1' and other_ready_i(1) = '1' and ready = '1') then ra_en <= '0'; end if; -- --------------------------- -- FIFO Read Address Counter -- --------------------------- if rawdata_vld = '0' then ra <= (others => '0'); elsif ra_en = '1' then ra <= ra + "1"; end if; end if; end process; end chnlbond;