⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 par_framer.vhd

📁 使用IDELAY实现8倍过采样异步串行信号恢复信号
💻 VHD
📖 第 1 页 / 共 2 页
字号:
                                  in_vector(24) or in_vector(23));
        trs_match3_l1( 4) <= not (in_vector(27) or in_vector(26) or 
                                  in_vector(25) or in_vector(24));
        trs_match3_l1( 5) <= not (in_vector(28) or in_vector(27) or 
                                  in_vector(26) or in_vector(25));
        trs_match3_l1( 6) <= not (in_vector(29) or in_vector(28) or 
                                  in_vector(27) or in_vector(26));
        trs_match3_l1( 7) <= not (in_vector(30) or in_vector(29) or 
                                  in_vector(28) or in_vector(27));
        trs_match3_l1( 8) <= not (in_vector(31) or in_vector(30) or 
                                  in_vector(29) or in_vector(28));
        trs_match3_l1( 9) <= not (in_vector(32) or in_vector(31) or 
                                  in_vector(30) or in_vector(29));
        trs_match3_l1(10) <= not (in_vector(33) or in_vector(32) or 
                                  in_vector(31) or in_vector(30));
        trs_match3_l1(11) <= not (in_vector(34) or in_vector(33) or 
                                  in_vector(32) or in_vector(31));
        trs_match3_l1(12) <= not (in_vector(35) or in_vector(34) or 
                                  in_vector(33) or in_vector(32));
        trs_match3_l1(13) <= not (in_vector(36) or in_vector(35) or 
                                  in_vector(34) or in_vector(33));
        trs_match3_l1(14) <= not (in_vector(37) or in_vector(36) or 
                                  in_vector(35) or in_vector(34));
        trs_match3_l1(15) <= not (in_vector(38) or in_vector(37) or 
                                  in_vector(36) or in_vector(35));
    end process;

    -- second level of gates

    process(trs_match1_l1)
    begin
        trs_match1(0) <= trs_match1_l1( 0) and trs_match1_l1( 4) and 
                         trs_match1_l1( 6);
        trs_match1(1) <= trs_match1_l1( 1) and trs_match1_l1( 5) and 
                         trs_match1_l1( 7);
        trs_match1(2) <= trs_match1_l1( 2) and trs_match1_l1( 6) and 
                         trs_match1_l1( 8);
        trs_match1(3) <= trs_match1_l1( 3) and trs_match1_l1( 7) and 
                         trs_match1_l1( 9);
        trs_match1(4) <= trs_match1_l1( 4) and trs_match1_l1( 8) and 
                         trs_match1_l1(10);
        trs_match1(5) <= trs_match1_l1( 5) and trs_match1_l1( 9) and 
                         trs_match1_l1(11);
        trs_match1(6) <= trs_match1_l1( 6) and trs_match1_l1(10) and 
                         trs_match1_l1(12);
        trs_match1(7) <= trs_match1_l1( 7) and trs_match1_l1(11) and 
                         trs_match1_l1(13);
        trs_match1(8) <= trs_match1_l1( 8) and trs_match1_l1(12) and 
                         trs_match1_l1(14);
        trs_match1(9) <= trs_match1_l1( 9) and trs_match1_l1(13) and 
                         trs_match1_l1(15);
    end process;

    process(trs_match2_l1)
    begin
        trs_match2(0) <= trs_match2_l1( 0) and trs_match2_l1( 4) and 
                         trs_match2_l1( 6);
        trs_match2(1) <= trs_match2_l1( 1) and trs_match2_l1( 5) and 
                         trs_match2_l1( 7);
        trs_match2(2) <= trs_match2_l1( 2) and trs_match2_l1( 6) and 
                         trs_match2_l1( 8);
        trs_match2(3) <= trs_match2_l1( 3) and trs_match2_l1( 7) and 
                         trs_match2_l1( 9);
        trs_match2(4) <= trs_match2_l1( 4) and trs_match2_l1( 8) and 
                         trs_match2_l1(10);
        trs_match2(5) <= trs_match2_l1( 5) and trs_match2_l1( 9) and 
                         trs_match2_l1(11);
        trs_match2(6) <= trs_match2_l1( 6) and trs_match2_l1(10) and 
                         trs_match2_l1(12);
        trs_match2(7) <= trs_match2_l1( 7) and trs_match2_l1(11) and 
                         trs_match2_l1(13);
        trs_match2(8) <= trs_match2_l1( 8) and trs_match2_l1(12) and 
                         trs_match2_l1(14);
        trs_match2(9) <= trs_match2_l1( 9) and trs_match2_l1(13) and 
                         trs_match2_l1(15);
    end process;

    process(trs_match3_l1)
    begin
        trs_match3(0) <= trs_match3_l1( 0) and trs_match3_l1( 4) and 
                         trs_match3_l1( 6);
        trs_match3(1) <= trs_match3_l1( 1) and trs_match3_l1( 5) and 
                         trs_match3_l1( 7);
        trs_match3(2) <= trs_match3_l1( 2) and trs_match3_l1( 6) and 
                         trs_match3_l1( 8);
        trs_match3(3) <= trs_match3_l1( 3) and trs_match3_l1( 7) and 
                         trs_match3_l1( 9);
        trs_match3(4) <= trs_match3_l1( 4) and trs_match3_l1( 8) and 
                         trs_match3_l1(10);
        trs_match3(5) <= trs_match3_l1( 5) and trs_match3_l1( 9) and 
                         trs_match3_l1(11);
        trs_match3(6) <= trs_match3_l1( 6) and trs_match3_l1(10) and 
                         trs_match3_l1(12);
        trs_match3(7) <= trs_match3_l1( 7) and trs_match3_l1(11) and 
                         trs_match3_l1(13);
        trs_match3(8) <= trs_match3_l1( 8) and trs_match3_l1(12) and 
                         trs_match3_l1(14);
        trs_match3(9) <= trs_match3_l1( 9) and trs_match3_l1(13) and 
                         trs_match3_l1(15);
    end process;

    -- third level of gates generates a unary bit pattern indicating which offsets
    -- contain valid TRS symbols
    trs_match_all <= trs_match1 and trs_match2 and trs_match3;

    -- If any of the bits in trs_match_all are asserted, the assert trs_detected        
    trs_detected <= '0' when (trs_match_all = (trs_match_all'range => '0')) else
                    '1';

    -- The following case statement asserts trs_error if more than one bit is set
    -- in trs_match_all.
    process(trs_match_all)
    begin
        case trs_match_all is
            when "0000000000" => trs_error  <= '0';
            when "0000000001" => trs_error  <= '0';
            when "0000000010" => trs_error  <= '0';
            when "0000000100" => trs_error  <= '0';
            when "0000001000" => trs_error  <= '0';
            when "0000010000" => trs_error  <= '0';
            when "0000100000" => trs_error  <= '0';
            when "0001000000" => trs_error  <= '0';
            when "0010000000" => trs_error  <= '0';
            when "0100000000" => trs_error  <= '0';
            when "1000000000" => trs_error  <= '0';
            when others       => trs_error  <= '1';
        end case;   
    end process;

    --
    -- The following logic encodes the trs_match_all vector into a binary offset code.
    --
    offset_val(0) <= trs_match_all(1) or trs_match_all(3) or trs_match_all(5) or
                     trs_match_all(7) or trs_match_all(9);
    offset_val(1) <= trs_match_all(2) or trs_match_all(3) or trs_match_all(6) or
                     trs_match_all(7);
    offset_val(2) <= trs_match_all(4) or trs_match_all(5) or trs_match_all(6) or
                     trs_match_all(7);
    offset_val(3) <= trs_match_all(8) or trs_match_all(9);

    --
    -- offset_reg: barrel shifter offset register
    --
    -- The offset_reg loads the offset_val whenever trs_detected is
    -- asserted and trs_error is not asserted and frame_en is asserted.
    --
    process(clk, rst)
    begin
        if (rst = '1') then
            offset_reg <= (others => '0');
        elsif (clk'event and clk = '1') then
            if (ce = '1') then
                if (trs_detected = '1' and trs_error = '0' and 
                    frame_en = '1') then
                    offset_reg <= offset_val;
                end if;
            end if;
        end if;
    end process;

    --
    -- New start position detector
    -- 
    -- A comparison between offset_val and offset_reg determines if
    -- the new offset is different than the current one. If there is
    -- a mismatch and frame_en is not asserted, then the nsp output
    -- will be asserted.
    --
    new_offset <= '0' when offset_val = offset_reg else
                  '1';

    process(clk, rst)
    begin
        if (rst = '1') then
            nsp <= '1';
        elsif (clk'event and clk = '1') then
            if (ce = '1') then
                if (trs_detected = '1' and trs_error = '0') then
                    nsp <= not frame_en and new_offset;
                end if;
            end if;
        end if;
    end process;

    --
    -- barrel_in: barrel shifter input register
    --
    -- This register implements a pipeline delay stage so that the
    -- barrel shifter's data input matches the delay on the offset
    -- input caused by the offset_reg.
    --
    process(clk, rst)
    begin
        if (rst = '1') then
            barrel_in <= (others => '0');
        elsif (clk'event and clk = '1') then
            if (ce = '1') then
                barrel_in <= in2_reg(8 downto 0) & in3_reg;
            end if;
        end if;
    end process;

    --
    -- barrel shifter
    --
    -- The barrel shifter extracts a 10-bit field from the 19-bit barrel_in 
    -- vector. The bits extracted depend on the value of the offset_reg. If 
    -- offset_reg is zero, barrel_in[9:0] are output by the barrel shifter. At 
    -- the other extreme, an offset_reg value of 9 causes the barrel shifter to 
    -- output barrel_in[18:9].
    --
    -- It is implemented as a two-level MUX structure. The first level consists 
    -- of 13 3-input MUXes which do the gross (4 increment) shifting. The second
    -- level consists of 10 4-input MUXes which do the fine (1 increment 
    -- shifting) by selecting which first level MUX output is selected to drive 
    -- the output bit. Note that to make it easier to code the barrel shifter 
    -- first level with a for loop, the bs_in vector expands the barrel_in value
    -- out to 20 bits with the two MS dummy bits permanently set to zero.
    --
    bs_in <= "00" & barrel_in;              -- create 20-bit input vector
    bs_sm <= offset_reg(3) & offset_reg(2); -- MUX sel bits for first level
    bs_sl <= offset_reg(1) & offset_reg(0); -- MUX sel bits for second level

    process(bs_in, bs_sm)                   -- implement first level of MUXes
    begin
        for i in 0 to 12 loop
            case bs_sm is
                when "00"   => bs_m1(i) <= bs_in(i);
                when "01"   => bs_m1(i) <= bs_in(i + 4);
                when "10"   => bs_m1(i) <= bs_in(i + 8);
                when others => bs_m1(i) <= '0';
            end case;
        end loop;
    end process;

    process(bs_m1, bs_sl)                   -- implement second level of MUXes
    begin
        for i in 0 to 9 loop
            case bs_sl is
                when "00"   => barrel_out(i) <= bs_m1(i);
                when "01"   => barrel_out(i) <= bs_m1(i + 1);
                when "10"   => barrel_out(i) <= bs_m1(i + 2);
                when others => barrel_out(i) <= bs_m1(i + 3);
            end case;
        end loop;
    end process;

    --
    -- The output of the module is the barrel shifter output
    --
    q <= barrel_out;

    --
    -- trs: trs output generation logic
    --
    -- The trs_out register is a 4-bit shift register which shifts everytime
    -- the bit_cntr(0) bit is asserted. The trs output signal is the OR of
    -- the four bits in this register so it becomes asserted when the first
    -- character of the TRS symbol is output and remains asserted for the
    -- following three characters of the TRS symbol.
    --
    process(clk, rst)
    begin
        if (rst = '1') then
            trs_out <= (others => '0');
        elsif (clk'event and clk = '1') then
            if (ce = '1') then
                trs_out <= trs_detected & trs_out(3 downto 1);
            end if;
        end if;
    end process;

    trs <= trs_out(3) or trs_out(2) or trs_out(1) or trs_out(0);

end synth;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -