Skip to content

Commit

Permalink
Add 7 segment display decoder
Browse files Browse the repository at this point in the history
Fede-26 committed Feb 19, 2024
1 parent c6dbc50 commit 2c20f06
Showing 5 changed files with 192 additions and 4 deletions.
4 changes: 3 additions & 1 deletion sap_1.gprj
Original file line number Diff line number Diff line change
@@ -5,8 +5,10 @@
<Version>5</Version>
<Device name="GW1NR-9C" pn="GW1NR-LV9QN88PC6/I5">gw1nr9c-004</Device>
<FileList>
<File path="src/CPU/ALU.vhd" type="file.vhdl" enable="1"/>
<File path="src/ALU.vhd" type="file.vhdl" enable="1"/>
<File path="src/Binary_To_7_Segment_Decoder.vhd" type="file.vhdl" enable="1"/>
<File path="src/Clock_Divider.vhd" type="file.vhdl" enable="1"/>
<File path="src/RAM.vhd" type="file.vhdl" enable="1"/>
<File path="src/SAP_1_Top.vhd" type="file.vhdl" enable="1"/>
</FileList>
</Project>
6 changes: 3 additions & 3 deletions sap_1.gprj.user
Original file line number Diff line number Diff line change
@@ -4,8 +4,8 @@
<Version>1.0</Version>
<FlowState>
<Process ID="Synthesis" State="2"/>
<Process ID="Pnr" State="2"/>
<Process ID="Gao" State="2"/>
<Process ID="Pnr" State="4"/>
<Process ID="Gao" State="4"/>
<Process ID="Rtl_Gao" State="2"/>
</FlowState>
<ResultFileList>
@@ -20,5 +20,5 @@
<ResultFile ResultFileType="RES.syn.report" ResultFilePath="impl/gwsynthesis/sap_1_syn.rpt.html"/>
<ResultFile ResultFileType="RES.syn.resource" ResultFilePath="impl/gwsynthesis/sap_1_syn_rsc.xml"/>
</ResultFileList>
<Ui>000000ff00000001fd0000000200000000000001000000025ffc0200000001fc0000003f0000025f0000009a01000018fa000000010200000003fb00000030004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00440065007300690067006e0100000000ffffffff0000006600fffffffb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00500072006f00630065007300730100000000ffffffff0000006200fffffffb00000036004600700067006100500072006f006a006500630074002e00500061006e0065006c002e0048006900650072006100720063006800790100000000ffffffff0000008100ffffff000000030000050000000110fc0100000001fc00000000000005000000009e00fffffffa000000000100000002fb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00470065006e006500720061006c0100000000ffffffff0000004d00fffffffb0000002e004600700067006100500072006f006a006500630074002e00500061006e0065006c002e004900730073007500650100000000ffffffff0000009e00ffffff000003fa0000025f00000004000000040000000800000008fc000000010000000200000004000000220043006f00720065002e0054006f006f006c006200610072002e00460069006c00650100000000ffffffff0000000000000000000000220043006f00720065002e0054006f006f006c006200610072002e004500640069007401000000b6ffffffff0000000000000000000000240043006f00720065002e0054006f006f006c006200610072002e0054006f006f006c00730100000195ffffffff0000000000000000ffffffff0100000264ffffffff0000000000000000</Ui>
<Ui>000000ff00000001fd0000000200000000000001000000025ffc0200000001fc0000003f0000025f0000000000fffffffaffffffff0200000003fb00000030004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00440065007300690067006e0100000000ffffffff0000000000000000fb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00500072006f00630065007300730100000000ffffffff0000000000000000fb00000036004600700067006100500072006f006a006500630074002e00500061006e0065006c002e0048006900650072006100720063006800790100000000ffffffff0000000000000000000000030000050000000110fc0100000001fc00000000000005000000009e00fffffffa000000000100000002fb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00470065006e006500720061006c0100000000ffffffff0000004d00fffffffb0000002e004600700067006100500072006f006a006500630074002e00500061006e0065006c002e004900730073007500650100000000ffffffff0000009e00ffffff000003fa0000025f00000004000000040000000800000008fc000000010000000200000003000000220043006f00720065002e0054006f006f006c006200610072002e00460069006c00650100000000ffffffff0000000000000000000000220043006f00720065002e0054006f006f006c006200610072002e004500640069007401000000b6ffffffff0000000000000000000000240043006f00720065002e0054006f006f006c006200610072002e0054006f006f006c00730100000195ffffffff0000000000000000</Ui>
</UserConfig>
83 changes: 83 additions & 0 deletions src/Binary_To_7_Segment_Decoder.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Binary_To_7_Segment_Decoder is
port (
i_Clk : in std_logic; -- Clock
i_Num : in std_logic_vector(15 downto 0); -- 4 Digit hex number
o_D1, o_D2, o_D3, o_D4 : out std_logic; -- 7 segment display selector
o_A, o_B, o_C, o_D, o_E, o_F, o_G : out std_logic -- 7 segment display segments
);
end Binary_To_7_Segment_Decoder;

