Add seven-segments module and integrate it into the top level
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
42
soc/peripheral/hex2physical.vhd
Normal file
42
soc/peripheral/hex2physical.vhd
Normal 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;
|
||||
@@ -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
|
||||
|
||||
137
soc/peripheral/seven_segment_display.vhd
Normal file
137
soc/peripheral/seven_segment_display.vhd
Normal 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;
|
||||
43
soc/peripheral/simple_timer.vhd
Normal file
43
soc/peripheral/simple_timer.vhd
Normal 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;
|
||||
88
soc/testbench/hex2physical_tb.vhd
Normal file
88
soc/testbench/hex2physical_tb.vhd
Normal 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;
|
||||
78
soc/testbench/segment_tb.vhd
Normal file
78
soc/testbench/segment_tb.vhd
Normal 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;
|
||||
58
soc/testbench/simple_timer_tb.vhd
Normal file
58
soc/testbench/simple_timer_tb.vhd
Normal 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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user