Jump to content
  • 0

Something simple is apparently impossible. Incr/decr number.


Tickstart

Question

Hi, I'm just beginning with FPGA's, I bought a Basys 3 this past tuesday.

I'm trying to increment a 4-bit value with the on-board Up-button and decrease it with the Down-button. What is a straight forward way of doing this?? I've tried to get this to work for the last two days. The buttons are debounced, so that's not an issue.

I've tried keeping the value in a signal vector and depending on which button is pressed, add a one or add a two's complement -1. The adding is done with a 4 bit adder I built, which works.

 

I'm sort of new to VHDL and digital design so any useful tips or hints or general advice are very much appreciated.

Instead of getting 1, 2, 3, 4, 5, 6 etc when pressing the Up button, I get a very weird pattern.. See attached photo (the arrows were meant to show that the pattern repeated itself after a number of presses).

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

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity btn_map is
    Port ( btnD, btnU : in STD_LOGIC;							--btnU/D stands for up/down
           key : out STD_LOGIC_VECTOR (3 downto 0));
end btn_map;

architecture Behavioral of btn_map is

component trig_4b_Adder is
    Port ( clk : in STD_LOGIC;			--I modified the adder with some D-flops to not create a combinatorial loop (hence the clk)
           c, y : in STD_LOGIC_VECTOR (3 downto 0);				--c/y are the two 4-bit inputs to the adder
           s : out STD_LOGIC_VECTOR (3 downto 0));				--s = result
end component;

signal val, add_sub, new_key : STD_LOGIC_VECTOR (3 downto 0) := (others => '0');
signal trigger : STD_LOGIC := '0';		-- clock for the adder, "keypressed"

begin

    Adder: trig_4b_Adder port map(clk => trigger, c => val, y => add_sub, s => new_key); -- add_sub is either the +1, -1 or 0
    
    process(btnD, btnU)
        variable minus : STD_LOGIC_VECTOR (3 downto 0) := "1111";
        variable plus : STD_LOGIC_VECTOR (3 downto 0) := "0001";
        variable zero : STD_LOGIC_VECTOR (3 downto 0) := "0000";
        begin
            if btnD = '1' then
                add_sub <= minus;
            elsif btnU = '1' then
                add_sub <= plus;
            else
                add_sub <= zero; -- (sub zero lol)
            end if;
        end process;
                               
    trigger <= btnU or btnD;		-- start the adder
    val <= new_key;	-- I want to save the result from the adder till next clock cycle	-- these two lines of code feel bad for some reason,
    key <= new_key; -- key is the output from this module					-- like my design is inherently flawed somehow..
    
end Behavioral;

 

IMG_20170422_040209832.jpg

Link to comment
Share on other sites

Recommended Posts

It seems that FPGA became fashionable once more. It motivates but not enough. In my opinion in order to learn HDL one should have real need to use FPGAs. In my case I simply didn't have any other viable technical solution.

It should be noted that complexity can quickly get at an unmanageable level. For this reason I appreciate very much introduction by Xilinx of IP integrator with block design. It creates upper level of abstraction and automate interfacing. I believe that it follows the industry trends along with Mathworks and others.

Link to comment
Share on other sites

@Notarobot,

22 minutes ago, Notarobot said:

It should be noted that complexity can quickly get at an unmanageable level. For this reason I appreciate very much introduction by Xilinx of IP integrator with block design. It creates upper level of abstraction and automate interfacing. I believe that it follows the industry trends along with Mathworks and others.

And I like vim better than emacs (or eclipse, nano, etc.)  [Ref]  What's your point?  I mean, truly, is this really the appropriate thread to discuss and promote the IP integrator?  @Tickstart is just trying to build some very simple logic within his FPGA.  Do you really think he needs the IP integrator to do that?

