Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

Serial transmission seems one step behind where it should be

Hi everyone

As a solo project for school I'm building a one bit error detection and correction circuit. The error correction and detection itself is happening on the DE2 and I have a small program written in C on the computer which communicates back and forth with the board to send in code words with errors in them to test the circuit.

I've got everything working on the error detection/correction side of things but I'm having the strangest error pop up when communicating between the computer and the board. Whenever the board receives a word to be checked, it transmits out the answer for the previous word received.

So the board is always sending out answers one step behind what has been received and I can't figure it out for the life of me. I've put some of my code below. Hopefully it's just a silly mistake that I've overlooked. I'd appreciate any tips or tricks you guys can send my way.

My code for everything so far. The parts in red are where the codeword is sent out and received

    
        if(KEY(0) = '0') then        ECC_STATE    <= INIT_STATE;
        LEDR(17 downto 14) <= (others => '0');
        
    elsif(CLOCK_50'EVENT AND CLOCK_50 = '1') then        
        if(ECC_STATE = INIT_STATE) then
            -- Initialise everything
            TX_START        <=    '0';
            TX_DATA        <=    (others => '0');
            ECC_STATE    <= RX_WAIT_STATE1;
            START_DECODE<= '0';
            LEDR(17 downto 15)    <= "000";
            LEDG    <= (others => '0');
            
        elsif(ECC_STATE = RX_WAIT_STATE1) then
            LEDR(17 downto 15)    <= "001";            -- State indicator
            TX_START                <= '0';            -- Reset Transmitting indicator
            if(RX_BUSY = '1') then                    -- Receiving started
                ECC_STATE    <= RX_WAIT_STATE2;        -- Next state
            else
                ECC_STATE    <= RX_WAIT_STATE1;        -- Stay in this state
            end if;
            
        elsif(ECC_STATE = RX_WAIT_STATE2) then
            LEDR(17 downto 15)    <= "010";            -- State indicator
            if(RX_BUSY = '0') then                        -- Receiving finished
                ECC_STATE        <= DECODE_STATE;        -- Transition to next state
                CODED        <=    RX_DATA(6 downto 0);    -- Data to be decoded
                LEDR(7 downto 0) <= RX_DATA;            -- Data Received on LEDs
                START_DECODE    <= '1';                -- Start decoding
            else
                ECC_STATE    <= RX_WAIT_STATE2;
            end if;
            
        elsif(ECC_STATE = DECODE_STATE) then
            LEDR(17 downto 15)    <= "011";            -- State indicator
            START_DECODE    <= '0';                -- Reset Start decode signal
            
            -- Wait for decoding to be complete and make sure transmitting not still happening
            if(DECODE_BUSY = '1' OR TX_BUSY = '1') then
                ECC_STATE    <= DECODE_STATE;
            else    -- stay in this state
                ECC_STATE    <= SEND_STATE;
            end if;
            
        elsif(ECC_STATE = SEND_STATE) then
            LEDR(17 downto 15)<= "100";                -- State indicator
            TX_DATA         <=    '0' & DECODED;        -- Data to be transmitted
            LEDG(6 downto 0) <= DECODED;            -- Show data on LEDs
            TX_START         <= '1';                -- Send start transmitting signal
            ECC_STATE         <=    RX_WAIT_STATE1;    -- Transition to next state
        else
            ECC_STATE         <= RX_WAIT_STATE1;        -- To avoid inferring latches
        end if;
    end if;

Here is the portion where the decoding actually happens. This is instantiated as a process within the previous code. Again, parts in red are where the data comes in and goes out.


process(Reset_L, CLK)
begin
    if(Reset_L = '0') then
        State <= ResetState;
    elsif (CLK'EVENT AND CLK = '1') then
    
        if(State = ResetState) then        -- reset everything
            State    <= Ready;
            Syndrome        <=    (others => '0');
            DataDecode    <= (others => '0');
            ShiftCount    <=    "1110";
            Busy            <= '0';
            
        elsif(State = Ready) then            -- Default Wait state
            State    <= Ready;
            Syndrome        <=    "000";
            DataDecode    <=    "000000000000000000000";
            Busy             <= '0';
            if(Start = '1') then                -- Start signal received
                State    <=    ShiftIN;      -- next state
                Busy    <=    '1';            -- Decoding is busy
                DataDecode(20 downto 14)    <=    DATAIN;     --copy in the data
            end if;
        
        elsif(State = ShiftIN) then
            Busy            <= '1';
            Syndrome(2)       <= DataDecode(14) XOR Syndrome(0);
            Syndrome(1)    <= Syndrome(2) XOR Syndrome(0);
            Syndrome(0)    <= Syndrome(1);
            DataDecode    <= '0' & DataDecode(20 downto 1);
            ShiftCount    <= ShiftCount - 1;
            if(ShiftCount = "0001") then -- on the last shift
                State <= Finished;
            end if;
            
            if(ShiftCount <= "0111") then
                DataDecode(6)    <= DataDecode(7) XOR (Syndrome(0) AND Syndrome(2) AND(NOT(Syndrome(1))));
            end if;    
        
        elsif(State = Finished) then
            Busy            <= '0';   -- no longer busy
            DATAOUT        <= DataDecode(6 downto 0);   -- Data to be sent out
            Syndrome             <= "000";       -- reset syndrome
            ShiftCount            <= "1110";     -- reset the count
            State         <= Ready;      -- next state
            
        else 
            State            <= ResetState;
        end if;
    end if;
    
end process;

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If its one clock behind where it should be, then its just a pipelining problem. Add an extra register in the other, parrallel data path and everything is aligned again.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    If its one clock behind where it should be, then its just a pipelining problem. Add an extra register in the other, parrallel data path and everything is aligned again.

    --- Quote End ---

    I was thinking that myself but adding an extra wait state did not fix the problem. The processes aren't truly parallel since one has to wait for the other to finish before continuing.

    Am I making things too complicated by having separate processes? Would I be better off just combining them into one larger process?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Having 2 or 1 process isnt really here nor there, its the code and comments that matter. To fix this it's going to take good test vectors in a good testbench to replicate the problem to debug it yourself.