OpenCores
URL https://opencores.org/ocsvn/spacewire_light/spacewire_light/trunk

Subversion Repositories spacewire_light

[/] [spacewire_light/] [trunk/] [rtl/] [vhdl/] [spwxmit_fast.vhd] - Diff between revs 2 and 3

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 2 Rev 3
Line 120... Line 120...
--   5 txclk + 3 sysclk = 5 + 3*4 txclk = 17 txclk
--   5 txclk + 3 sysclk = 5 + 3*4 txclk = 17 txclk
--  is less than 20 bit periods even at maximum transmission rate, so
--  is less than 20 bit periods even at maximum transmission rate, so
--  no problem there.
--  no problem there.
--
--
--  This is different when the data stream includes 4-bit tokens.
--  This is different when the data stream includes 4-bit tokens.
--  See the datasheet for an analysis of that case.
--  See the manual for further comments.
--
--
--  Implementation guidelines
--  Implementation guidelines
--  -------------------------
--  -------------------------
--
--
--  To minimize clock skew, IOB flip-flops should be used to drive
--  To minimize clock skew, IOB flip-flops should be used to drive
Line 198... Line 198...
 
 
    -- Data records passed between clock domains.
    -- Data records passed between clock domains.
    type token_type is record
    type token_type is record
        tick:       std_ulogic;                     -- send time code
        tick:       std_ulogic;                     -- send time code
        fct:        std_ulogic;                     -- send FCT
        fct:        std_ulogic;                     -- send FCT
 
        fctpiggy:   std_ulogic;                     -- send FCT and N-char
        flag:       std_ulogic;                     -- send EOP or EEP
        flag:       std_ulogic;                     -- send EOP or EEP
        char:       std_logic_vector(7 downto 0);   -- character or time code
        char:       std_logic_vector(7 downto 0);   -- character or time code
    end record;
    end record;
 
 
    -- Registers in txclk domain
    -- Registers in txclk domain
Line 218... Line 219...
        b_txflip:   std_ulogic;
        b_txflip:   std_ulogic;
        b_valid:    std_ulogic;
        b_valid:    std_ulogic;
        b_token:    token_type;
        b_token:    token_type;
        -- stage C
        -- stage C
        c_update:   std_ulogic;
        c_update:   std_ulogic;
 
        c_busy:     std_ulogic;
        c_esc:      std_ulogic;
        c_esc:      std_ulogic;
        c_fct:      std_ulogic;
        c_fct:      std_ulogic;
        c_bits:     std_logic_vector(8 downto 0);
        c_bits:     std_logic_vector(8 downto 0);
        -- stage D
        -- stage D
        d_bits:     std_logic_vector(8 downto 0);
        d_bits:     std_logic_vector(8 downto 0);
