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

📄 anc_pkt_gen.vhd

📁 XAPP299 version 1.0 reference design files
💻 VHD
📖 第 1 页 / 共 2 页
字号:
                next_state <= S_WAIT;
        end case;   
    end process;
            
    --
    -- FSM: outputs
    --
    -- This block decodes the current state to generate the various outputs of 
    -- the FSM.
    --
    process(current_state, calc_udw_parity, send_pkt)
    begin
        -- Unless specifically assigned in the case statement, all FSM outputs
        -- default to the values here..
        pkt_rdy_out     <= '0';
        pmux_sel        <= PMUXSEL_DID;
        dmux_sel        <= DMUXSEL_PGEN;
        omux_sel        <= OMUXSEL_DATA;
        clr_checksum    <= '0';
        clr_udw_rd_cntr <= '0';
        inc_udw_rd_cntr <= '0';
        dec_dc          <= '0';
        pkt_end         <= '0';
        pkt_in_empty_x  <= '0';
        ld_out_reg      <= '0';
        
        case current_state is
            when S_WAIT => 
                pkt_in_empty_x <= '1';
                omux_sel <= OMUXSEL_ADF0;
                ld_out_reg <= '1';

            when S_ADF1 =>
                omux_sel <= OMUXSEL_ADF1;
                pkt_rdy_out <= '1';
                if (send_pkt = '1') then
                    ld_out_reg <= '1';
                else
                    ld_out_reg <= '0';
                end if; 

            when S_ADF2 =>
                omux_sel <= OMUXSEL_ADF1;
                ld_out_reg <= '1';
                clr_checksum <= '1';

            when S_DID =>
                pmux_sel <= PMUXSEL_DID;
                dmux_sel <= DMUXSEL_PGEN;
                omux_sel <= OMUXSEL_DATA;
                ld_out_reg <= '1';

            when S_DBN =>
                pmux_sel <= PMUXSEL_DBN;
                dmux_sel <= DMUXSEL_PGEN;
                omux_sel <= OMUXSEL_DATA;
                ld_out_reg <= '1';
                clr_udw_rd_cntr <= '1';  

            when S_DC =>
                pmux_sel <= PMUXSEL_DC;
                dmux_sel <= DMUXSEL_PGEN;
                omux_sel <= OMUXSEL_DATA;
                inc_udw_rd_cntr <= '1';
                dec_dc <= '1';
                ld_out_reg <= '1';
            
            when S_UDW =>
                pmux_sel <= PMUXSEL_UDW;
                if (calc_udw_parity = '1') then
                    dmux_sel <= DMUXSEL_PGEN;
                else
                    dmux_sel <= DMUXSEL_UDW;
                end if;
                omux_sel <= OMUXSEL_DATA;
                inc_udw_rd_cntr <= '1';
                dec_dc <= '1';
                ld_out_reg <= '1';
                
            when S_CHK =>
                omux_sel <= OMUXSEL_CHK;
                ld_out_reg <= '1';

            when S_END =>
                pkt_end <= '1';

            when S_ABRT =>
                omux_sel <= OMUXSEL_ADF0;
                ld_out_reg <= '1';

            when others =>
        end case;
    end process;
                                
    --
    -- pmux
    --
    -- The pmux selects the input to the parity generator. There are four 
    -- inputs: DID register, DBN register, DC register, and UDW RAM.
    --
    process(pmux_sel, udw, did, dbn, dc)
    begin
        case pmux_sel is
            when PMUXSEL_DID => pmux <= did;
            when PMUXSEL_DBN => pmux <= dbn;
            when PMUXSEL_DC  => pmux <= dc;
            when others      => pmux <= udw(7 downto 0);
        end case;
    end process;

    --
    -- dmux
    --
    -- The dmux selects the data word to be sent to the omux and the checksum 
    -- generator. There are two inputs: the UDW RAM or the output of the pmux 
    -- via the parity geneator.
    --
    process(dmux_sel, pword, udw)
    begin
        if (dmux_sel = DMUXSEL_UDW) then
            dmux <= udw;
        else
            dmux <= pword;
        end if;
    end process;

    --
    -- omux
    --
    -- The omux selects the value to send to the output of the module. There are
    -- four inputs: all zeros (first ADF word), all ones (second & third ADF
    -- words), the output of the dmux, or the checksum generator.
    --
    process(omux_sel, dmux, checksum)
    begin
        case omux_sel is
            when OMUXSEL_ADF0 => omux <= ANC_ADF0;
            when OMUXSEL_ADF1 => omux <= ANC_ADF1;
            when OMUXSEL_DATA => omux <= dmux;
            when others       => omux <= (not checksum(8) & checksum);
        end case;
    end process;

    --
    -- parity bit generation
    --
    -- This code calculates the parity of bits 7:0 of the data word. The parity
    -- bit is inserted at bit 8 of the data word and the inverse of the parity
    -- bit is inserted at bit 9.
    --
    parity <= pmux(7) xor pmux(6) xor pmux(5) xor pmux(4) xor pmux(3) xor
              pmux(2) xor pmux(1) xor pmux(0);

    pword <= (not parity & parity & pmux(7 downto 0));

    --
    -- checksum calculator
    --
    -- This code generates a checksum for the ANC packet. The checksum is 
    -- cleared to zero prior to beginning the checksum calculation by the FSM 
    -- asserting the clr_checksum signal. The data word is added to the current  
    -- checksum continuously. The checksum is a 9-bit value and is computed by  
    -- summing all but the MSB of the data word with the current checksum value  
    -- and ignoring any carry bits.
    --
    process(clk,rst)
    begin
        if (rst = '1') then
            checksum <= (others => '0');
        elsif (clk'event and clk = '1') then
            if (ce = '1') then
                if (clr_checksum = '1') then
                    checksum <= (others => '0');
                else
                    checksum <= std_ulogic_vector(std_logic_vector(checksum) + 
                                                  std_logic_vector(dmux(8 downto 0)));
                end if;
            end if;
        end if;
    end process;

    --
    -- DID register
    --
    -- This register holds the DID word for the ANC packet. The DID register 
    -- loads from the data_in bus when ld_did is asserted. Only eight bits are 
    -- stored in the DID register. The module generates the correct parity bits 
    -- for the two MSBs of the DID word when inserted in the ANC packet.
    --
    process(clk,rst)
    begin
        if (rst = '1') then
            did <= (others => '0');
        elsif (clk'event and clk = '1') then
            if (ce = '1') then
                if (ld_did = '1' and pkt_in_empty_x = '1') then
                    did <= data_in(7 downto 0);
                end if;
            end if;
        end if;
    end process;

    --
    -- DBN/SDID register
    --
    -- This register holds the DBN or SDID word for the ANC packet. The DBN 
    -- register loads from the data_in bus when the ld_dbn signal is asserted. 
    -- Only eight bits are stored in the register. The module generates the 
    -- correct parity bits for the two MSBs of the DBN/SDID word when inserted
    -- into the ANC packet.
    --
    process(clk, rst)
    begin
        if (rst = '1') then
            dbn <= (others => '0');
        elsif (clk'event and clk = '1') then
            if (ce = '1') then
                if (ld_dbn = '1' and pkt_in_empty_x = '1') then
                    dbn <= data_in(7 downto 0);
                end if;
            end if;
        end if;
    end process;
                
    --
    -- DC register/counter
    --
    -- This register holds the DC (data count) word for the ANC packet. It loads
    -- from the data_in bus when the ld_dc signal is asserted. Only eight bits 
    -- are stored in the register. The DC register also acts as a down counter 
    -- as UDW words are output.
    --
    process(clk,rst)
    begin
        if (rst = '1') then
            dc <= (others => '0');
        elsif (clk'event and clk = '1') then
            if (ld_dc = '1' and pkt_in_empty_x = '1') then
                dc <= data_in(7 downto 0);
            elsif (dec_dc = '1') then
                dc <= std_ulogic_vector(std_logic_vector(dc) - 1);
            end if;
        end if;
    end process;
            
    dc_eq_0 <= '1' when dc = UBYTE_ZERO else '0';

    --
    -- UDW RAM
    --  
    -- The UDW RAM holds the user data words. Data is written into the RAM by
    -- placing the data on the data_in bus, the address on the udw_wr_adr bus, 
    -- and asserting the ld_udw signal. All 10-bits of the data_in bus are 
    -- written to the UDW RAM. However, if the calc_udw_parity signal is 
    -- asserted as the packet is being generated, the two MSBs of the UDW RAM  
    -- are ignored and instead, the parity generator is used to generate parity 
    -- bits for the two MSBs of the UDW.
    --
    -- Code is given to infer either a block RAM or a single-port distributed
    -- RAM. Separate code is given for the distributed RAM so that a single-port 
    -- RAM will be inferred rather than a larger dual-port distributed RAM. In
    -- order to keep the control timing of both cases identical, a register for  
    -- the read address is inserted for the distributed RAM case. The block RAM 
    -- case requires a read address register in order to infer the block RAM.
    --

    ----------------------------------------------------------------------------
    -- Infer dual-port block RAM
    --
    -- Uncomment the following code to infer block RAM for the UDW RAM

--  	udw_wr_en <= ce and ld_udw and pkt_in_empty_x;
--   
--  	process(clk)
--  	begin
--      	if (clk'event and clk = '1') then
--          	if (udw_wr_en = '1') then
--              udw_ram(conv_integer(udw_wr_adr)) <= data_in;
--         	 end if;
--          	udw_rd_adr <= udw_rd_cntr;
--      	end if;
--  	end process;
--   
--  	udw <= udw_ram(conv_integer(udw_rd_adr));

    ----------------------------------------------------------------------------

    ----------------------------------------------------------------------------
    -- Infer single-port distributed RAM

    udw_wr_en <= ce and ld_udw and pkt_in_empty_x;
    udw_adr <= udw_wr_adr when ((ld_udw and pkt_in_empty_x) = '1') 
               else udw_rd_cntr;
      
    process(clk)
    begin
        if (clk'event and clk = '1') then
            if (udw_wr_en = '1') then
                udw_ram(conv_integer(udw_adr)) <= data_in;
            end if;
            udw <= udw_ram(conv_integer(udw_adr));
        end if;
    end process;

    --------------------------------------------------------------------------------

    --
    -- UDW read counter
    --
    -- This eight-bit up counter generates read addresses into the UDW RAM to 
    -- read out the UDW words in correct order.
    --
    process(clk, rst)
    begin
        if (rst = '1') then
            udw_rd_cntr <= (others => '0');
        elsif (clk'event and clk = '1') then
            if (ce = '1') then
                if (clr_udw_rd_cntr = '1') then
                    udw_rd_cntr <= (others => '0');
                elsif (inc_udw_rd_cntr = '1') then
                    udw_rd_cntr <= udw_rd_cntr + 1;
                end if;
            end if;
        end if;
    end process;

    --
    -- anc_out
    --
    -- This is the output register of the module. It loads from the omux 
    -- whenever the ld_out_reg signal is asserted.
    --
    process(clk,rst)
    begin
        if (rst = '1') then
            anc_out <= (others => '0');
        elsif (clk'event and clk = '1') then
            if (ce = '1') then
                if (ld_out_reg = '1') then
                    anc_out <= omux;
                end if;
            end if;
        end if;
    end process;

    --
    -- pkt_size
    --
    -- The pkt_size output is set to seven more than the size of they ANC 
    -- packet's payload (DC word).
    --
    pkt_size <= std_ulogic_vector(std_logic_vector(('0' & dc)) + 7);
        
    pkt_in_empty <= pkt_in_empty_x;
                    
end synth;

⌨️ 快捷键说明

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