architecture rtl of Binary_To_7_Segment_Decoder is
signal w_First_Digit, w_Second_Digit, w_Third_Digit, w_Fourth_Digit : std_logic_vector(3 downto 0);
signal w_Current_Digit_Content : std_logic_vector(3 downto 0);
signal r_Current_Viewing_Digit : std_logic_vector(1 downto 0) := "00";
signal w_Output : std_logic_vector(6 downto 0);
begin

-- Split the number into 4 digits
w_First_Digit <= i_Num(15 downto 12);
w_Second_Digit <= i_Num(11 downto 8);
w_Third_Digit <= i_Num(7 downto 4);
w_Fourth_Digit <= i_Num(3 downto 0);

-- Selects the current digit to display
w_Current_Digit_Content <= w_First_Digit when r_Current_Viewing_Digit = "00" else
w_Second_Digit when r_Current_Viewing_Digit = "01" else
w_Third_Digit when r_Current_Viewing_Digit = "10" else
w_Fourth_Digit;

-- Enable the digit to display (active low)
o_D1 <= '0' when r_Current_Viewing_Digit = "00" else
'1';
o_D2 <= '0' when r_Current_Viewing_Digit = "01" else
'1';
o_D3 <= '0' when r_Current_Viewing_Digit = "10" else
'1';
o_D4 <= '0' when r_Current_Viewing_Digit = "11" else
'1';

-- 7 segment display decoder
w_Output <= "1111110" when w_Current_Digit_Content = "0000" else -- 0x7E
"0110000" when w_Current_Digit_Content = "0001" else -- 0x30
"1101101" when w_Current_Digit_Content = "0010" else -- 0x6D
"1111001" when w_Current_Digit_Content = "0011" else -- 0x79
"0110011" when w_Current_Digit_Content = "0100" else -- 0x33
"1011011" when w_Current_Digit_Content = "0101" else -- 0x5B
"1011111" when w_Current_Digit_Content = "0110" else -- 0x5F
"1110000" when w_Current_Digit_Content = "0111" else -- 0x70
"1111111" when w_Current_Digit_Content = "1000" else -- 0x7F
"1111011" when w_Current_Digit_Content = "1001" else -- 0x7B
"1110111" when w_Current_Digit_Content = "1010" else -- 0x77
"0011111" when w_Current_Digit_Content = "1011" else -- 0x1F
"1001110" when w_Current_Digit_Content = "1100" else -- 0x4E
"0111101" when w_Current_Digit_Content = "1101" else -- 0x3D
"1001111" when w_Current_Digit_Content = "1110" else -- 0x4F
"1000111" when w_Current_Digit_Content = "1111" else -- 0x47
"0000000";

-- 7 segment display output
o_A <= w_Output(6);
o_B <= w_Output(5);
o_C <= w_Output(4);
o_D <= w_Output(3);
o_E <= w_Output(2);
o_F <= w_Output(1);
o_G <= w_Output(0);

process (i_Clk)
begin
if rising_edge(i_Clk) then

-- Rotate the digit to display
r_Current_Viewing_Digit <= "01" when r_Current_Viewing_Digit = "00" else
"10" when r_Current_Viewing_Digit = "01" else
"11" when r_Current_Viewing_Digit = "10" else
"00";
end if;
end process;