Granted, many projects can be simplified by integrating multiple different component pieces and parts together.  Granted, the industry likes solutions that keep you from needing to build the wheel four or more times.  Granted that abstraction is a very good thing for accomplishing this.  That said ...

  1. Xilinx's IP integrator is not the solution to all problems.  This problem, in particular, is a good example of one for which the IP integrator is overkill.
  2. Xilinx's IP integrator will get you hooked on Xilinx solutions, and may therefore make it difficult for you to switch FPGA vendors. 
  3. Other non-IP integrator solutions exist, even for Xilinx FPGA's.
  4. If you wanted to buy a chip with all the capabilities already integrated within it, you would not have bought an FPGA.  You would have bought a microcontroller.  A quick search of any microcontroller on Digikey will give you a long list of supported interfaces, many of them beyond what you can get within an FPGA, even though the list of components looks an awful lot like the stuff you can get via the IP integrator.  But you (or whoever) bought your FPGA because a microcontroller wasn't available to do your task.  As a result, you need to get used to building stuff using components that are not available to the IP integrator.  Hence, a good solid understanding of VHDL or Verilog will go a long ways.
  5. FPGA solutions built with Xilinx's IP integrator can be difficult to debug.  When someone else's IP has an error, and you can't tell why, ... it can be very frustrating.  Just read these forums.  As it is, in my own code, I can understand and explain every warning Vivado gives me and why each of those warnings are appropriate--I just can't explain any of the ones from any of the foreign IP I integrate into my own code.
  6. Not all of the IP Xilinx provides is "good" IP.  For example, Xilinx's Memory Interface Generator (MIG) generates SDRAM interfaces with *horrible* latency--perhaps twice as much latency as the chip itself requires.  In other words, and again, there is a time and place for building your own.

So ... can we please leave the IP integrator discussions to threads for which they are relevant?

Thanks,

Dan

Link to comment
Share on other sites

All,

For the record Zygot never mentioned class or school. I've learned more doing projects like Tickster is doing than anything I learned in a class. But then I have decades of professional experience behind me. Working on real hardware and using simulator tools has expanded my knowledge much more than if I took specific college classes would have. But being mentored by extremely talented people as a young engineer did way more for shaping my ability to self-learn than college did.  The thing is that without guidance most of us would just learn bad habits and not be able to develop the self-critical attitude and structure that builds knowledge. I would never try to learn Yoga from a book... I'd just end up hurting myself. There are extraordinary people who seems to be able to become experts without being challenged by someone more knowledgeable ( I've know a few ) but most of us are mere mortals. Without having the foundation built by extremely gifted engineers demanding personal structure and developing good processes I doubt that I would be able to have done this self-learning effectively. None of this is to knock the benefit of having a gifted professor, if you're lucky enough to have had one.

I asked about formal training because knowing about this would help me better assess where my thoughts should go.

So, if you'd bear with me Tickstart;

Did you create testbenches for your design entities? ( the problem with testbenches is that you need to write HDL in order to test HDL and there's a bit of art to writing testbenches in its own right... but if your skill at writing HDL for synthesis is shaky you probably won't do a lot better with testbenches )

What is your preparation for doing this project?  Books, formal training ( not necessarily in a school ), studying other peoples code?

Before setting out on this project did you try smaller less complex experiments to hone your craft?

Tell us a bit about yourself and where you come from FPGA development-wise. Evidently we're not going to make terrific progress by tomorrow so, if we're not in a big hurry and there are no deadlines, let's slow down and corral the discussion to fit your needs. You start out with "Hi, I'm just beginning with FPGA's" so there's no where to go but forward, right?

 

 

Link to comment
Share on other sites

1 hour ago, zygot said:

Did you create testbenches for your design entities? ( the problem with testbenches is that you need to write HDL in order to test HDL and there's a bit of art to writing testbenches in its own right... but if your skill at writing HDL for synthesis is shaky you probably won't do a lot better with testbenches )

 

Myeahno not particularly good with test benches. Half the time my outputs are undefined so I just disregard them and assume they work. I test them on hardware instead. I can't understand why Xilinx doesn't automate the testbenches. I've used VHDL testbench generators a bit, but yeah I don't know how to write them.

 

1 hour ago, zygot said:

Tell us a bit about yourself and where you come from FPGA development-wise. Evidently we're not going to make terrific progress by tomorrow so, if we're not in a big hurry and there are no deadlines, let's slow down and corral the discussion to fit your needs. You start out with "Hi, I'm just beginning with FPGA's" so there's no where to go but forward, right?

 

Indeed. Well, I'm a bachelor in computer science, or at least soon after I've presented my thesis etc (which involved a Zynq-7000 chip (the Zedboard)). I did not do any HDL design then though, only C programming. Other than that I have had one course in digital design in which we did some vhdl coding, but that was a long time ago and I wasn't very interested either. When it comes to programming I'm obviously used to more... Neat languages. "Regular" imperative languages like C and Java etc but also declarative ones like Haskell and Prolog.

I honestly don't think my code is that bad, you've just seen a small part of it, the only part that doesn't work, so I'm not too happy about your description of me.

I got the 7-segment screen to work for instance, that at least SOUNDS like a harder thing to implement than a simple up-/down counting variable...

 

Anyway, I don't like using other people's code unless I understand it, so if you're posting code please state what's different about it in comparison to something else. I'm the most impatient person in the world so I need very to-the-point, concrete explanations for why I'm failing. I am not stupid, just uninformed. If there's one thing I've at least got some hang of it's doing mealy-/moore machines by hand with 0's and 1's on paper, karnaugh maps and stuff, which works for small things. I don't really like vhdl's functions and processes and procedures, they're confusing and obfuscating.

 

Anyway, I don't even know how this is normally done. If I tie the clock signal to the adder it will go haywire and add four million things per half second. I have to create some sort of "escapement" I guess, for just letting one signal through at a time...

 I thought about having a dedicated up- vs down counter but apparently it's impossible to connect the same "out variable" or signal to those two modules (signal contention I assume).

 

Let's roll back for a minute, I'd love to hear how you (as in all of you) would go about this problem :) Just need a fresh pair of eyes. The numbers I get are consistent and wrong, but the adder works in other applications.

