1
\$\begingroup\$

I have been trying to design a simple Hardware design to controll another board that powers a set of LEDs for a stage drum lighting system. I cannot for the life of me figure out why I am recieving these warnings

In short what I am trying to do here is create a design that switches the lights color each time the Base drum (BaseBeat) is hit, with a maximum transition time of 1 light change a second (I am using a 50Mhz clock so I used a counter qtemp to count up and then reset after the BaseBeat is pressed) I have tested both the TB and the design on my Spartan3e but nothing happens (when I remove anything to do with the clock and the one second transition limit it works).

Also so far I have taken one course on VHDL and FPGA design, I will be taking more this spring, but I hope to have this working so I can set up the light system earlier.

these are the warnings

WARNING:Xst:646 - Signal  is assigned but never used. This unconnected signal will be trimmed during the optimization process.
WARNING:PhysDesignRules:367 - The signal  is incomplete. The signal
 does not drive any load pins in the design.
WARNING:Par:288 - The signal clk_IBUF has no load. PAR will not attempt to route this signal.
WARNING:Par:283 - There are 1 loadless signals in this design. This design will cause Bitgen to issue DRC warnings.

(the next_color warning does not seem to be my major problem, although I could be wrong)

Here is my code:

entity LEDcontroller is
port(   BaseBeat: in STD_LOGIC;
        output,ON_BOARD_LED_output: out STD_LOGIC_VECTOR(2 downto 0);
        color_scheme: in STD_LOGIC_VECTOR(1 downto 0); 
        ON_BOARD_LED_color_scheme: out STD_LOGIC_VECTOR(1 downto 0); 
        ON_BOARD_LED_BaseBeat: out STD_LOGIC;
        ON_BOARD_LED_ONEsec_flag: out STD_LOGIC;
         clk : in STD_LOGIC);
end LEDcontroller;

architecture controller_behavior of LEDcontroller is
type color_type is (RED, YELLOW, GREEN, TURQOISE, BLUE, PINK, WHITE, OFF); 
signal current_color: color_type := OFF;
signal next_color: color_type := OFF;   
signal outputTEMP: STD_LOGIC_VECTOR(2 downto 0);        -- default is off 
signal qtemp: STD_LOGIC_VECTOR(24 downto 0);
signal ONEsec_flag: STD_LOGIC;

