Add seven-segments module and integrate it into the top level

This commit is contained in:
2022-11-12 20:17:56 +01:00
parent 62173ffb5e
commit 9756b655b6
10 changed files with 491 additions and 8 deletions

View File

@@ -29,6 +29,7 @@ package config is
constant CFG_LED : integer := CFG_DMEM+1;
constant CFG_SW : integer := CFG_LED+1;
constant CFG_TIMER : integer := CFG_SW+1;
constant CFG_SEG : integer := CFG_TIMER+1;
-----------------------------
-- base address (BADR) & mask address (MADR)
@@ -40,6 +41,7 @@ package config is
constant CFG_BADR_LED : generic_addr_type := 16#000F0000#;
constant CFG_BADR_SW : generic_addr_type := 16#000F0004#;
constant CFG_BADR_TIMER : generic_addr_type := 16#000F0008#;
constant CFG_BADR_SEG : generic_addr_type := 16#000F00A0#;
-- mask addr
constant CFG_MADR_ZERO : generic_mask_type := 0;
@@ -49,6 +51,7 @@ package config is
constant CFG_MADR_LED : generic_mask_type := 16#3FFFFF#; -- size=1 byte
constant CFG_MADR_SW : generic_mask_type := 16#3FFFFF# - (4 - 1); -- size=4 byte
constant CFG_MADR_TIMER : generic_mask_type := 16#3FFFFF# - (8 - 1); -- size=8 byte (2 words)
constant CFG_MADR_SEG : generic_mask_type := 16#3FFFFF# - (8 - 1); -- size=8 byte (2 words)
end package config;

View File

@@ -0,0 +1,42 @@
-- See the file "LICENSE" for the full license governing this code. --
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.lt16x32_global.all;
use work.config.all;
entity hex2physical is
port(
hex : in std_logic_vector(4 downto 0);
cathodes : out std_logic_vector(7 downto 0)
);
end hex2physical;
architecture Behavioral of hex2physical is
begin
process(hex)
begin
case hex is
when "00000" => cathodes <= "10000001"; -- "0"
when "00001" => cathodes <= "11110011"; -- "1"
when "00010" => cathodes <= "01001001"; -- "2"
when "00011" => cathodes <= "01100001"; -- "3"
when "00100" => cathodes <= "00110011"; -- "4"
when "00101" => cathodes <= "00100101"; -- "5"
when "00110" => cathodes <= "00000101"; -- "6"
when "00111" => cathodes <= "11110001"; -- "7"
when "01000" => cathodes <= "00000001"; -- "8"
when "01001" => cathodes <= "00100001"; -- "9"
when "01010" => cathodes <= "00010001"; -- "A"
when "01011" => cathodes <= "00000111"; -- "B"
when "01100" => cathodes <= "10001101"; -- "C"
when "01101" => cathodes <= "01000011"; -- "D"
when "01110" => cathodes <= "00001101"; -- "E"
when "01111" => cathodes <= "00011101"; -- "F"
when others => cathodes <= "11111111"; -- "Off"
end case;
end process;
end Behavioral;

View File

@@ -57,6 +57,22 @@ package lt16soc_peripherals is
);
end component;
component wb_segment is
generic(
memaddr : generic_addr_type; --:= CFG_BADR_SEG;
addrmask : generic_mask_type --:= CFG_BADR_SEG;
);
port(
clk : in std_logic;
rst : in std_logic;
wslvi : in wb_slv_in_type;
wslvo : out wb_slv_out_type;
anodes : out std_logic_vector(7 downto 0);
cathodes : out std_logic_vector(7 downto 0)
);
end component;
end lt16soc_peripherals;
package body lt16soc_peripherals is

View File

