Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17252 Discussions

Serial transmission seems one step behind where it should be

Altera_Forum
Honored Contributor II
1,348 Views

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;
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
635 Views

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.

0 Kudos
Altera_Forum
Honored Contributor II
635 Views

 

--- 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?
0 Kudos
Altera_Forum
Honored Contributor II
635 Views

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.

0 Kudos
Reply