begin
    process(clk)
        begin
            if (clk'event and clk='1') then
                    qtemp <= qtemp + 1;
                 end if;
    end process;

    sequence: process(current_color,color_scheme)
        begin
            if (color_scheme = "00") then
                case current_color is
                        when RED => next_color <= GREEN;

                        when GREEN => next_color <= BLUE;

                        when BLUE => next_color <= RED;

                        when OTHERS => next_color <= RED;
                end case;           
            elsif (color_scheme = "01") then
                case current_color is
                        when RED => next_color <= YELLOW;

                        when YELLOW => next_color <= GREEN;

                        when GREEN => next_color <= TURQOISE;

                        when TURQOISE => next_color <= BLUE;

                        when BLUE => next_color <= PINK;

                        when PINK => next_color <= RED;

                        when OTHERS => next_color <= RED;
                    end case;
             elsif (color_scheme = "10") then
                case current_color is
                        when RED => next_color <= PINK;

                        when PINK => next_color <= BLUE;

                        when BLUE => next_color <= TURQOISE;

                        when TURQOISE => next_color <= GREEN;

                        when GREEN => next_color <= YELLOW;

                        when YELLOW => next_color <= RED;

                        when OTHERS => next_color <= RED;
                    end case;
                else
                case current_color is
                        when RED => next_color <= BLUE;

                        when BLUE => next_color <= GREEN;

                        when GREEN => next_color <= WHITE;

                        when WHITE => next_color <= RED;

                        when OTHERS => next_color <= RED;
                    end case;
                end if;
            end process;

    transition: process(BaseBeat,qtemp)
        begin
                    if (qtemp = "10111110101111000010000000") then
                        ONEsec_flag <= '1';
                    end if;
                    if (BaseBeat'event and BaseBeat = '1') and (ONEsec_flag='1') then 
                        current_color <= next_color;
                        ONEsec_flag <= '0';
                    else 
                        current_color <= current_color;
                    end if;
                end process;

    control: process(current_color)
        begin
                case current_color is 
                    -- main colors
                    when RED => outputTEMP <= "110"; 
                    when GREEN => outputTEMP <= "101";
                    when BLUE => outputTEMP <= "011";
                    --extended colors
                    when YELLOW => outputTEMP <= "100";
                    when TURQOISE => outputTEMP <= "001";
                    when PINK => outputTEMP <= "010";
                    --all or nothing
                    when WHITE => outputTEMP <= "000";
                    when OTHERS => outputTEMP <= "111";
                end case;
        end process;    

        --components
        --main outputs
        output <= outputTEMP;
        -- on board led outputs
        ON_BOARD_LED_output <= outputTEMP;
        ON_BOARD_LED_color_scheme <= color_scheme;
        ON_BOARD_LED_BaseBeat <= BaseBeat;  
        ON_BOARD_LED_ONEsec_flag<=ONEsec_flag;
end controller_behavior;

and my UCF:

# Clocks
NET "clk" LOC = " B8 " ;#Bank = 0, Signal name = MCLK


# Pin assignment for LEDs
NET "ON_BOARD_LED_output" LOC = "G1" ; # Bank = 3, Signal name = LD7
NET "ON_BOARD_LED_output" LOC = "P4" ; # Bank = 2, Signal name = LD6
NET "ON_BOARD_LED_output" LOC = "N4" ;  # Bank = 2, Signal name = LD5

NET "ON_BOARD_LED_BaseBeat" LOC = "P6" ; # Bank = 2, Signal name = LD3

NET "ON_BOARD_LED_color_scheme" LOC = "M11" ; # Bank = 2, Signal name = LD1
NET "ON_BOARD_LED_color_scheme" LOC = "M5" ;  # Bank = 2, Signal name = LD0
NET "ON_BOARD_LED_ONEsec_flag" LOC = "P7" ;  # Bank = 2, Signal name = LD5

NET "color_scheme" LOC = "L3";  # Bank = 3, Signal name = SW1
NET "color_scheme" LOC = "P11";  # Bank = 2, Signal name = SW0

NET "BaseBeat" LOC = "A7";  # Bank = 1, Signal name = BTN3




# Loop Back only tested signals
#NET "BaseBeat" LOC = "C6"  | DRIVE = 2  | PULLUP ; # Bank = 1, Signal name = JA1
NET "output" LOC = "B6"  | DRIVE = 2  | PULLUP ; # Bank = 1, Signal name = JA2
NET "output" LOC = "C5"  | DRIVE = 2  | PULLUP ; # Bank = 1, Signal name = JA3
NET "output" LOC = "B7"  | DRIVE = 2  | PULLUP ; # Bank = 1, Signal name = JA4
#NET "BaseBeat" CLOCK_DEDICATED_ROUTE = FALSE; 
 

Sorry that this is long, please help me though if you are able to, I have given myself several headaches reading my book and searching the forums all to no avail.
Thanks in advance, Scott

EDIT:

in response to my own comment to @Paebbels' suggestions

@Paebbels I do have a new issue now, even after a second has passed the transition does
not always occur when BaseBeat is pressed. When I hold BaseBeat down for a long time, the 
lights start transiting every second, but when I quickly press them even after a second it
 does not always transition, only some times. Oddly enough, if I press the BaseBeat for say
 1/2 a second it doesn't always transition either? (I thought it may have something to do 
with rising_edg(clk) and BaseBeat not occurring at the same time, but rising_edg(clk) occurs
 25M times in half a second..) Thanks again

I altered the suggested statement:

ONEsec_flag <= '1' when (qtemp = 49999999) else '0';

to be:

process(clk)
            begin
                if rising_edge(clk) then
                    if (qtemp = 49999999) then ONEsec_flag <= '1';
                    elsif (BaseBeat='1') then ONEsec_flag <= '0';
                    else ONEsec_flag <= ONEsec_flag;
                    end if;
                end if;
        end process;

Is this good design practice? it seems to be working now (it transitions after a second regardless of how long or fast I press the BaseBeat) and I think I made it synchronous, at least within my understanding of synchronous.

Thanks for all the help guys, especially you @Paebbels! have a Happy New Year!

\$\endgroup\$
  • \$\begingroup\$ What IDE are you using (xilinx vivado or xilinx legacy ISE?) Also why did you opt for an FPGA rather than a simpler microcontroller for your application? It sounds like you're in over your head \$\endgroup\$ – Funkyguy Dec 31 '14 at 8:39
  • \$\begingroup\$ What is the name of your development board? Please, can you fix your source code in the question? It's a single line after if (clk'event and clk='1') then \$\endgroup\$ – Paebbels Dec 31 '14 at 10:55
  • \$\begingroup\$ @Funkyguy I already have this code working on a microcontroller, but I am interested in porting it to an fpga because this upcoming semester I will be taking 2 courses on fpga design and I am going to be porting my current matlab code for my senior design project to an fpga, so I thought this would be a great little project to do over break to refresh my vhdl knowledge. \$\endgroup\$ – scarlso9 Dec 31 '14 at 19:45
  • \$\begingroup\$ @Paebbels I am using a simple Basys2 board. I am unsure of what you mean by fixing my source code, it looks like what I meant to put? (or am I that lost haha). Thanks guys \$\endgroup\$ – scarlso9 Dec 31 '14 at 19:46
  • \$\begingroup\$ @ScottCarlson David Koontz edited your post, so everyone could read it. There seams to be a bug if user use <pre>...</pre> tags to enclose code lines. I could only see your code up to the line if (clk'event and clk='1') then after that I got only scrambled lines. So not it's fixed and I extended my answer :) \$\endgroup\$ – Paebbels Jan 1 '15 at 3:21