@@ -0,0 +1,137 @@
-- See the file "LICENSE" for the full license governing this code. --
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.lt16x32_global.all;
use work.wishbone.all;
use work.config.all;
entity wb_segment is
generic(
memaddr : generic_addr_type; --:= CFG_BADR_SEG;
addrmask : generic_mask_type --:= CFG_MADR_SEG;
);
port(
clk : in std_logic;
rst : in std_logic;
wslvi : in wb_slv_in_type;
wslvo : out wb_slv_out_type;
anodes : out std_logic_vector(7 downto 0);
cathodes : out std_logic_vector(7 downto 0)
);
end wb_segment;
architecture Behavioral of wb_segment is
signal ack : std_logic;
signal hex_register : std_logic_vector(63 downto 0);
signal data_out : std_logic_vector(63 downto 0);
signal hex : std_logic_vector(4 downto 0);
signal timer_overflow : std_logic;
signal overflow_counter : integer range 0 to 7;
component hex2physical
port(
hex : in std_logic_vector(4 downto 0);
cathodes : out std_logic_vector(7 downto 0)
);
end component;
component simple_timer
generic(
timer_start : std_logic_vector (31 downto 0)
);
port(
clk : in std_logic;
rst : in std_logic;
timer_overflow : out std_logic
);
end component;
begin
converter : hex2physical
port map(
hex => hex,
cathodes => cathodes
);
timer: simple_timer
generic map (timer_start => x"00000008")
port map(
clk => clk,
rst => rst,
timer_overflow => timer_overflow
);
process(clk)
begin
if clk'event and clk='1' then
if rst = '1' then
ack <= '0';
data_out <= (others=>'0');
hex_register <= (others=>'0');
else
data_out <= (others=>'0');
if wslvi.stb = '1' and wslvi.cyc = '1' then
if wslvi.we='0' then
data_out <= hex_register;
else
-- Write enable
if wslvi.adr(2) = '0' then
hex_register(31 downto 0) <= dec_wb_dat(wslvi.sel,wslvi.dat);
else -- wslvi.adr(2) = '1'
hex_register(63 downto 32) <= dec_wb_dat(wslvi.sel,wslvi.dat);
end if;
end if;
if ack = '0' then
ack <= '1';
else
ack <= '0';
end if;
else
ack <= '0';
end if;
end if;
end if;
end process;
process(clk)
begin
if clk'event and clk='1' then
if rst = '1' then
hex <= hex_register(4 downto 0);
anodes <= (others => '0');
overflow_counter <= 0;
else
if timer_overflow = '1' then
if overflow_counter = 7 then
overflow_counter <= 0;
else
overflow_counter <= overflow_counter + 1;
end if;
anodes <= (others => '0');
anodes(overflow_counter) <= '1';
hex <= hex_register(overflow_counter * 8 + 4 downto overflow_counter * 8);
end if;
end if;
end if;
end process;
wslvo.dat <=
data_out(31 downto 0) when wslvi.adr(2) = '0' else
data_out(63 downto 32) when wslvi.adr(2) = '1';
wslvo.ack <= ack;
wslvo.wbcfg <= wb_membar(memaddr, addrmask);
end Behavioral;

View File

@@ -0,0 +1,43 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity simple_timer is
generic(
timer_start : std_logic_vector (31 downto 0)
);
port(
clk : in std_logic;
rst : in std_logic;
timer_overflow : out std_logic
);
end entity simple_timer;
architecture Behavioral of simple_timer is
signal counter : integer range 1 to to_integer(unsigned(timer_start));
signal overflow : std_logic;
begin
process(clk)
begin
if clk'event and clk='1' then
if rst = '1' then
counter <= to_integer(unsigned(timer_start));
else
overflow <= '0';
if counter = 1 then
counter <= to_integer(unsigned(timer_start));
overflow <= '1';
else
counter <= counter - 1;
end if;
end if;
end if;
end process;
timer_overflow <= overflow;
end Behavioral;

View File