end rtl;
17 changes: 17 additions & 0 deletions src/SAP_1_Top.vhd
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity sap_1_top is
port (
@@ -18,6 +19,10 @@ architecture rtl of sap_1_top is
signal r_Reg_B : std_logic_vector(7 downto 0); -- General purpose register B
signal r_Reg_MAR : std_logic_vector(3 downto 0); -- Memory address register (4-bit)

-- Program counter
signal r_Program_Counter : std_logic_vector(3 downto 0); -- Program counter (4-bit)
signal r_Program_Counter_Enable : std_logic; -- Enable signal for the program counter

-- ALU
signal w_ALU_Out : std_logic_vector(7 downto 0); -- Output of the ALU

@@ -29,6 +34,7 @@ architecture rtl of sap_1_top is
signal w_Bus : std_logic_vector(7 downto 0);
signal r_Bus_Enable_ALU : std_logic := '0'; -- Enable the bus to be driven by the ALU
signal r_Bus_Enable_RAM : std_logic := '0'; -- Enable the bus to be driven by the RAM
signal r_Bus_Enable_PC : std_logic := '0'; -- Enable the bus to be driven by the program counter

-- Flags
signal w_Carry : std_logic; -- Carry flag (set if the ALU operation results in a carry)
@@ -70,6 +76,17 @@ begin
-- Bus
w_Bus <= w_ALU_Out when r_Bus_Enable_ALU = '1' else
w_RAM_Out when r_Bus_Enable_RAM = '1' else
("0000" & r_Program_Counter) when r_Bus_Enable_PC = '1' else
(others => 'Z');

-- Program counter
Process_Counter : process (w_Clk)
begin
if rising_edge(w_Clk) then
if r_Program_Counter_Enable = '1' then
r_Program_Counter <= std_logic_vector(to_unsigned(to_integer(unsigned( r_Program_Counter )) + 1, 4));
end if;
end if;
end process Process_Counter;

end rtl;
86 changes: 86 additions & 0 deletions src/sim/Binary_To_7_Segment_Decoder_TB.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library vunit_lib;
context vunit_lib.vunit_context;

entity Binary_To_7_Segment_Decoder_TB is
generic (runner_cfg : string);
end entity;

architecture tb of Binary_To_7_Segment_Decoder_TB is

signal r_Clk : std_logic := '0';
signal r_Num : std_logic_vector(15 downto 0) := (others => '0');
signal w_D1, w_D2, w_D3, w_D4 : std_logic;
signal w_A, w_B, w_C, w_D, w_E, w_F, w_G : std_logic;

begin
-- Instantiate the UUT
UUT : entity work.Binary_To_7_Segment_Decoder
port map(
i_Clk => r_Clk, -- Clock
i_Num => r_Num, -- 4 Digit hex number
o_D1 => w_D1, o_D2 => w_D2, o_D3 => w_D3, o_D4 => w_D4, -- 7 segment display selector
o_A => w_A, o_B => w_B, o_C => w_C, o_D => w_D, o_E => w_E, o_F => w_F, o_G => w_G -- 7 segment display segments
);

-- Clock
-- r_Clk <= not r_Clk after 5 ns;

main : process
begin
test_runner_setup(runner, runner_cfg);
wait for 10 ns;

r_Num <= x"F1E8";
wait for 10 ns;

-- First digit
assert (w_D1 = '0' and w_D2 = '1' and w_D3 = '1' and w_D4 = '1') report "Error: First digit is not the first" severity failure;
assert (w_A = '1' and w_B = '0' and w_C = '0' and w_D = '0' and w_E = '1' and w_F = '1' and w_G = '1') report "Error: First digit display wrong segments" severity failure;

-- Switch to second digit
r_Clk <= '0';
wait for 10 ns;
r_ClK <= '1';
wait for 10 ns;
assert (w_D1 = '1' and w_D2 = '0' and w_D3 = '1' and w_D4 = '1') report "Error: Second digit is not the second" severity failure;
assert (w_A = '0' and w_B = '1' and w_C = '1' and w_D = '0' and w_E = '0' and w_F = '0' and w_G = '0') report "Error: Second digit display wrong segments" severity failure;

-- Switch to third digit
r_Clk <= '0';
wait for 10 ns;
r_ClK <= '1';
wait for 10 ns;
assert (w_D1 = '1' and w_D2 = '1' and w_D3 = '0' and w_D4 = '1') report "Error: Third digit is not the third" severity failure;
assert (w_A = '1' and w_B = '0' and w_C = '0' and w_D = '1' and w_E = '1' and w_F = '1' and w_G = '1') report "Error: Third digit display wrong segments" severity failure;

-- Switch to fourth digit
r_Clk <= '0';
wait for 10 ns;
r_ClK <= '1';
wait for 10 ns;
assert (w_D1 = '1' and w_D2 = '1' and w_D3 = '1' and w_D4 = '0') report "Error: Fourth digit is not the fourth" severity failure;
assert (w_A = '1' and w_B = '1' and w_C = '1' and w_D = '1' and w_E = '1' and w_F = '1' and w_G = '1') report "Error: Fourth digit display wrong segments" severity failure;

-- Return to first digit
r_Clk <= '0';
wait for 10 ns;
r_ClK <= '1';
wait for 10 ns;
assert(w_D1 = '0' and w_D2 = '1' and w_D3 = '1' and w_D4 = '1') report "Error: First digit is not the first" severity failure;
assert(w_A = '1' and w_B = '0' and w_C = '0' and w_D = '0' and w_E = '1' and w_F = '1' and w_G = '1') report "Error: First digit display wrong segments" severity failure;

-- Switch number without clock
r_Num <= x"1234";
wait for 10 ns;
assert(w_D1 = '0' and w_D2 = '1' and w_D3 = '1' and w_D4 = '1') report "Error: First digit is not the first" severity failure;
assert(w_A = '0' and w_B = '1' and w_C = '1' and w_D = '0' and w_E = '0' and w_F = '0' and w_G = '0') report "Error: First digit display wrong segments" severity failure;

wait for 10 ns;

test_runner_cleanup(runner); -- Simulation ends here
end process;
end architecture;

0 comments on commit 2c20f06

Please sign in to comment.