0
\$\begingroup\$

I'm really desperate right now. I have written a VHDL code that gets an input of type std_logic_vector(0 downto 0) [in__con1_dio4_rs485_rs] which it should collect in 8-bit blocks. For this I use an 8 bit vector [tmp], whereupon I perform a left-shift.

My problem here is that I only need every 8th result of tmp for the output, i.e. always when the vector has been completely rewritten with the inputs. Therefore I wrote a simple if-statement, which passes the tmp-value to the output [Whole-Frame] using the signal cntclk, which counts the passes of the overlying if-statement.

Unfortunately, it does not work if I check the cntclk for 7 (8 bits), because then the value is passed correctly at the beginning, but not anymore. But if I set cntclk to other values, like in the attached pictures, to 7 bits or 9 bits, it works fine.

I'm sorry if it should be a trivial question, but I've been looking for a solution since last week and can't find the right way.

Here the code:

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE IEEE.MATH_REAL.ALL;


ENTITY User IS
PORT (
Whole_Frame_ch5 : out std_logic_vector(7 downto 0) := (others => '0');
in_con1_dio3           : IN std_logic_vector(0 DOWNTO 0); -- SCLK
in_con1_dio4_rs485_rx  : IN std_logic_vector(0 DOWNTO 0); --MOSI
in_con1_dio6           : IN std_logic_vector(0 DOWNTO 0); --CS
    );
END;

ARCHITECTURE rtl OF User IS
signal clkT :   std_logic := '0';   --clock 
signal tmp: std_logic_vector(7 downto 0);
signal cntclk : integer := 0;
BEGIN

clkT <= in_con1_dio3(0);

PROCESS(clkT)

BEGIN

if falling_edge(clkT) and in_con1_dio6(0) = '0' then

--left shift 8 bit vector

tmp(0) <= in_con1_dio4_rs485_rx(0);
for i in 1 to 7 loop
    tmp(i) <= tmp(i - 1);
end loop;

cntclk <= cntclk + 1;

if cntclk = 8 then    --only changed this value for screenshots
  whole_Frame_ch5 <= tmp;
  cntclk <= 0;
end if;

end if; 

END PROCESS;

END ARCHITECTURE rtl;  -- of  User

Screenshots: the output is the second last wave, cntclk the last wave

cntclk = 6 --> passes tmp to output after 7 shifts

cntclk = 7 --> passes tmp to output after 8 shifts --does not work

cntclk = 8 --> passes tmp to output after 9 shifts

  1. Screenshot: cntclk = 6 --> passes tmp to output after 7 shifts
  2. Screenshot: cntclk = 7 --> passes tmp to output after 8 shifts --does not work
  3. Screenshot: cntclk = 8 --> passes tmp to output after 9 shifts

The only thing I have changed between these screenshots of the simulation was the value for the if-statement that checks the cntclk.

Thank you in advance..

Mik

\$\endgroup\$
0
\$\begingroup\$

Your leftshift doesn't work. You're putting the new value at bit position 0 and then start shifting from bit position 1 to bit position 7. Usually you would do something like this

tmp <= tmp(tmp'left-1 downto 0) & in_con1_dio4_rs485_rx(0);

Why do you re-assign your clock signal, just use the one from the port definition. Then you might should have a reset signal to e.g. properly initialize your tmp vector. And last but not least, you start counting from 0 and compare to 8, note that signal assignments in processes happen after the process has finished, so you actually wanna check for cntclk = 7.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ ok you are right. I've found this left-shift in my university records. I've now changed it. But one problem remains: I can check for a value I want and it works, except when I check for cntclk = 7. It still looks like in my second screenshot above. Does this happen because the vector tmp also has a length of 8 or is this rather coincidence? \$\endgroup\$ – mik13 Feb 4 at 9:21
  • \$\begingroup\$ Check the value of tmp, if you're always shifting in the same 8 bits, the output doesn't change. \$\endgroup\$ – po.pe Feb 4 at 11:39
0
\$\begingroup\$

You are running into one of the standard HDL 'temporal' problems.

You want to shift the variable (into a shift register) but you are forgetting that, that takes a clock cycle. Thus if you take another clock cycle to use the result you are running into problems as a new bit is arriving again.

The solution is simple (and if you think about it obvious):
If you get to the last clock cycle of your byte, you pass the input bit straight on to the result. Thus you never shift the last bit in the shift register but pass is straight on to the stored output.

I am busy at the moment so have to leave the exact coding to you.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.