Link to comment
Share on other sites

@Tickstart,

32 minutes ago, Tickstart said:

Let's roll back for a minute, I'd love to hear how you (as in all of you) would go about this problem :) Just need a fresh pair of eyes.

Sure!  For starters, I'd use the code @hamster posted above for debouncing the button inputs. As I said above, his final piece of code was better than the one I had written for the same purpose.

Second, I'd keep track of the last (debounced) button state, as well as the current (debounced) button state.  When the current button state is down and different from the last one, I'd look at the two buttons, up and down.  If both were pressed or neither were pressed, I'd do nothing.  Otherwise I'd adjust the counter.  Forgive the Verilog, but the result would look something like:

reg	[3:0]	counter;

reg	last_up, last_down, this_up, this_down;
initial last_up = 1'b0;
initial last_down = 1'b0;
initial this_up = 1'b0;
initial this_down = 1'b0;
initial	counter = 0;

always @(posedge i_clk)
begin
	//
	last_up   <= button_up;
    last_down <= button_down;
    //
    this_up   <= (button_up)&&(!last_up);
    this_down <= (button_down)&&(!last_down);
    //
    case({this_up, this_down})
    2'b01: if (counter) 
    		counter <= counter - 1'b1; 
            else
            counter <= 4'h9;
    2'b10: if (counter < 4'h9)
    		counter <= counter + 1'b1;
            else
            counter <= 4'h0;
    default: counter <= counter;
    endcase
end

Congrats on getting the 7Seg up and running too!  I agree with you as well, though, that ... you'd think the 7segment display would be harder than getting this simple counter up and running.  Still, handling asynchronous input (such as the buttons) is enough to ... how did @zygot put it?  Keep a professional up at night?  ;)

Good luck on your project, and keep us posted if you need any more help.

Dan

Link to comment
Share on other sites

Tickstart,these

I haven't made any "description" of you nor do I think that you're stupid... so please don't amend my comments to garner an unearned insult. If I want to insult you I will do so without there being any doubt about it. Actually, there was the one time I DID try and insult someone intentionally and he just thought that I was funny.... what an ass ( a MENSA member ) so I've given that up. Really, I don't want to insult anyone ( other than that guy...) but seem to have a knack for doing it unintentionally. It's a "gift" I suppose....

So, thanks for the background. This is helpful and I think that we can get somewhere.

First off, the fact that even with over 20 years of experience writing HDL code professionally I write test benches for all of my design modules should be a big hint as to what kind of advice you will get from me, Learn how to write testbenches. There is help on the internet if you look for it. Testbenches don't solve all problems as they only do what you make the test... meaning that you have to understand what to test for. This reason alone is why you need to use them. Your skill designing solutions to problems will get better as your testbenches improve. Trust me on this.

You state: "I don't really like vhdl's functions and processes and procedures, they're confusing and obfuscating."

Yes they are... until you understand the concepts. Until you do using VHDL or Verilog will be a very painful exercise for you. And will System C and whatever becomes popular down the road as well. This is something that I can't help you with... you need to decide that it's worth your time and effort. Having some sort of mentor might help. You don't have to take a course but it wouldn't hurt either. As I mentioned before FPGA design concepts are different from standard computer languages ( I've used C, PASCAL, ADA, PYTHON, numerous assembly languages, custom languages, etc, etc.) . If you don't have an interest in learning them you will be a very frustrated person doing your FPGA development. That's just advice not a judgement about you.

So, it should be no surprise to you that I disagree with your last statement: "Just need a fresh pair of eyes". But you are under no obligation to take my advise.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...