1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Fpga

Discussion in 'Microcontrollers' started by AtomSoft, Jul 23, 2011.

  1. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Ok i know im posting alot here but figured out i can implement a internal signal to use instead of the actual pin. This way i can leave it as OUT and not INOUT and also not have to process it:

    Code (text):

    entity BlinkLed is
        Port ( LED_01 : out  STD_LOGIC;
               OSC_IN : in  STD_LOGIC;
                  RESET : in STD_LOGIC);     
    end BlinkLed;

    architecture Behavioral of BlinkLed is
        signal state : std_logic;
    begin
       
        process(OSC_IN, RESET) is begin
       
        if(RESET = '1') then
          state <= '0';
        elsif(rising_edge(OSC_IN)) then
          state <= not state;
        end if;
           
        end process;
       
        LED_01 <= state;

    end Behavioral;
     
    [​IMG]

    Im sure i can also use BIT instead of STD_LOGIC but heh its ok i assume
     

    Attached Files:

    • sim.jpg
      sim.jpg
      File size:
      23.8 KB
      Views:
      214
    Last edited: Aug 1, 2011
  2. BrownOut

    BrownOut Banned

    Joined:
    Jun 10, 2009
    Messages:
    4,630
    Likes:
    60
    Location:
    Huntsville, Alabama USA
    Good job! ( had you coded in verilog, it would have worked fine as an output )


    You can, but "bit" is generally used in non-synthisized code. For synthesis, stick with STD_LOGIC.
     
    Last edited: Aug 1, 2011
    • Like Like x 1
  3. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Ah ok heh..
    Ok cool, ill stick with the STD_LOGIC stuff... Thanks again! was very helpful
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US

    Hey BrownOut can you check this out... I would simulate but tired heh.. i just tried to guess how this would work. Messing around and trying to make a 32bit shift register.

    Pins:
    sin : Serial In
    lat : Latch Pin
    clk : Clock Pin
    rst : Reset (clears pins and counter)

    Code (text):

    entity shift32 is
        Port ( sin : in  STD_LOGIC;
               lat : in  STD_LOGIC;
               clk : in  STD_LOGIC;
               rst : in  STD_LOGIC;
               db : out  STD_LOGIC_VECTOR (31 downto 0));
    end shift32;

    architecture Behavioral of shift32 is

        signal tempReg : STD_LOGIC_VECTOR (31 downto 0);
        shared variable cnt : integer; 
       
    begin

    process (clk,lat,rst,sin,tempReg)

    begin

        if(rst = '1') then
          for i in 0 to 31 loop
                tempReg(i) <= '0';
         end loop;
         
          cnt := 0;
        elsif(rising_edge(clk)) then
       
            if(sin='1') then
                tempReg(cnt) <= '1';
            else
                tempReg(cnt) <= '0';
            end if;  
           
            cnt := cnt + 1;
           
            if(cnt = 32) then
                cnt := 0;
            end if;

            if(lat = '1') then
                db <= tempReg;
            end if;    
           
        end if;
       
    end process;

    end Behavioral;
     
     
  6. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Let me explain what how it should work.. There are 4 signals in and 32 out. There is no serial out , not needed.

    LAT = send the data in the register the DB pins.
    CLK = clocks the data into the register.
    SER = serial data in
    RST = Clears the register but wont clear the output unless the LAT is enabled

    Internal signals:
    TempReg = 32bit shift register data
    cnt = current bit we are on, can be 0 to 31

    So you clock data in on the rising edge of the ser pin and when cnt reaches 32 its cleared to 0 to start over. You can enable the LAT and see the values for each clock or enable lat when 32 bits are clocked in and change the whole output in 1 shot.

    Not sure how good this code is since i made it but seems like it would work
     
  7. BrownOut

    BrownOut Banned

    Joined:
    Jun 10, 2009
    Messages:
    4,630
    Likes:
    60
    Location:
    Huntsville, Alabama USA
    A couple things:

    The process is a clocked process, so the only signals in the sensitivity list should be clock and reset.
    You don't have to use if/else to assign the sin values to the shift register. Just use "tempReg(cnt) <= sin;
    You dont need a loop to initialize the tempReg. You can just do this: "tempReg <= (others => '0');
    If you make cnt a 5 bit STD_LOGIC_VECTOR, it will roll over by itself.

    Otherwise, good job!
     
  8. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Thanks wow....

    tempReg(cnt) <= sin; -- This makes perfect sense, im not sure why i didnt do it...
    tempReg <= (others => '0'); -- I saw that somewhere but didnt know how to use it... thanks a ton

    If you make cnt a 5 bit STD_LOGIC_VECTOR,it will roll over by itself. -- Awesome idea! But how would i ? Do i make it a signal ? or can i do that with variables... im still waiting on a certain book to arrive to read
     
  9. BrownOut

    BrownOut Banned

    Joined:
    Jun 10, 2009
    Messages:
    4,630
    Likes:
    60
    Location:
    Huntsville, Alabama USA
    signal cnt : STD_LOGIC_VECTOR(5 downto 0)

    You'll need this in your design file:

    --- Library Files ---
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    The last two libraries include packages that allow you to do the addition on STD_LOGIC_VECTORS.
     
    Last edited: Aug 3, 2011
  10. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    SO you meant 6 bits :D

    Also :

    Code (text):

    ERROR:HDLParsers:821 - "C:/XWD/Shift32/shift32.vhd" Line 58. Wrong index type for tempReg.
    --.. on code
    tempReg(cnt) <= sin;       
     
     
  11. BrownOut

    BrownOut Banned

    Joined:
    Jun 10, 2009
    Messages:
    4,630
    Likes:
    60
    Location:
    Huntsville, Alabama USA
    Correct

    OH right, I guess cnt does have to be an integer. For counters other than indices, you can use STD_LOGIC_VECTOR and the libraries. BTW, here is how I do my shift registers:


    Code (text):
       signal shifter    : STD_LOGIC_VECTOR(MAX_LED-1 downto 0);
       ...
             if(clk_cnter(CNT_MAX) = '1' and clk_cntr_d = '0') then
                if(dir = '0') then
                 shifter <= '0' & shifter(MAX_LED-1 downto 1);  -- right shift
                else
                 shifter <= shifter(MAX_LED-2 downto 0) & '0';  -- left shift
                end if;  
    etc...
     
    Last edited: Aug 3, 2011
  12. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    heh no problem, thanks again
     
  13. BrownOut

    BrownOut Banned

    Joined:
    Jun 10, 2009
    Messages:
    4,630
    Likes:
    60
    Location:
    Huntsville, Alabama USA
    I added some code to my last message while you were replying. Take a look at it.
     
  14. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Ah i see cool, Direction was a nice addition. Im lazy so i usually try make one piece of code so changing which way it shifts in doesnt affect me. I plan to test this out with a PIC as soon as i get my board
     
  15. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    My FPGA board should be here by friday the latest... had some bill issues heh... anyway i think im understanding FPGAs more and more everyday.

    BrownOut since you seem to be the most experienced in this field here... i am going to make a small (very small) LED Blink example with the ability to change blink rates... can you simply go over the code and comment on good/bad parts?
     
  16. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Well this doesnt synthesize but looks fine to me...
    I get a error:
    Code (text):

    INTERNAL_ERROR:Xst:cmain.c:3464:1.56 -  Process will terminate. For technical support on this issue, please open a WebCase with this project attached at http://www.xilinx.com/support.  

     
    Code (text):

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    -----------------------------------------------------

    entity BlinkRate is
    port(   myButton:   in std_logic;
           myClock:     in std_logic;
           myReset:     in std_logic;
           myLED:       out std_logic
    );
    end BlinkRate;

    -----------------------------------------------------

    architecture myFSM of BlinkRate is
        -- states of myFSM
         signal myLEDState : STD_LOGIC;
        type state_type is (S0, S1, S2, S3);
        signal next_state, current_state: state_type;
         shared variable myRate: integer;
         shared variable myCount: integer;   -- shared variable cnt : integer;

    begin
       
        -- cocurrent process#1: state registers
        state_reg: process(myClock, myReset)
        begin

        if (myReset='1') then
                    myLEDState <= '0';
                    myRate := 32000000;
                    myCount := 0;
                current_state <= S0;
        elsif (myClock'event and myClock='1') then
            current_state <= next_state;
             if(myCount=myRate) then
                myLEDState <= not myLEDState;
                myCount := 0;
            else
                myCount :=myCount + 1;
            end if;
        end if;
        myLED <= myLEDState;
       end process;                      

        -- cocurrent process#2: combinational logic
        comb_logic: process(current_state, myButton)
        begin

        case current_state is

            when S0 =>
                if myButton='0' then
                    next_state <= S0;
                else
                     myRate := 16000000;
                    next_state <= S1;
                end if;

            when S1 => 
                if myButton='0' then
                    next_state <= S1;
                else
                     myRate := 8000000;
                    next_state <= S2;
                end if;

            when S2 => 
                if myButton='0' then
                    next_state <= S2;
                else
                     myRate := 4000000;
                    next_state <= S3;
                end if;

            when S3 =>
                if myButton='0' then
                    next_state <= S3;
                else
                     myRate := 32000000;
                    next_state <= S0;
                end if;

            when others =>
               myRate := 32000000;
                next_state <= S0;

        end case;

       end process;

    end myFSM;
     
    What should happen here is when it first start the initial rate is 32000000 which is the 32mhz on board so its like a 1 second blink. Then when you press the button it cuts the time in half.. 500ms blink then when you press it cuts in 1/2 again 250ms then when you press it cuts in half again... 125ms... now if you press 1 more time it goes back to 1 seconds blink...

    Well thats the theory... as you can see it doesnt (COMPILE)(SYNTHESIZE) i like compile word better
     
    Last edited: Aug 8, 2011
  17. BrownOut

    BrownOut Banned

    Joined:
    Jun 10, 2009
    Messages:
    4,630
    Likes:
    60
    Location:
    Huntsville, Alabama USA
    You have the signal "my_rate" assigned in two different processes. You don't need to reset it to zero in the clock/reset process, because you reset "current_state" to s0, where you can then assign "my_rate" to the initial value. However, in the process "comb_logic" you have states/inputs where "my_rate" is not assigned. YOu should either create a signal called "next_my_rate" and assign "my_rate" in the clock process, or else just make sure that "my_rate" is assigned under every condition in comb_logic. Also, be careful assigning huge numbers to integers. If your software defines integers as 16-bit, it won't hold your 32M number. Instead, figure out how many bits it takes to hold such a number, and use a vector to assign it. ie.

    2^n=32MEG => n=log(2)32MEG/n therefore, n=25. Conversly, you can just create a 25-bit counter and pick off sucessively lower bits ( starting w/MSB ) for your blink rate, ie,

    Code (text):
    signal counter : STD_LOGIC_VECTOR(24 downto 0)

    ....


    case current_state
    ...

    when s0 -> LED_STATE <= counter(24)

    ...

    when s1 -> LED_STATE <= counter(23)

    etc.
    Looks like you're on the right track. I like the way you're using the pushbutton to change the blink rate.
     
    Last edited: Aug 8, 2011
  18. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Thanks a ton, im still a bit confused tho... sorry... just noticed your update... thanks.. the thing is im using the RATE in the clock so it counts to the rate. If i send the counter to LED State nothing will happen really

    signal counter : STD_LOGIC_VECTOR[24 downto 0]

    how would i set the entire signal value ?

    do i simply... counter <= 30842; or something

    i think im tired and will tackle this tomorrow.. if i said something stupid here omit that :D im just very sleepy :(
     
  19. BrownOut

    BrownOut Banned

    Joined:
    Jun 10, 2009
    Messages:
    4,630
    Likes:
    60
    Location:
    Huntsville, Alabama USA
    You don't. Look at my example, I only send a single bit of the counter:

    Code (text):
    when s0 -> LED_STATE <= counter(24)
    The parenthesis around the "24" means assign bit 24 of the counter.

    Good idea, heh!
     
  20. BrownOut

    BrownOut Banned

    Joined:
    Jun 10, 2009
    Messages:
    4,630
    Likes:
    60
    Location:
    Huntsville, Alabama USA
    There is yet another way, you can do this:

    LED_STATE <= counter = "XYZ". Although this abstracts the resultant logic, I don't often use this style.
     
  21. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    i have to admit. Im still lost but that just means i need to read up more :D Ill figure it out... oh yeah i was thinking of this also.. since i changed myRate to a STD_LOGIC_VECTOR(24 downto 0) can i set it like:
    Code (text):

    myRate <= "1111010000100100000000000";
     
    ? is that a safe thing?
     
    Last edited: Aug 9, 2011

Share This Page