@@ -0,0 +1,88 @@
-- See the file "LICENSE" for the full license governing this code. --
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
LIBRARY work;
USE work.lt16soc_peripherals.ALL;
ENTITY hex2physical_tb IS
END ENTITY;
ARCHITECTURE sim OF hex2physical_tb IS
signal hex : std_logic_vector(4 downto 0) := "00000";
signal cathodes : std_logic_vector(7 downto 0);
component hex2physical
port(
hex : in std_logic_vector(4 downto 0);
cathodes : out std_logic_vector(7 downto 0)
);
end component;
BEGIN
converter: hex2physical
port map(
hex => hex,
cathodes => cathodes
);
stimuli: process
begin
hex <= "00000";
wait for 2 ns;
hex <= "00001";
wait for 2 ns;
hex <= "00010";
wait for 2 ns;
hex <= "00011";
wait for 2 ns;
hex <= "00100";
wait for 2 ns;
hex <= "00101";
wait for 2 ns;
hex <= "00110";
wait for 2 ns;
hex <= "00111";
wait for 2 ns;
hex <= "01000";
wait for 2 ns;
hex <= "01001";
wait for 2 ns;
hex <= "01010";
wait for 2 ns;
hex <= "01011";
wait for 2 ns;
hex <= "01100";
wait for 2 ns;
hex <= "01101";
wait for 2 ns;
hex <= "01110";
wait for 2 ns;
hex <= "01111";
wait for 2 ns;
hex <= "10000";
wait for 2 ns;
assert false report "Simulation terminated!" severity failure;
end process stimuli;
END ARCHITECTURE;

View File

@@ -0,0 +1,78 @@
-- See the file "LICENSE" for the full license governing this code. --
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
LIBRARY work;
USE work.lt16soc_peripherals.ALL;
USE work.wishbone.ALL;
USE work.wb_tp.ALL;
USE work.config.ALL;
ENTITY segment_tb IS
END ENTITY;
ARCHITECTURE sim OF segment_tb IS
constant CLK_PERIOD : time := 10 ns;
signal clk : std_logic := '0';
signal rst : std_logic;
signal data : std_logic_vector(31 downto 0);
signal anodes : std_logic_vector(7 downto 0);
signal cathodes : std_logic_vector(7 downto 0);
signal slvi : wb_slv_in_type;
signal slvo : wb_slv_out_type;
BEGIN
SIM_SLV: wb_segment
generic map(
memaddr => CFG_BADR_SEG,
addrmask => CFG_MADR_SEG
)
port map(
clk => clk,
rst => rst,
wslvi => slvi,
wslvo => slvo,
anodes => anodes,
cathodes => cathodes
);
clk_gen: process
begin
clk <= not clk;
wait for CLK_PERIOD/2;
end process clk_gen;
stimuli: process
begin
rst <= '1';
wait for CLK_PERIOD;
rst <= '0';
data <= (others => '0');
data(7 downto 0) <= "000" & "0" & x"A"; -- Unused & !Enable & Value
data(15 downto 8) <= "000" & "0" & x"B"; -- Unused & !Enable & Value
data(23 downto 16) <= "000" & "0" & x"C"; -- Unused & !Enable & Value
data(31 downto 24) <= "000" & "0" & x"D"; -- Unused & !Enable & Value
generate_sync_wb_single_write(slvi,slvo,clk,data);
wait for 10 ns;
data <= (others => '0');
data(7 downto 0) <= "000" & "0" & x"E"; -- Unused & !Enable & Value
data(15 downto 8) <= "000" & "0" & x"F"; -- Unused & !Enable & Value
data(23 downto 16) <= "000" & "0" & x"0"; -- Unused & !Enable & Value
data(31 downto 24) <= "000" & "0" & x"1"; -- Unused & !Enable & Value
generate_sync_wb_single_write(slvi,slvo,clk,data, ADR_OFFSET => 4);
wait for 10 us;
assert false report "Simulation terminated!" severity failure;
end process stimuli;
END ARCHITECTURE;

