hamster tutorial show digits in all 4 segments. What are these...?


mubase

Recommended Posts

Hi again. Following the FPGA tutorial book from Hamster. Excellent book. All beginners must give it a try.

 

In following the tutorials I have come to the exercise asking to implement a number on all 4 digits on the logicstart board. 

I understood the code to use 2 digits per 4 switches.

Now I am not sure as to what this means:

 

 

• Create a new module that can display four digits on the seven segment display. This will be useful for any project you design
that uses the sevenseg displays. Its interface signals should look something like:
clk : in std_logic
digit0 : in std_logic_vector(3 downto 0)
digit1 : in std_logic_vector(3 downto 0)
digit2 : in std_logic_vector(3 downto 0)
digit3 : in std_logic_vector(3 downto 0)
anodes : out std_logic_vector(3 downto 0)
sevenseg : out std_logic_vector(6 downto 0)
dp : out std_logic
 
I understand what all entity components are except the "digitx" signals.
Are they attached to switches or are they part of a clock signal??
 
Link to comment
Share on other sites

Hi OTM.

So the digits inputs will do the same thing as the bcd input in this code..?

library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;entity test isport (      clk : in std_logic;        bcd : in std_logic_vector(3 downto 0);  --BCD input        segment7 : out std_logic_vector(6 downto 0)  -- 7 bit decoded output.    );end test;--'a' corresponds to MSB of segment7 and g corresponds to LSB of segment7.architecture Behavioral of test isbeginprocess (clk,bcd)BEGINif (clk'event and clk='1') thencase  bcd iswhen "0000"=> segment7 <="0000001";  -- '0'when "0001"=> segment7 <="1001111";  -- '1'when "0010"=> segment7 <="0010010";  -- '2'when "0011"=> segment7 <="0000110";  -- '3'when "0100"=> segment7 <="1001100";  -- '4' when "0101"=> segment7 <="0100100";  -- '5'when "0110"=> segment7 <="0100000";  -- '6'when "0111"=> segment7 <="0001111";  -- '7'when "1000"=> segment7 <="0000000";  -- '8'when "1001"=> segment7 <="0000100";  -- '9' --nothing is displayed when a number more than 9 is given as input. when others=> segment7 <="1111111"; end case;end if;end process;end Behavioral;

 

and I just implement 4 cases of each digit with anode ="xxxx" for each one??

Link to comment
Share on other sites

Can't you just connect them to external switches? Or you could have a slow 16 bit counter and connect them as:

digit3(3 downto 0) <= counter(15 downto 12);

digit2(3 downto 0) <= counter(11 downto 8);

etc...

 

Note: the counter counts in binary through all combinations, if your display code is not set up do display hex values, you might end up with blank digits when hex values come up.

Link to comment
Share on other sites

I would suggest ensuring that the 7seg decoder you use for the digits can do hexadecimal numbers so you can put and 4 bit value into the digitX signals and get a meaningful output.

 

Aside from this, if you want to do a decimal counter you will need to do a binary to BCD converter to get 4x4bit BCD inputs, if you want to do a hex counter then just put each 4 bits of the 16 bit counter into the digitX ports and it will count in hex.

Link to comment
Share on other sites

This code will use the "WITH x SELECT" statements that you most likely have not seen, but they are shorthand for what can be implemented using a process, 

 

If you can imagine that 'ones', 'tens', 'hundreds' and 'thousands' are named 'digit0' through 'digit3', and rather than being locally maintained counters are  actually signals passed into the entity...

 

 

library IEEE;
 
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity sevenseg is
    Port ( segments : out  STD_LOGIC_VECTOR (6 downto 0);
           dp       : out  STD_LOGIC;
           anodes   : out  STD_LOGIC_VECTOR (3 downto 0);
 
           clk : in  STD_LOGIC);
end sevenseg;
 
architecture Behavioral of sevenseg is
   signal counter   : std_logic_vector(25 downto 0);
   signal ones      : std_logic_vector(3 downto 0) := (others => '0');
   signal tens      : std_logic_vector(3 downto 0) := (others => '0');
   signal hundreds  : std_logic_vector(3 downto 0) := (others => '0');
   signal thousands : std_logic_vector(3 downto 0) := (others => '0');
   signal digit     : std_logic_vector(3 downto 0) := (others => '0');
begin
   
   with digit  select segments <= "1000000" when "0000",
                                  "1111001" when "0001",
                                  "0100100" when "0010",
                                  "0110000" when "0011",
                                  "0011001" when "0100",
                                  "0010010" when "0101",
                                  "0000010" when "0110",
                                  "1111000" when "0111",
                                  "0000000" when "1000",
                                  "0010000" when "1001",
                                  "1111111" when others;
   
   with counter(16 downto 15) select digit <=  ones      when "00",
                                               tens      when "01",
                                               hundreds  when "10",
                                               thousands when others;
 
   with counter(16 downto 13) select anodes <= "1110" when "0000",
                                               "1101" when "0100",
                                               "1011" when "1000",
                                               "0111" when "1100",
                                               "1111" when others;
                                     
   dp <= '1';
 
cp: process(clk)
   begin   
      if rising_edge(clk) then
         if counter < 3199999 then
            counter <= counter+1;
         else
            counter <= (others => '0');
            if ones = 9 then
               ones <= (others => '0');
               if tens = 9 then
                  tens <= (others => '0');
                  if hundreds = 9 then
                     hundreds <= (others => '0');
                     if thousands = 9 then
                        thousands <= (others => '0');
                     else
                        thousands <= thousands + 1;
                     end if;
                  else
                     hundreds  <= hundreds + 1;
                  end if;                  
               else
                  tens <= tens + 1;
               end if;
            else
               ones <= ones + 1;
            end if;
         end if;
      end if;
   end process;
end Behavioral;
 
Link to comment
Share on other sites

Hi guys and thanks again for pulling me out of a world of S**t. B) 

Alex:

 digit3(3 downto 0) <= counter(15 downto 12);

digit2(3 downto 0) <= counter(11 downto 8);

 

I did attempt going down this route but couldn't get it to work. 

I could't work out the timing between switching anodes and my CASE blocks were all over the place.

The BCD code I inserted from another tutorial I could understand but not convert to 4 digits. 

 

Hamster. Thanks for putting this source file up. I had not known about the "with" "select" statement until today. :) 

Looks like a CASE block with more flexibility..

You make it look simple which in my eyes is the sign of a good coder. :)  Along with being able to think laterally.

 

 

I need to go back over the counter chapter to get a grip on clocking and counts ( x downto y.)

Thanks again for the help!

Link to comment
Share on other sites

Archived

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