3
\$\begingroup\$

Some hints for and questions to your code:

  • signal nextColor should not have a default value, because it's not mapped to a register
    signal nextColor : color_type;
  • signal qtemp misses a default value: it's a counter/mapped to a register
  • secondly, this signal represents a counter and it's used in arithmetic calculations. So qtemp should be of type (un)signed or integer/natural. Doing artithmetic calculations on std_logic_vector is not a recommended style.
    signal qtemp : unsigned(24 downto 0) := (others => '0');
  • qtemp should also be reset to 0 after 1 second passed by (as David Koontz wrote in the comment below)
  • if you change the type of qtemp you can rewrite the test (qtemp = "10111110101111000010000000") to (qtemp = 50000000)
    Actually, it should be 49,999,999, because your counter starts at 0.
  • ONEsec_flag is asynchronous set and synchronous reset -> try to write full synchronous design.
  • line if (BaseBeat'event and BaseBeat = '1') and (ONEsec_flag='1') then can and will cause several problems:

    1. BaseBeat is no clock signal, but you are using this signal as a clock. A better solution would be to use BaseBeat as an (clock)enable signal.
    2. writing a rising edge condition and a clock enable in one line is no good style. Additionally it can cause synthesis tools to infer wrong hardware.
    3. In combination with your else-statement this code will not be synthesizable. Here is a solution:

      calculating the flag (concurrent statement):
      ONEsec_flag <= '1' when (qtemp = 49999999) else '0'; -- ternary operator like ?: in C

      transition process:

      transition: process(clk)
      begin
        if rising_edge(clk) then         -- synchronous design using the main clock    
          if (BaseBeat = '1') then       -- using BaseBeat as an clock enable
            if (ONEsec_flag='1') then    -- using flag as an write enable (second ce)
              current_color <= next_color;
            end if;
          end if;
        end if;
      end process;
      
  • So now, flag is calculated concurrently, it can be used to reset the second timer, otherwise a 25 bit vector will overflow after 2^25 cycles, that are 33554432:

    process(clk)
    begin
      if (clk'event and clk='1') then
        if (ONEsec_flag = '1') then      -- synchronous reset if one second is reached
          qtemp <= (others => '0');
        else
          qtemp <= qtemp + 1;
        end if;
      end if;
     end process;
    
  • this leads us to another problem: your counter signal has insufficient bits to hold 49,999,999 -> you need at least 26 bits

  • the UCF file has several errors:

    1. NET "clk" ... has another signal name in comment
    2. one signal can not have multiple locations
    3. ON_BOARD_LED_output is a vector, so you should access each bit by using netname<index> and assign a location for each bit.

      NET "ON_BOARD_LED_output<2>" LOC = "G1" ; # Bank = 3, Signal name = LD7
      NET "ON_BOARD_LED_output<1>" LOC = "P4" ; # Bank = 2, Signal name = LD6
      NET "ON_BOARD_LED_output<0>" LOC = "N4" ; # Bank = 2, Signal name = LD5
      
    4. NET "output" ...: Why have you enabled internal pullup resistors (inside the IOB)? Most development boards have them externally.

    5. and why are you limiting the current to 2 mA (DRIVE = 2)?
    6. All pins have no assigned IOSTANDARD: This is needed for a proper timing analysis. If you want to switch to newer FPGAs and tools, it's then absolutely necessary to declare an IOSTANDARD
\$\endgroup\$
  • \$\begingroup\$ qtemp not gtemp. Spelling IOSTANARD. Now here's a question for you. Should qtemp be cleared at one second to insure color changes are at one second intervals? \$\endgroup\$ – user8352 Dec 31 '14 at 10:44
  • \$\begingroup\$ @DavidKoontz Fixed typos :) -- Were did you get the missing source code? \$\endgroup\$ – Paebbels Dec 31 '14 at 10:58
  • \$\begingroup\$ The code was simply not visible due to how it was described using html tags instead of mark up tags. Certainly looks different doesn't it? \$\endgroup\$ – user8352 Dec 31 '14 at 11:37
  • \$\begingroup\$ How about showing how to insure color changes on 1 sec intervals? \$\endgroup\$ – user8352 Dec 31 '14 at 11:38
  • \$\begingroup\$ @DavidKoontz Absolutely! This changed a lot :) -- So I added a bullet for the counter reset and bit count \$\endgroup\$ – Paebbels Dec 31 '14 at 12:00

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.