Line 275... Line 277...
        allow_char: std_ulogic;                     -- '1' when allowed to send data and time
        allow_char: std_ulogic;                     -- '1' when allowed to send data and time
        sent_fct:   std_ulogic;                     -- '1' when at least one FCT token was sent
        sent_fct:   std_ulogic;                     -- '1' when at least one FCT token was sent
    end record;
    end record;
 
 
    -- Initial state of system clock domain
    -- Initial state of system clock domain
 
    constant token_reset: token_type := (
 
        tick        => '0',
 
        fct         => '0',
 
        fctpiggy    => '0',
 
        flag        => '0',
 
        char        => (others => '0') );
    constant regs_reset: regs_type := (
    constant regs_reset: regs_type := (
        txenreg     => '0',
        txenreg     => '0',
        txdivreg    => (others => '0'),
        txdivreg    => (others => '0'),
        txdivnorm   => '0',
        txdivnorm   => '0',
        txdivtmp    => "00",
        txdivtmp    => "00",
        txdivsafe   => '0',
        txdivsafe   => '0',
        sysflip0    => '0',
        sysflip0    => '0',
        sysflip1    => '0',
        sysflip1    => '0',
        token0      => ( tick => '0', fct => '0', flag => '0', char => (others => '0') ),
        token0      => token_reset,
        token1      => ( tick => '0', fct => '0', flag => '0', char => (others => '0') ),
        token1      => token_reset,
        tokmux      => '0',
        tokmux      => '0',
        txflip0     => "00",
        txflip0     => "00",
        txflip1     => "00",
        txflip1     => "00",
        pend_fct    => '0',
        pend_fct    => '0',
        pend_char   => '0',
        pend_char   => '0',
Line 334... Line 342...
    begin
    begin
        v           := r;
        v           := r;
        vtx         := rtx;
        vtx         := rtx;
        v_needtoken := '0';
        v_needtoken := '0';
        v_havetoken := '0';
        v_havetoken := '0';
        v_token     := ( tick => '0', fct => '0', flag => '0', char => (others => '0') );
        v_token     := token_reset;
 
 
        -- ---- FAST CLOCK DOMAIN ----
        -- ---- FAST CLOCK DOMAIN ----
 
 
        -- Stage A: Synchronize token buffer counts from system clock domain.
        -- Stage A: Synchronize token buffer counts from system clock domain.
        vtx.a_sysflip0(0) := r.sysflip0;
        vtx.a_sysflip0(0) := r.sysflip0;
Line 347... Line 355...
        vtx.a_sysflip1(1) := rtx.a_sysflip1(0);
        vtx.a_sysflip1(1) := rtx.a_sysflip1(0);
 
 
        -- Stage B: Multiplex tokens from system clock domain.
        -- Stage B: Multiplex tokens from system clock domain.
        -- Update stage B three bit periods after updating stage C
        -- Update stage B three bit periods after updating stage C
        -- (i.e. in time for the next update of stage C).
        -- (i.e. in time for the next update of stage C).
        -- Do not update stage B if the last token from stage C was ESC;
        -- Do not update stage B if stage C is indicating that it needs to
        -- stage C already knows what token to put after the ESC.
        -- send a second token to complete its task.
        vtx.b_update := rtx.txclken and rtx.e_count(0) and (not rtx.c_esc);
        vtx.b_update := rtx.txclken and rtx.e_count(0) and (not rtx.c_busy);
        if rtx.b_mux = '0' then
        if rtx.b_mux = '0' then
            vtx.b_txflip := rtx.txflip0;
            vtx.b_txflip := rtx.txflip0;
        else
        else
            vtx.b_txflip := rtx.txflip1;
            vtx.b_txflip := rtx.txflip1;
        end if;
        end if;
Line 378... Line 386...
        end if;
        end if;
 
 
        -- Stage C: Prepare to transmit EOP, EEP or a data character.
        -- Stage C: Prepare to transmit EOP, EEP or a data character.
        vtx.c_update := rtx.txclken and rtx.e_count(3);
        vtx.c_update := rtx.txclken and rtx.e_count(3);
        if rtx.c_update = '1' then
        if rtx.c_update = '1' then
            -- NULL is broken into two tokens: ESC + FCT
 
            -- time codes are broken into two tokens: ESC + char
            -- NULL is broken into two tokens: ESC + FCT.
 
            -- Time-codes are broken into two tokens: ESC + char.
 
 
 
            -- Enable c_esc on the first pass of a NULL or a time-code.
            vtx.c_esc   := (rtx.b_token.tick or (not rtx.b_valid)) and
            vtx.c_esc   := (rtx.b_token.tick or (not rtx.b_valid)) and
                           (not rtx.c_esc);
                           (not rtx.c_esc);
            vtx.c_fct   := rtx.b_token.fct or (not rtx.b_valid);
 
 
            -- Enable c_fct on the first pass of an FCT and on
 
            -- the second pass of a NULL (also the first pass, but c_esc
 
            -- is stronger than c_fct).
 
            vtx.c_fct   := (rtx.b_token.fct and (not rtx.c_busy)) or
 
                           (not rtx.b_valid);
 
 
 
            -- Enable c_busy on the first pass of a NULL or a time-code
 
            -- or a piggy-backed FCT. This will tell stage B that we are
 
            -- not done yet.
 
            vtx.c_busy  := (rtx.b_token.tick or (not rtx.b_valid) or
 
                            rtx.b_token.fctpiggy) and (not rtx.c_busy);
 
 
            if rtx.b_token.flag = '1' then
            if rtx.b_token.flag = '1' then
                if rtx.b_token.char(0) = '0' then
                if rtx.b_token.char(0) = '0' then
                    -- prepare to send EOP
                    -- prepare to send EOP
                    vtx.c_bits  := "000000101"; -- EOP = P101
                    vtx.c_bits  := "000000101"; -- EOP = P101
                else
                else
Line 491... Line 514...
            vtx.txflip1   := '0';
            vtx.txflip1   := '0';
            vtx.b_update  := '0';
            vtx.b_update  := '0';
            vtx.b_mux     := '0';
            vtx.b_mux     := '0';
            vtx.b_valid   := '0';
            vtx.b_valid   := '0';
            vtx.c_update  := '0';
            vtx.c_update  := '0';
 
            vtx.c_busy    := '1';
            vtx.c_esc     := '1';           -- need to send 2nd part of NULL
            vtx.c_esc     := '1';           -- need to send 2nd part of NULL
            vtx.c_fct     := '1';
            vtx.c_fct     := '1';
            vtx.d_bits    := "000000111";   -- ESC = P111
            vtx.d_bits    := "000000111";   -- ESC = P111
            vtx.d_cnt4    := '1';           -- 3 bits + implicit parity bit
            vtx.d_cnt4    := '1';           -- 3 bits + implicit parity bit
            vtx.d_cnt10   := '0';
            vtx.d_cnt10   := '0';
Line 582... Line 606...
            -- Prepare new token.
            -- Prepare new token.
            if r.allow_char = '1' and r.pend_tick = '1' then
            if r.allow_char = '1' and r.pend_tick = '1' then
                -- prepare to send time code
                -- prepare to send time code
                v_token.tick  := '1';
                v_token.tick  := '1';
                v_token.fct   := '0';
                v_token.fct   := '0';
 
                v_token.fctpiggy := '0';
                v_token.flag  := '0';
                v_token.flag  := '0';
                v_token.char  := r.pend_time;
                v_token.char  := r.pend_time;
                v_havetoken   := '1';
                v_havetoken   := '1';
                if v_needtoken = '1' then
                if v_needtoken = '1' then
                    v.pend_tick := '0';
                    v.pend_tick := '0';
                end if;
                end if;
            elsif r.allow_fct = '1' and (xmiti.fct_in = '1' or r.pend_fct = '1') then
            else
 
                if r.allow_fct = '1' and (xmiti.fct_in = '1' or r.pend_fct = '1') then
                -- prepare to send FCT
                -- prepare to send FCT
                v_token.tick  := '0';
 
                v_token.fct   := '1';
                v_token.fct   := '1';
                v_token.flag  := '0';
 
                v_havetoken   := '1';
                v_havetoken   := '1';
                if v_needtoken = '1' then
                if v_needtoken = '1' then
                    v.pend_fct  := '0';
                    v.pend_fct  := '0';
                    v.sent_fct  := '1';
                    v.sent_fct  := '1';
                end if;
                end if;
            elsif r.allow_char = '1' and r.pend_char = '1' then
                end if;
 
                if r.allow_char = '1' and r.pend_char = '1' then
                -- prepare to send N-Char
                -- prepare to send N-Char
                v_token.tick  := '0';
                    -- Note: it is possible to send an FCT and an N-Char
                v_token.fct   := '0';
                    -- together by enabling the fctpiggy flag.
 
                    v_token.fctpiggy := v_token.fct;
                v_token.flag  := r.pend_data(8);
                v_token.flag  := r.pend_data(8);
                v_token.char  := r.pend_data(7 downto 0);
                v_token.char  := r.pend_data(7 downto 0);
                v_havetoken   := '1';
                v_havetoken   := '1';
                if v_needtoken = '1' then
                if v_needtoken = '1' then
                    v.pend_char := '0';
                    v.pend_char := '0';
                end if;
                end if;
            end if;
            end if;
 
            end if;
 
 
            -- Put new token in slot.
            -- Put new token in slot.
            if v_havetoken = '1' then
            if v_havetoken = '1' then
                if r.tokmux = '0' then
                if r.tokmux = '0' then
                    if r.sysflip0 = r.txflip0(1) then
                    if r.sysflip0 = r.txflip0(1) then

powered by: WebSVN 2.1.0

© copyright 1999-2019 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.