Shift Register Problem

Discussion in 'VHDL' started by Indroneel Ganguly, May 5, 2006.

  1. Hello Group,

    I am new to VHDL and would appreciate any pointers, or suggestions in this
    problem.
    I am trying to modify a shift register, when the LOAD pin is active(active
    low signal)
    , I load values into the shifter register's internal register with levels on
    the Pins
    and constant. So that on LOAD the shift register contains some input pin
    values and
    a internal string.

    However when I try to do this (loading Pins and internal register) the pins
    get loaded
    as zeros.

    The shift register works fine when I am using only pins or only internally
    stored values.

    Below is the code with the working variants commented out. It also contains
    an output shift
    register connected to the input shift register.
    Hello,

    I am new to VHDL and would appreciate any pointers, or suggestions in this
    problem.
    I am trying to modify a shift register, when the LOAD pin is active(active
    low signal)
    , I load values into the shifter register's internal register with levels on
    the Pins
    and constant. So that on LOAD the shift register contains some input pin
    values and
    a internal string.

    However when I try to do this (loading Pins and internal register) the pins
    get loaded
    as zeros.

    The shift register works fine when I am using only pins or only internally
    stored values.


    INP_BYTEx are input pins
    DI2,DI1 are data out from the input and output of the shift registers
    INPUT_SIZE = Size of shift register in bits -1
    OUTPUT_SIZE = Size of shift register in bits -1
    The CLK is not a periodic clock it is starts with a delay after LOAD.

    Below is the code with the working variants commented out. It also contains
    an output shift
    register connected to the input shift register.

    IF (LOAD_AL='0') THEN
    internal_input(INPUT_SIZE DOWNTO 0) <= INP_BYTE0 & "11110101" &
    INP_BYTE2 ; -- this doesnt work

    -- These below work
    -- internal_input(INPUT_SIZE DOWNTO 0) <= INP_BYTE0 & INP_BYTE1 &
    INP_BYTE2;
    -- internal_input(INPUT_SIZE DOWNTO 0) <= "11110101" & "11111111" &
    "00000000";

    ELSIF Rising_Edge(CLK) THEN
    internal_output <= internal_output(OUTPUT_SIZE-1 DOWNTO 0) & SSC_DO;
    internal_input <= internal_input(INPUT_SIZE-1 DOWNTO 0) &
    internal_output(OUTPUT_SIZE);
    END IF;
    DI2 <= internal_input(INPUT_SIZE);
    DI1 <= internal_output(OUTPUT_SIZE);

    I would be very grateful for any suggestions or pointers as to what I am
    overlooking.
    My hunch is that a register is used and this is initialized to zero because
    the INP_BYTEx and string are not available at the same time.
    Is that correct, and how do I work around it.

    Thanks in advance.
    Indroneel
     
    Indroneel Ganguly, May 5, 2006
    #1
    1. Advertising

  2. Indroneel Ganguly wrote:


    > However when I try to do this (loading Pins and internal register) the pins
    > get loaded
    > as zeros.


    > IF (LOAD_AL='0') THEN
    > internal_input(INPUT_SIZE DOWNTO 0) <= INP_BYTE0 & "11110101" &
    > INP_BYTE2 ; -- this doesnt work

    ....
    > ELSIF Rising_Edge(CLK) THEN

    ....
    > END IF;

    ....

    Do you have INP_BYTE0 and INP_BYTE2 in your sensitivity list of this
    process?

    process(LOAD_AL,INP_BYTE0,INP_BYTE2,CLK)
    ....

    Ralf
     
    Ralf Hildebrandt, May 5, 2006
    #2
    1. Advertising

  3. Thanks for you reply Ralf.
    No I dont have them on the sensitivity list, the synthesis tool issues a
    warning and tells 'assuming
    completeness', I will try to make the change and test it on the hardware
    tomorrow.

    But why are they necessary on the sensitivity list ?
    I placed only CLK and LOAD on the sensitivity list because I wanted the
    process to repeat only
    when the CLK and LOAD signals change.

    Kind regards,
    Indroneel
    "Ralf Hildebrandt" <> wrote in message
    news:...
    > Indroneel Ganguly wrote:
    >
    >
    >> However when I try to do this (loading Pins and internal register) the
    >> pins get loaded
    >> as zeros.

    >
    >> IF (LOAD_AL='0') THEN
    >> internal_input(INPUT_SIZE DOWNTO 0) <= INP_BYTE0 & "11110101" &
    >> INP_BYTE2 ; -- this doesnt work

    > ...
    >> ELSIF Rising_Edge(CLK) THEN

    > ...
    >> END IF;

    > ...
    >
    > Do you have INP_BYTE0 and INP_BYTE2 in your sensitivity list of this
    > process?
    >
    > process(LOAD_AL,INP_BYTE0,INP_BYTE2,CLK)
    > ...
    >
    > Ralf
     
    Indroneel Ganguly, May 5, 2006
    #3
  4. Indroneel Ganguly wrote:


    > No I dont have them on the sensitivity list, the synthesis tool issues a
    > warning and tells 'assuming
    > completeness', I will try to make the change and test it on the hardware
    > tomorrow.
    >
    > But why are they necessary on the sensitivity list ?


    If LOAD_AL='0' and INP_BYTE0 or INP_BYTE2 change the value the process
    is not triggered again if they are not in the sensitivity list.

    For synthesis the sensitivity list is "ignored" and "automatically
    completed". Therefore the synthesis tool gives you a warining that the
    synthesized circuit will act equal to the process with the full
    sensitivity list - which may be a different behavior to the simulation
    where the sensitivity list is not complete. -> Short: Simulation and
    synthesis may differ.

    => Make the sensitivity list complete and simulate your design. Maybe
    then you can see why your circuit acts not as intended.

    Ralf
     
    Ralf Hildebrandt, May 5, 2006
    #4
  5. Indroneel Ganguly

    Guest

    Actually Ralf already gave the answer, but here is another try:

    If you put only CLK and LOAD in your sensitivity list, assume the
    following input:

    CLK
    ________--------_________---------_________---------_________---------
    LOAD
    -------------------------__________________________________________
    INP_BYTE0 X"AA" | X"BB"

    Now what should happen when INP_BYTE0 changes to X"BB" ?
    If you only put LOAD into the sensitivity list of your process, then
    "internal_input" would have to hold its value of X"AA", because
    your process isn't sensitive to changes in INP_BYTE0.

    So if you want to synthesis this kind of construction you would need
    a kind of double clocked register (a register which reacts on the
    rising
    edge of CLK and on the falling edge of LOAD).
    Usually the synthesis will do something different, because it ususally
    doesn't know how to produce double clocked registers...

    so long
    lundril
     
    , May 6, 2006
    #5
  6. Ralf and Lundril , thank you both for your inputs.
    I tried out the shift register with the sensitivity list changed, I included
    the INP_BYTEx into the
    list. It still doesnt work.
    Even added internal_input to the sensitivity list, that doesnt help either.

    Let me try to explain what I cant understand.
    when I load the values to the shift register directly from the pins it
    works. that is if I have the following code:
    (having only CLK and LOAD on the sensitvity list) .

    internal_input(INPUT_SIZE DOWNTO 0) <= INP_BYTE0 & INP_BYTE1 & INP_BYTE2;

    The shift register also works when I load a constant into it (again with
    only CLK and LOAD) on the sensitivity list
    like this:
    internal_input(INPUT_SIZE DOWNTO 0) <= X"AA"&X"BB"&X"CC";

    Now when I change either of the lines above to a mixed combination like
    this:
    internal_input(INPUT_SIZE DOWNTO 0) <= INP_BYTE0&X"BB"&X"CC";

    The shift register doesnt work any more. This is what puzzles me, why doesnt
    it work for such combination of internal_input.

    I hope you understand where I am getting stuck.

    Regards,
    Indroneel


    <> wrote in message
    news:...
    > Actually Ralf already gave the answer, but here is another try:
    >
    > If you put only CLK and LOAD in your sensitivity list, assume the
    > following input:
    >
    > CLK
    > ________--------_________---------_________---------_________---------
    > LOAD
    > -------------------------__________________________________________
    > INP_BYTE0 X"AA" | X"BB"
    >
    > Now what should happen when INP_BYTE0 changes to X"BB" ?
    > If you only put LOAD into the sensitivity list of your process, then
    > "internal_input" would have to hold its value of X"AA", because
    > your process isn't sensitive to changes in INP_BYTE0.
    >
    > So if you want to synthesis this kind of construction you would need
    > a kind of double clocked register (a register which reacts on the
    > rising
    > edge of CLK and on the falling edge of LOAD).
    > Usually the synthesis will do something different, because it ususally
    > doesn't know how to produce double clocked registers...
    >
    > so long
    > lundril
    >
     
    Indroneel Ganguly, May 6, 2006
    #6
  7. Indroneel Ganguly

    Jeremy Ralph Guest

    First, I agree with Ralf and the others that you need to have
    LOAD_AL,INP_BYTE0,INP_BYTE2,CLK in your sensitivity list or your
    synthesis and simulation won't work the same.

    >I placed only CLK and LOAD on the sensitivity list because I wanted the
    >process to repeat only
    >when the CLK and LOAD signals change


    As the others already mentioned sensitivity lists are *not* used for by
    synthesis. As a rule of thumb -- to simulate VHDL as it would work
    after synthesis -- you should put all signals that are not sampled (by
    clk) and appear in an if statement or appear on the RHS of a signal
    statement. In this situation that is the LOAD_AL, INP_BYTE0 and
    INP_BYTE1.

    If you make the entire circuit synchronous this might make things
    simpler. Try this:

    some_proc: PROCESS(clk)
    BEGIN

    IF (clk'EVENT AND clk='1') THEN
    IF (load_al='0') THEN
    internal_input(INPUT_SIZE DOWNTO 0) <= INP_BYTE0 & "11110101" &
    INP_BYTE2 ;
    END IF;
    internal_output <= internal_output(OUTPUT_SIZE-1 DOWNTO 0) & SSC_DO;
    internal_input <= internal_input(INPUT_SIZE-1 DOWNTO 0) &
    internal_output(OUTPUT_SIZE);
    END IF;
    END PROCESS some_proc;

    DI2 <= internal_input(INPUT_SIZE);
    DI1 <= internal_output(OUTPUT_SIZE);

    This way everything will be sampled on a clock edge. Of course the
    outputs will be garbage until after you do your first load. You might
    want to include a reset signal of some sort. Also, if your inputs
    aren't synchronized to the clk, then you should synchronize them...
    googleing on the topic should reveal some hints on how to synchronize
    signals. I'd think putting load_al through two serially connected
    flops should take care of synchronization for this situation.

    Hope this helps.
    Jeremy


    ---
    PDTi [ http://www.productive-eda.com ]
    SpectaReg -- Spec-down code and doc generation for memory mapped
    registers
     
    Jeremy Ralph, May 6, 2006
    #7
  8. Indroneel Ganguly

    Jeremy Ralph Guest

    Ooops, problem in my above code. Don't think load_al would work... I
    think this might be better...

    IF (clk'EVENT AND clk='1') THEN
    IF (load_al='0') THEN
    internal_input(INPUT_SIZE DOWNTO 0) <= INP_BYTE0 & "11110101" &
    INP_BYTE2 ;
    ELSE
    internal_input <= internal_input(INPUT_SIZE-1 DOWNTO 0) &
    internal_output(OUTPUT_SIZE);
    END IF;

    internal_output <= internal_output(OUTPUT_SIZE-1 DOWNTO 0) & SSC_DO;
    END IF;
    END PROCESS some_proc;
     
    Jeremy Ralph, May 6, 2006
    #8
  9. Indroneel Ganguly wrote:


    > Let me try to explain what I cant understand.
    > when I load the values to the shift register directly from the pins it
    > works.


    Did you simulate your code before synthesis? Build a testbench, that
    acts like the real world (the pins).

    Is your load-signal hazard-free? (It is an asynchronous load and
    therefore it must be hazard-free.)

    Ralf
     
    Ralf Hildebrandt, May 9, 2006
    #9
  10. Thank you Ralf, Lundril and Jeremy for your help.
    It was really kind of you guys to take your time and explain things to me.

    Am wrapping up my side of the results.

    I did simulate the design using test benches, I needed 2 to simulate a start
    up condition and a normal operation.
    The load signals are asynchronous (not exactly), the clock's starts with a
    fixed delay after load and stops just before
    the load comes. Also the clock is periodic for 8 ticks, then a longer gap
    and so on.
    It comes out of a uC !

    Anyways the problem was apparently not in the code or simulation but in the
    synthesis tool, I changed it and it works
    fine. Even with a only clk and load on the sensitivity list, I had
    restricted the sensitivity list because the other signals shouldnt
    trigger the process again, in any case the time saving for the simulation in
    the code would have not mattered.(Model Tech advice)

    So am differing with the advise on extending the sensitivity list, but I
    will keep it in mind just in case all else fails.

    Now perhaps I just might get my Master's -:)

    Regards,
    Indroneel
     
    Indroneel Ganguly, May 11, 2006
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roberto Gallo

    Shift - byte[] buf shift

    Roberto Gallo, Jan 27, 2004, in forum: Java
    Replies:
    3
    Views:
    2,070
    Thomas Schodt
    Jan 27, 2004
  2. Wenjie
    Replies:
    3
    Views:
    1,039
    Ron Samuel Klatchko
    Jul 11, 2003
  3. Replies:
    6
    Views:
    2,211
    Dave Higton
    Jun 30, 2006
  4. Replies:
    16
    Views:
    1,091
    Mike Treseler
    Oct 20, 2006
  5. Santosh Nayak

    Left Shift / Right Shift Operators

    Santosh Nayak, Nov 30, 2006, in forum: C Programming
    Replies:
    16
    Views:
    1,455
    CBFalconer
    Nov 30, 2006
Loading...

Share This Page