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

📄 hdsdi_framer_mult.vhd

📁 SDI接口的源程序,包括扰码编码,并串转换,用VHDL硬件描述语言编写
💻 VHD
📖 第 1 页 / 共 2 页
字号:
    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 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 <= '1' when offset_val /= offset_reg else '0';

    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' 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 <= (dly_reg(18 downto 0) & dly_reg2);
            end if;
        end if;
    end process;

    --
    -- Barrel shifter
    --
    -- The barrel shifter extracts a 20-bit field from the bs_in vector.
    -- The bits extracted depend on the value of the offset_reg.  The barrel 
    -- shifter shifts the 39-bit input vector left by 0 to 19 bit positions. If
    -- the shift code is zero, then the resulting output is barrel_in[19:0]. On
    -- the other extreme, if the shift code is 19, then the resulting output is
    -- barrel_in[38:19].
    --
    -- This version of the barrel shifter is implemented in two levels. The top
    -- level shifts the input vector either 0 or 12 bit positions right. The 
    -- bottom level shifts zero to 11 bit positions right. MULT18X18 blocks are
    -- used to implement both levels.
    --

    --
    -- Barrel shifter top level
    --
    -- This level of the barrel shifter will right shift the input vector either
    -- 0 bit positions or 12 bit positions, depending on the sc_top bit.
    --
    -- Three 18X18 multipliers are used at the top level to implement 2:1 MUXes.
    -- Each 18x18 multiplier can be used for 9 2:1 MUXes. A for loop creates an 
    -- input vector for the top level MUXes. Another for loop picks all the odd
    -- outputs from the three MUXes for the 27-bit wide output vector to feed to
    -- the next level of the barrel shifter.
    --
    -- The inputs to the A term of the multipliers are arranged like this:
    --
    -- BS_TOP_A:  8 20  7 19  6 18  5 17  4 16  3 15  2 14  1 13  0 12
    -- BS_TOP_B: 17 29 16 28 15 27 14 26 13 25 12 24 11 23 10 22  9 21
    -- BS_TOP_C: 26 38 25 37 24 36 23 35 22 34 21 33 20 32 19 31 18 30
    --
    -- If the sc_top shift code bit is zero, the a multiplier value of 1 is 
    -- input to the B term of each multiplier. This results in each input bit 
    -- going straight out to the corresponding output bit (i.e. bit 1 of the A 
    -- input appears on bit 1 of the P port.
    --  
 
    process(barrel_in)
    begin
        for i in 0 to 26 loop
            bs_in(i * 2) <= barrel_in(i + 12);
            bs_in(i * 2 + 1) <= barrel_in(i);
        end loop;
    end process;  
    
    bstop_bin <= (1 => sc_top, 0 => not sc_top, others => '0');

    BS_TOP_A : MULT18X18
        port map (
            A       => bs_in(17 downto 0),
            B       => bstop_bin,
            P       => bstop_a);

    BS_TOP_B : MULT18X18
        port map (
            A       => bs_in(35 downto 18),
            B       => bstop_bin,
            P       => bstop_b);

    BS_TOP_C : MULT18X18
        port map (
            A       => bs_in(53 downto 36),
            B       => bstop_bin,
            P       => bstop_c);

    process(bstop_a, bstop_b, bstop_c)
    begin
        for i in 0 to 8 loop
            bstop(i)      <= bstop_a(i * 2 + 1);
            bstop(i + 9)  <= bstop_b(i * 2 + 1);
            bstop(i + 18) <= bstop_c(i * 2 + 1);
        end loop;
    end process;

    -- 
    -- Bottom level of barrel shifter
    --
    -- This level of the barrel shifter will shift the output of the top level
    -- left 0 to 11 bits. Note, however, that it only needs to shift the vector 
    -- 7 bits to the left if the top level is doing a 12-bit left shift.
    --
    -- The bottom level of the barrel shifter is made of another three 18x18
    -- multipliers. In this level, each multiplier implements seven 12:1 MUXes.
    -- The inputs to A input of the multipliers are connected like this:
    --
    -- BS_BOT_A: bstop[17:0]
    -- BS_BOT_B: bstop[24:7]
    -- BS_BOT_C: {barrel_in[31:27], bstop[26:14]}
    --
    -- BS_BOT_C has its MS 5 bits connected directly to the MS 5 bits from the 
    -- barrel shifter's input vector rather than from the 2:1 MUXes of the top
    -- level. This is because these bits positions are only used when shifting
    -- left more than 7 bits which can only occur if the top level is not 
    -- shifting. 
    --
    bsbot_bin <= ("000000" & sc_bot);

    BS_BOT_A : MULT18X18 
        port map (
            A       => bstop(17 downto 0),
            B       => bsbot_bin,
            P       => bsbot_a);

    BS_BOT_B : MULT18X18 
        port map (
            A       => bstop(24 downto 7),
            B       => bsbot_bin,
            P       => bsbot_b);

    bsbotc_ain <= (barrel_in(31 downto 27) & bstop(26 downto 14));

    BS_BOT_C : MULT18X18 
        port map (
            A       => bsbotc_ain,
            B       => bsbot_bin,
            P       => bsbot_c);

    barrel_out <= (bsbot_c(16 downto 11) & bsbot_b(17 downto 11) & bsbot_a(17 downto 11));

    --
    -- Barrel shifter shift code generation
    --
    -- This logic takes the offset_reg value and produces shift codes for the
    -- top and bottom level MUXes of the barrel shifter. sc_bot is 12-bit vector
    -- that always has only one bit asserted. The value is dependent upon 
    -- offset_reg MOD 12, such that if this result is 0, then sc_bot = 2048. If
    -- the result is 1, sc_bot = 1024. And so on, until the result is 11 and the
    -- shift code is 1. sc_top is 0 for offset_reg values of 11 or less and 1 
    -- otherwise.
    --

    process(offset_reg)
    begin
        case offset_reg is
            when "00000" => 
                sc_top <= '0';
                sc_bot <= "100000000000";

            when "00001" => 
                sc_top <= '0';
                sc_bot <= "010000000000";

            when "00010" => 
                sc_top <= '0';
                sc_bot <= "001000000000";

            when "00011" => 
                sc_top <= '0';
                sc_bot <= "000100000000";

            when "00100" => 
                sc_top <= '0';
                sc_bot <= "000010000000";

            when "00101" => 
                sc_top <= '0';
                sc_bot <= "000001000000";

            when "00110" => 
                sc_top <= '0';
                sc_bot <= "000000100000";

            when "00111" => 
                sc_top <= '0';
                sc_bot <= "000000010000";

            when "01000" => 
                sc_top <= '0';
                sc_bot <= "000000001000";

            when "01001" => 
                sc_top <= '0';
                sc_bot <= "000000000100";

            when "01010" => 
                sc_top <= '0';
                sc_bot <= "000000000010";

            when "01011" => 
                sc_top <= '0';
                sc_bot <= "000000000001";

            when "01100" => 
                sc_top <= '1';
                sc_bot <= "100000000000";

            when "01101" => 
                sc_top <= '1';
                sc_bot <= "010000000000";

            when "01110" => 
                sc_top <= '1';
                sc_bot <= "001000000000";

            when "01111" => 
                sc_top <= '1';
                sc_bot <= "000100000000";

            when "10000" => 
                sc_top <= '1';
                sc_bot <= "000010000000";

            when "10001" => 
                sc_top <= '1';
                sc_bot <= "000001000000";

            when "10010" => 
                sc_top <= '1';
                sc_bot <= "000000100000";

            when "10011" => 
                sc_top <= '1';
                sc_bot <= "000000010000";

            when others => 
                sc_top <= '0';
                sc_bot <= "100000000000";
        end case;
    end process;

    --
    -- Output registers
    --
    process(clk, rst)
    begin
        if rst = '1' then
            c_int <= (others => '0');
            y_int <= (others => '0');
        elsif clk'event and clk = '1' then
            if ce = '1' then
                c_int <= barrel_out(9 downto 0);
                y_int <= barrel_out(19 downto 10);
            end if;
        end if;
    end process;

    c <= c_int;
    y <= y_int;

    --
    -- 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;

    process(clk, rst)
    begin
        if rst = '1' then
            trs <= '0';
        elsif clk'event and clk = '1' then
            if ce = '1' then
                trs <= trs_out(3) or trs_out(2) or trs_out(1) or trs_out(0);
            end if;
        end if;
    end process;

    process(clk, rst)
    begin
        if rst = '1' then
            xyz_int <= '0';
        elsif clk'event and clk = '1' then
            if ce = '1' then
                xyz_int <= trs_out(0);
            end if;
        end if;
    end process;

    xyz <= xyz_int;
    eav <= xyz_int and y_int(6);
    sav <= xyz_int and not y_int(6);


    --
    -- TRS error detection
    --
    -- This code examines the protection bits in the XYZ word and asserts the
    -- trs_err output if an err is detected.
    --
    trs_err <= xyz_int and (
                    (y_int(5) xor y_int(6) xor y_int(7)) or
                    (y_int(4) xor y_int(8) xor y_int(6)) or
                    (y_int(3) xor y_int(8) xor y_int(7)) or
                    (y_int(2) xor y_int(8) xor y_int(7) xor y_int(6)) or
                    not y_int(9) or y_int(1) or y_int(0));

end synth;

⌨️ 快捷键说明

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