Electronics > Projects, Designs, and Technical Stuff
16 bit to 4 digit 7 segment decoder
obiwanjacobi:
That is awesome!
I have to see why mine is so different (made with WinCupl) - I'm on a different computer now.
I had a 22V10 and also had the multiplexer in there. I could see the at several (seg) outputs I exceeded the max number of product terms.
But I do not think I can make it work for a 16-bit bus. I would need 2 chips and some way of syncing them up.
----
I think -based on ebay prices- a single 40-pin ATMega8515 is the cheapest as it stand now. It would also be the simplest construction/wiring.
oPossum:
--- Quote from: obiwanjacobi on December 20, 2019, 07:26:49 am ---But I do not think I can make it work for a 16-bit bus. I would need 2 chips and some way of syncing them up.
--- End quote ---
I am not suggesting this is a good way, but I think it would work.
--- Code: ---entity hex_to_7_seg_multi is
port(
hex_in_a: in std_logic_vector ( 3 downto 0 );
hex_in_b: in std_logic_vector ( 3 downto 0 );
enable_a: in std_logic;
enable_b: in std_logic;
seg_a_out: out std_logic;
seg_b_out: out std_logic;
seg_c_out: out std_logic;
seg_d_out: out std_logic;
seg_e_out: out std_logic;
seg_f_out: out std_logic;
seg_g_out: out std_logic);
attribute LOC: string;
attribute LOC of hex_in_a: signal is "5 4 3 2";
attribute LOC of hex_in_b: signal is "9 8 7 6";
attribute LOC of enable_a: signal is "10";
attribute LOC of enable_b: signal is "11";
-- Gnd 12
attribute LOC of seg_a_out: signal is "15";
attribute LOC of seg_b_out: signal is "16";
attribute LOC of seg_c_out: signal is "17";
attribute LOC of seg_d_out: signal is "18";
attribute LOC of seg_e_out: signal is "19";
attribute LOC of seg_f_out: signal is "20";
attribute LOC of seg_g_out: signal is "21";
-- Vcc 24
end;
architecture Hex_to_7_seg_multi of hex_to_7_seg_multi is
signal polarity: std_logic := '0';
signal hex_in: std_logic_vector(3 downto 0);
signal seg_a: std_logic;
signal seg_b: std_logic;
signal seg_c: std_logic;
signal seg_d: std_logic;
signal seg_e: std_logic;
signal seg_f: std_logic;
signal seg_g: std_logic;
signal enabled: std_logic;
ATTRIBUTE SYN_KEEP : integer;
ATTRIBUTE SYN_KEEP OF enabled : SIGNAL IS 1;
ATTRIBUTE OPT : string;
ATTRIBUTE OPT OF enabled: SIGNAL IS "KEEP";
begin
process (enable_a, enable_b, hex_in_a, hex_in_b, polarity, enabled)
begin
if enable_b = '1' then
hex_in <= hex_in_b;
else
hex_in <= hex_in_a;
end if;
case hex_in is
when "0000" => seg_a <= '1'; seg_b <= '1'; seg_c <= '1'; seg_d <= '1'; seg_e <= '1'; seg_f <= '1'; seg_g <= '0';
when "0001" => seg_a <= '0'; seg_b <= '1'; seg_c <= '1'; seg_d <= '0'; seg_e <= '0'; seg_f <= '0'; seg_g <= '0';
when "0010" => seg_a <= '1'; seg_b <= '1'; seg_c <= '0'; seg_d <= '1'; seg_e <= '1'; seg_f <= '0'; seg_g <= '1';
when "0011" => seg_a <= '1'; seg_b <= '1'; seg_c <= '1'; seg_d <= '1'; seg_e <= '0'; seg_f <= '0'; seg_g <= '1';
when "0100" => seg_a <= '0'; seg_b <= '1'; seg_c <= '1'; seg_d <= '0'; seg_e <= '0'; seg_f <= '1'; seg_g <= '1';
when "0101" => seg_a <= '1'; seg_b <= '0'; seg_c <= '1'; seg_d <= '1'; seg_e <= '0'; seg_f <= '1'; seg_g <= '1';
when "0110" => seg_a <= '1'; seg_b <= '0'; seg_c <= '1'; seg_d <= '1'; seg_e <= '1'; seg_f <= '1'; seg_g <= '1';
when "0111" => seg_a <= '1'; seg_b <= '1'; seg_c <= '1'; seg_d <= '0'; seg_e <= '0'; seg_f <= '0'; seg_g <= '0';
when "1000" => seg_a <= '1'; seg_b <= '1'; seg_c <= '1'; seg_d <= '1'; seg_e <= '1'; seg_f <= '1'; seg_g <= '1';
when "1001" => seg_a <= '1'; seg_b <= '1'; seg_c <= '1'; seg_d <= '0'; seg_e <= '0'; seg_f <= '1'; seg_g <= '1';
when "1010" => seg_a <= '1'; seg_b <= '1'; seg_c <= '1'; seg_d <= '0'; seg_e <= '1'; seg_f <= '1'; seg_g <= '1';
when "1011" => seg_a <= '0'; seg_b <= '0'; seg_c <= '1'; seg_d <= '1'; seg_e <= '1'; seg_f <= '1'; seg_g <= '1';
when "1100" => seg_a <= '1'; seg_b <= '0'; seg_c <= '0'; seg_d <= '1'; seg_e <= '1'; seg_f <= '1'; seg_g <= '0';
when "1101" => seg_a <= '0'; seg_b <= '1'; seg_c <= '1'; seg_d <= '1'; seg_e <= '1'; seg_f <= '0'; seg_g <= '1';
when "1110" => seg_a <= '1'; seg_b <= '0'; seg_c <= '0'; seg_d <= '1'; seg_e <= '1'; seg_f <= '1'; seg_g <= '1';
when "1111" => seg_a <= '1'; seg_b <= '0'; seg_c <= '0'; seg_d <= '0'; seg_e <= '1'; seg_f <= '1'; seg_g <= '1';
end case;
enabled <= enable_a or enable_b;
if enabled = '1' then
if polarity = '1' then
seg_a_out <= seg_a;
seg_b_out <= seg_b;
seg_c_out <= seg_c;
seg_d_out <= seg_d;
seg_e_out <= seg_e;
seg_f_out <= seg_f;
seg_g_out <= seg_g;
else
seg_a_out <= not seg_a;
seg_b_out <= not seg_b;
seg_c_out <= not seg_c;
seg_d_out <= not seg_d;
seg_e_out <= not seg_e;
seg_f_out <= not seg_f;
seg_g_out <= not seg_g;
end if;
else
seg_a_out <= 'Z';
seg_b_out <= 'Z';
seg_c_out <= 'Z';
seg_d_out <= 'Z';
seg_e_out <= 'Z';
seg_f_out <= 'Z';
seg_g_out <= 'Z';
end if;
end process;
end Hex_to_7_seg_multi;
--- End code ---
tggzzz:
--- Quote from: obiwanjacobi on December 20, 2019, 07:26:49 am ---I think -based on ebay prices- a single 40-pin ATMega8515 is the cheapest as it stand now. It would also be the simplest construction/wiring.
--- End quote ---
To minimise pins, check out the concepts behind "charlieplexing".
obiwanjacobi:
--- Quote from: oPossum on December 20, 2019, 10:52:35 am ---I am not suggesting this is a good way, but I think it would work.
...
--- End quote ---
Yes, I would need to use the OE of the GALs. But I would like to program the multiplexer FF inside GAL/GALs as well. Then you'll end up with almost two identical GALs... I would use an extra input to sync up the second GAL with the first (have a couple of free inputs).
I have to look at you solution in greater detail and compare it to my design (that was too big). Perhaps I can find a way to slim it down...?
---
--- Quote from: tggzzz on December 20, 2019, 11:06:46 am ---To minimise pins, check out the concepts behind "charlieplexing".
--- End quote ---
Post #1
--- Quote from: obiwanjacobi on December 19, 2019, 08:27:08 am ---I have a (couple of) 4 digit 7 segment display module (NSB3881) and want to use it to plug into data and address buses of hobby projects to display bus values. The 7seg unit is common cathode and has all the segment lines (a-g/dp) connected over all 4 digits.
--- End quote ---
I do not know how to charlieplex common cathode segements... :-//
(I am not intimate with the finer details of charlieplexing)
obiwanjacobi:
@oPossum
I have tried your (first) example and copied the boolean expressions and it works fine.
I think my initial CUPL code was too 'abstract' for the compiler to optimize well...
This code:
--- Code: ---Name 2-Digit 7-Segment Decoder;
PartNo 2D7SDecoder-01;
Date 18-12-2019;
Revision 01;
Designer Marc Jacobi;
Company Canned Bytes;
Assembly unknown;
Location unknown;
Device g22v10;
/*Format j ;*/
/** input pins **/
PIN 1 = CLK;
PIN 2 = D0;
PIN 3 = D1;
PIN 4 = D2;
PIN 5 = D3;
PIN 6 = D4;
PIN 7 = D5;
PIN 8 = D6;
PIN 9 = D7;
/** output pins **/
PIN 14 = a;
PIN 15 = b;
PIN 16 = c;
PIN 17 = d;
PIN 18 = e;
PIN 19 = f;
PIN 20 = g;
PIN 21 = dp;
PIN 22 = n1;
PIN 23 = n2;
/* not used */
n1.ar = 'b'0;
n1.sp = 'b'0;
n1.d = !n1;
n2 = !n1;
dec0 = (D0 & n1) # (D4 & !n1);
dec1 = (D1 & n1) # (D5 & !n1);
dec2 = (D2 & n1) # (D6 & !n1);
dec3 = (D3 & n1) # (D7 & !n1);
FIELD decode = [dec3, dec2, dec1, dec0];
FIELD output = [dp, g, f, e, d, c, b, a];
TABLE decode => output
{
0 => 'b'00111111;
1 => 'b'00000110;
2 => 'b'01011011;
3 => 'b'01001111;
4 => 'b'01100110;
5 => 'b'01101101;
6 => 'b'01111101;
7 => 'b'00000111;
8 => 'b'01111111;
9 => 'b'01101111;
A => 'b'11110111;
B => 'b'11111100;
C => 'b'10111001;
D => 'b'11011110;
E => 'b'11111011;
F => 'b'11110001;
}
--- End code ---
resulted in these equations
--- Code: ---a =>
D4 & D5 & D6 & D7 & !n1
# !D4 & D7 & !n1
# D0 & D1 & D2 & D3 & n1
# !D0 & D3 & n1
# !D0 & !D2 & !D3 & n1
# !D4 & !D6 & !D7 & !n1
# D0 & D1 & !D3 & n1
# D4 & D5 & !D7 & !n1
# !D0 & D1 & D2 & !D3 & n1
# D0 & !D1 & D2 & !D3 & n1
# !D4 & D5 & D6 & !D7 & !n1
# D4 & !D5 & D6 & !D7 & !n1
# !D1 & !D2 & D3 & n1
# !D5 & !D6 & D7 & !n1
b =>
!D4 & D5 & D7 & !n1
# !D0 & D1 & D3 & n1
# !D0 & !D1 & !D3 & n1
# !D2 & !D3 & n1
# !D4 & !D5 & !D7 & !n1
# !D6 & !D7 & !n1
# D0 & D1 & !D3 & n1
# D4 & D5 & !D7 & !n1
# D0 & !D1 & D2 & D3 & n1
# D4 & !D5 & D6 & D7 & !n1
# !D1 & !D2 & D3 & n1
# !D5 & !D6 & D7 & !n1
c =>
!D4 & D5 & !D6 & D7 & !n1
# !D0 & D1 & !D2 & D3 & n1
# D0 & D1 & !D2 & n1
# !D1 & !D3 & n1
# D4 & D5 & !D6 & !n1
# !D5 & !D6 & !D7 & !n1
# !D4 & !D5 & D6 & !D7 & !n1
# D0 & D1 & !D3 & n1
# D4 & D5 & !D7 & !n1
# D0 & !D1 & D2 & D3 & n1
# !D0 & D1 & D2 & !D3 & n1
# D4 & !D5 & D6 & D7 & !n1
# !D4 & D5 & D6 & !D7 & !n1
# D4 & !D5 & D6 & !D7 & !n1
# !D1 & !D2 & D3 & n1
# !D5 & !D6 & D7 & !n1
d =>
!D4 & D5 & D6 & D7 & !n1
# !D0 & D1 & D2 & D3 & n1
# !D0 & !D2 & !D3 & n1
# D0 & D1 & !D2 & n1
# !D0 & !D1 & D2 & D3 & n1
# !D4 & !D6 & !D7 & !n1
# D4 & D5 & !D6 & !n1
# !D4 & !D5 & D6 & D7 & !n1
# D0 & !D1 & D2 & D3 & n1
# !D0 & D1 & D2 & !D3 & n1
# D0 & !D1 & D2 & !D3 & n1
# D4 & !D5 & D6 & D7 & !n1
# !D4 & D5 & D6 & !D7 & !n1
# D4 & !D5 & D6 & !D7 & !n1
# !D1 & !D2 & D3 & n1
# !D5 & !D6 & D7 & !n1
dec0 =>
D0 & n1
# D4 & !n1
dec1 =>
D1 & n1
# D5 & !n1
dec2 =>
D2 & n1
# D6 & !n1
dec3 =>
D3 & n1
# D7 & !n1
decode =>
dec3 , dec2 , dec1 , dec0
dp =>
D5 & D7 & !n1
# D1 & D3 & n1
# !D0 & !D1 & D2 & D3 & n1
# !D4 & !D5 & D6 & D7 & !n1
# D0 & !D1 & D2 & D3 & n1
# D4 & !D5 & D6 & D7 & !n1
e =>
D5 & D7 & !n1
# !D4 & D7 & !n1
# D1 & D3 & n1
# !D0 & D3 & n1
# !D0 & !D2 & !D3 & n1
# !D4 & !D6 & !D7 & !n1
# D0 & !D1 & D2 & D3 & n1
# !D0 & D1 & D2 & !D3 & n1
# D4 & !D5 & D6 & D7 & !n1
# !D4 & D5 & D6 & !D7 & !n1
f =>
D5 & D7 & !n1
# !D4 & D7 & !n1
# D1 & D3 & n1
# !D0 & D3 & n1
# !D0 & !D1 & !D3 & n1
# !D4 & !D5 & !D7 & !n1
# !D0 & D1 & D2 & !D3 & n1
# D0 & !D1 & D2 & !D3 & n1
# !D4 & D5 & D6 & !D7 & !n1
# D4 & !D5 & D6 & !D7 & !n1
# !D1 & !D2 & D3 & n1
# !D5 & !D6 & D7 & !n1
g =>
D5 & D7 & !n1
# !D4 & D5 & !D6 & !D7 & !n1
# D1 & D3 & n1
# !D0 & !D1 & D2 & !D3 & n1
# D1 & !D2 & !D3 & n1
# D4 & D5 & !D6 & !n1
# !D4 & !D5 & D6 & !D7 & !n1
# D0 & !D1 & D2 & D3 & n1
# !D0 & D1 & D2 & !D3 & n1
# D0 & !D1 & D2 & !D3 & n1
# D4 & !D5 & D6 & D7 & !n1
# !D4 & D5 & D6 & !D7 & !n1
# D4 & !D5 & D6 & !D7 & !n1
# !D1 & !D2 & D3 & n1
# !D5 & !D6 & D7 & !n1
n1.d =>
D5 & D7 & !n1
# !D4 & !D5 & D6 & D7 & !n1
# !D6 & !D7 & !n1
# !D4 & !D5 & D6 & !D7 & !n1
# D4 & D5 & !D7 & !n1
# D4 & !D5 & D6 & D7 & !n1
# !D4 & D5 & D6 & !D7 & !n1
# D4 & !D5 & D6 & !D7 & !n1
# !D5 & !D6 & D7 & !n1
n1.ar =>
0
n1.sp =>
0
n2 =>
D5 & D7 & !n1
# !D4 & !D5 & D6 & D7 & !n1
# !D6 & !D7 & !n1
# !D4 & !D5 & D6 & !D7 & !n1
# D4 & D5 & !D7 & !n1
# D4 & !D5 & D6 & D7 & !n1
# !D4 & D5 & D6 & !D7 & !n1
# D4 & !D5 & D6 & !D7 & !n1
# !D5 & !D6 & D7 & !n1
output =>
dp , g , f , e , d , c , b , a
--- End code ---
Have not taken the time to analyze what went wrong here...
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version