-1
\$\begingroup\$

I am a beginner in VHDL/FPGA and trying to understand the results of a simulation:

Example:

Let say, there is an input vector 001001010001. I can shift this vector by using the following expression:

shift_data <= data_in & shift_data( 0 to ( N- 2));

How should a result for this vector look like? Could someone explain me?

EDIT 1:

Port
        (
data_in:     in std_logic_vector( 11 downto 0);
...
);

---

type shift_array is array (integer range 0 to 19)  of std_logic_vector ( 11 downto 0);
signal shift_data : shift_array   := (others => (others => '0')); 
...
main_process : process(Clk)
begin       
if rising_edge(Clk)  then
  if Rst = '1' then 
     data_out <=(others => '0');
   elsif Enb = '1' then
          shift_data    <=  data_in & shift_data( 0 to 18); 
   
   end if;
data_out <=  shift_data(19 to 0);      --??
end if; 
end process main_process;

I have checked it with test bench and gotten 0. Where have I mistaken?

\$\endgroup\$
4
  • \$\begingroup\$ Is VHDL/FPGA a software? where are you simulating? \$\endgroup\$ Commented Apr 27, 2021 at 12:18
  • \$\begingroup\$ The answer depends on the declaration of the vector, which you haven't shown. \$\endgroup\$
    – user16324
    Commented Apr 27, 2021 at 14:29
  • \$\begingroup\$ Why do you start to use arrays now? Does it have to be 2 dimensional? It's not clear what you actually try to shift. There are several parts in your code that don't make sense \$\endgroup\$
    – po.pe
    Commented Apr 28, 2021 at 8:59
  • \$\begingroup\$ @po.pe I implement a filter and shift -operation is a part of it. I would like to check the simulation step by step and check how the shifted data looks like. Arrays, I think it is the best option for me, later I need this array for product with filter coefficients \$\endgroup\$
    – Jang Lee
    Commented Apr 28, 2021 at 9:18

2 Answers 2

1
\$\begingroup\$

In addition to the previous answer, here is a corresponding schematic representation of a shifter to the right, which may further help in understanding. I assume that the code is in a clocked process.

left shift register

The trick here is to note a range (bit order), which is set by using to keyword instead of a usual downto (reference).

to corresponds to big endian. So in L to R, L is the LSB and R the MSB.

Concatenation & works like this (reference):

A & B yields a vector whose length is the length of A + the length of B, with the content of A on the left and B on the right.

The bit order applies both to an array in the left part and concatenation. This results in the expression being equivalent to the following:

    shift_data(0 to (N-1)) <= data_in & shift_data(0 to (N-2));

which is equivalent to:

    shift_data(0) <= data_in;
    shift_data(1) <= shift_data(0);
    ...
    shift_data(N-1) <= shift_data(N-2);

The shift (with both possible directions, for a 4-bit wide register) can be seen in the following simulation results.

shift register simulation results

The corresponding testbench code:

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY shift_test IS
    GENERIC (N: integer := 4);
END shift_test;

ARCHITECTURE tb OF shift_test IS
    SIGNAL clk : STD_LOGIC;
    SIGNAL data_in : STD_LOGIC; 
    SIGNAL shift_data_r, shift_data_l: STD_LOGIC_VECTOR (0 to N-1) := (others => '0'); 
BEGIN

PROCESS 
BEGIN
    clk <= '0';
    wait for 100 ns;
    clk <= '1';
    wait for 100 ns;
END PROCESS;

PROCESS 
BEGIN
    data_in <= '0';
    wait for 350 ns;
    data_in <= '1';
    wait for 500 ns;
    data_in <= '0';
    wait for 300 ns;
    data_in <= '1';
    wait for 500 ns;
END PROCESS; 

PROCESS (clk)                      
BEGIN
    IF clk'EVENT AND clk = '1' THEN
        shift_data_r <= data_in & shift_data_r(0 to (N-2));
        shift_data_l <= shift_data_l(1 to (N-1)) & data_in;
    END IF;
END PROCESS; 
    
END tb;
\$\endgroup\$
4
  • \$\begingroup\$ Could you please check my realisation ( EDIT in the question)? \$\endgroup\$
    – Jang Lee
    Commented Apr 28, 2021 at 8:39
  • 1
    \$\begingroup\$ @JangLee There are errors in your code, which prevent successful compilation, but when fixed and with proper control your listed shift register works fine for me. You really should be careful when asking for help with the code, which doesn't compile. Besides, finding errors seems to be outside of the scope of the question (and SE is all about answers for particular questions). Anyway, errors to look for: Clk vs MainClk - you will want to use only one of them, elsif instead of elseif, ; after end loop, data_out <=(others => '0'); instead of data_out <='0'. \$\endgroup\$
    – megasplash
    Commented Apr 28, 2021 at 9:04
  • \$\begingroup\$ i am sorry it was a part of the code I am working on, I have mistaken when I copied it. My big problem is how to sent an array to output, is it possible? \$\endgroup\$
    – Jang Lee
    Commented Apr 28, 2021 at 9:22
  • 1
    \$\begingroup\$ @JangLee Again, it seems to be outside the scope of the question. To get a proper answer you should ask a new question, or you can probably find an existing relevant answer. However, here is a short answer: to get all array values at an output you will have to create a very wide output, which is quite impractical. You have two reasonable options: 1) leave it as it is now, as a shift out value with one vector at a time, and use this sequence of vectors in another module, or 2) implement whatever processing you want in this module, without the need to send it anywhere. \$\endgroup\$
    – megasplash
    Commented Apr 28, 2021 at 9:27
1
\$\begingroup\$

shift_data <= data_in & shift_data(0 to N-2) assuming N represents the size of shift_data will take in data_in as the new MSB and add bit0 to bitN-2 of the original vector. The LSB will be discarded. So with the given input vector 001001010001 and data_in = 1 the new resulting vector will be 100100101000.

I don't know if this is just personal preference, but I find it way more intuitive to work with the downto keyword instead of to.

Update
Reading the comments I have to add that I assumed that you declared the shift_data vector as

signal shift_data : std_logic_vector(0 to N-1);

If you use the downto keyword in your declaration, the answer is incorrect.

\$\endgroup\$
5
  • \$\begingroup\$ If declaration had different range, OP wouldn't get to simulation. I think your assumption is fully reasonable that the declaration uses to keyword and the vector is N bits wide. \$\endgroup\$
    – megasplash
    Commented Apr 28, 2021 at 8:36
  • \$\begingroup\$ Could you please check my realisation ( EDIT in the question)? \$\endgroup\$
    – Jang Lee
    Commented Apr 28, 2021 at 8:40
  • \$\begingroup\$ update: did you mean I have to write type shift_array is array (integer range 0 to 19) of std_logic_vector ( 0 to 11); ? Is it important , downto or to? \$\endgroup\$
    – Jang Lee
    Commented May 6, 2021 at 6:56
  • \$\begingroup\$ The to/downto keyword defines the bitordering of your std_logic_vector, so depending on what you're doing with it, it is important. \$\endgroup\$
    – po.pe
    Commented May 6, 2021 at 7:08
  • \$\begingroup\$ if i need to shift an integer type of data, can I do it without a conversion into logic vector? \$\endgroup\$
    – Jang Lee
    Commented May 7, 2021 at 12:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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