View File

@@ -0,0 +1,58 @@
-- See the file "LICENSE" for the full license governing this code. --
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
LIBRARY work;
USE work.lt16soc_peripherals.ALL;
ENTITY simple_timer_tb IS
END ENTITY;
ARCHITECTURE sim OF simple_timer_tb IS
constant CLK_PERIOD : time := 10 ns;
signal rst : std_logic;
signal clk : std_logic := '0';
signal overflow : std_logic;
component simple_timer
generic(
timer_start : std_logic_vector (31 downto 0)
);
port(
clk : in std_logic;
rst : in std_logic;
timer_overflow : out std_logic
);
end component;
BEGIN
timer: simple_timer
generic map (timer_start => x"0000001F")
port map(
clk => clk,
rst => rst,
timer_overflow => overflow
);
clk_gen: process
begin
clk <= not clk;
wait for CLK_PERIOD/2;
end process clk_gen;
stimuli: process
begin
rst <= '1';
wait for CLK_PERIOD;
rst <= '0';
wait for 5 us;
assert false report "Simulation terminated!" severity failure;
end process stimuli;
END ARCHITECTURE;

View File

@@ -14,7 +14,7 @@ use work.lt16soc_peripherals.all;
entity lt16soc_top is
generic(
programfilename : string := "../../programs/blinky.ram" -- see "Synthesize XST" process properties for actual value ("-generics" in .xst file)!
programfilename : string := "../../programs/timer_blinky.ram" -- see "Synthesize XST" process properties for actual value ("-generics" in .xst file)!
);
port(
-- clock signal
@@ -25,7 +25,10 @@ port(
led : out std_logic_vector(7 downto 0);
btn : in std_logic_vector(4 downto 0);
sw : in std_logic_vector(15 downto 0)
sw : in std_logic_vector(15 downto 0);
anodes : out std_logic_vector(7 downto 0);
cathodes : out std_logic_vector(7 downto 0)
);
end entity lt16soc_top;
@@ -37,7 +40,7 @@ architecture RTL of lt16soc_top is
signal rst_gen : std_logic;
constant slv_mask_vector : std_logic_vector(0 to NWBSLV-1) := b"1111_1000_0000_0001";
constant slv_mask_vector : std_logic_vector(0 to NWBSLV-1) := b"1111_1100_0000_0001";
constant mst_mask_vector : std_logic_vector(0 to NWBMST-1) := b"1000";
signal slvo : wb_slv_out_vector := (others=> wbs_out_none);
@@ -200,5 +203,20 @@ begin
port map(
clk,rst_gen,slvi(CFG_TIMER),slvo(CFG_TIMER), irq_lines(3)
);
segmentdev : wb_segment
generic map(
memaddr => CFG_BADR_SEG,
addrmask => CFG_MADR_SEG
)
port map(
clk => clk,
rst => rst,
wslvi => slvi(CFG_SEG),
wslvo => slvo(CFG_SEG),
anodes => anodes,
cathodes => cathodes
);
end architecture RTL;

View File

@@ -72,11 +72,11 @@ set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led[7]
##Buttons
set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { rst }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { BTNC }]; #IO_L9P_T1_DQS_14 Sch=btnc
set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { BTNU }]; #IO_L4N_T0_D05_14 Sch=btnu
set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { BTNL }]; #IO_L12P_T1_MRCC_14 Sch=btnl
set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { BTNR }]; #IO_L10N_T1_D15_14 Sch=btnr
set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { BTND }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { btn[0] }]; #IO_L9P_T1_DQS_14 Sch=btnc
set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btn[1] }]; #IO_L4N_T0_D05_14 Sch=btnu
set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btn[2] }]; #IO_L12P_T1_MRCC_14 Sch=btnl
set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btn[3] }]; #IO_L10N_T1_D15_14 Sch=btnr
set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btn[4] }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
##Pmod Headers