commit d07f908273c104b59647b247304308fb229af295
parent aac37b56ff30d051ab324e271fee685b5a03f71d
Author: Martin Klöckner <mjkloeckner@gmail.com>
Date: Sat, 18 Apr 2026 11:29:04 -0300
Update `tps/1/src/*`
Diffstat:
11 files changed, 339 insertions(+), 237 deletions(-)
diff --git a/tps/1/src/intersection_ctrl.vhd b/tps/1/src/intersection_ctrl.vhd
@@ -1,128 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-entity intersection_ctrl is
-
- generic(clk_freq : integer := 1e6); -- default 1 MHz clock frequency
- port(
- clk : in std_logic;
- rst : in std_logic;
-
- red_1 : out std_logic := '1';
- yel_1 : out std_logic := '0';
- gre_1 : out std_logic := '0';
- red_2 : out std_logic := '0';
- yel_2 : out std_logic := '0';
- gre_2 : out std_logic := '1');
-
-end entity;
-
-architecture intersection_ctrl_arq of intersection_ctrl is
-
- constant RED_TIME_MS : integer := 30e3;
- constant YEL_TIME_MS : integer := 3e3;
- constant GRE_TIME_MS : integer := 30e3;
-
- type state_t is(state_0, state_1, state_2, state_3, state_4, state_5);
-
- signal state : state_t := state_0;
- signal clk_ms : std_logic;
- signal ms_tick_cnt : unsigned(31 downto 0) := (others => '0');
-
-begin
-
- rtc : entity work.rtc(rtc_arq)
- generic map(clk_freq => clk_freq)
- port map(
- clk => clk,
- rst => rst,
- clk_ms => clk_ms);
-
- process(rst, clk_ms, ms_tick_cnt, state) is
- begin
-
- if rst = '1' then
- state <= state_0;
- ms_tick_cnt <= (others => '0');
- else
- ms_tick_cnt <= ms_tick_cnt + 1;
- case state is
- when state_0 =>
- if ms_tick_cnt = RED_TIME_MS then
- ms_tick_cnt <= (others => '0');
- state <= state_1;
-
- red_1 <= '1';
- yel_1 <= '0';
- gre_1 <= '0';
- red_2 <= '0';
- yel_2 <= '1';
- gre_2 <= '0';
- end if;
- when state_1 =>
- if ms_tick_cnt = YEL_TIME_MS then
- ms_tick_cnt <= (others => '0');
- state <= state_2;
-
- red_1 <= '1';
- yel_1 <= '1';
- gre_1 <= '0';
- red_2 <= '1';
- yel_2 <= '0';
- gre_2 <= '0';
- end if;
- when state_2 =>
- if ms_tick_cnt = YEL_TIME_MS then
- ms_tick_cnt <= (others => '0');
- state <= state_3;
-
- red_1 <= '0';
- yel_1 <= '0';
- gre_1 <= '1';
- red_2 <= '1';
- yel_2 <= '0';
- gre_2 <= '0';
- end if;
- when state_3 =>
- if ms_tick_cnt = GRE_TIME_MS then
- ms_tick_cnt <= (others => '0');
- state <= state_4;
-
- red_1 <= '0';
- yel_1 <= '1';
- gre_1 <= '0';
- red_2 <= '1';
- yel_2 <= '0';
- gre_2 <= '0';
- end if;
- when state_4 =>
- if ms_tick_cnt = YEL_TIME_MS then
- ms_tick_cnt <= (others => '0');
- state <= state_5;
-
- red_1 <= '1';
- yel_1 <= '0';
- gre_1 <= '0';
- red_2 <= '1';
- yel_2 <= '1';
- gre_2 <= '0';
- end if;
- when state_5 =>
- if ms_tick_cnt = YEL_TIME_MS then
- ms_tick_cnt <= (others => '0');
- state <= state_0;
-
- red_1 <= '1';
- yel_1 <= '0';
- gre_1 <= '0';
- red_2 <= '0';
- yel_2 <= '0';
- gre_2 <= '1';
- end if;
- end case;
- end if;
-
- end process;
-
-end architecture;
diff --git a/tps/1/src/intersection_ctrl_tb.vhd b/tps/1/src/intersection_ctrl_tb.vhd
@@ -1,40 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-entity intersection_ctrl_tb is
-end entity;
-
-architecture intersection_ctrl_tb_arq of intersection_ctrl_tb is
-
- constant CLK_FREQ : integer := 1e6;
-
- signal sig_clk : std_logic := '0';
- signal sig_rst : std_logic := '0';
-
- signal sig_red_1 : std_logic := '0';
- signal sig_yel_1 : std_logic := '0';
- signal sig_gre_1 : std_logic := '0';
-
- signal sig_red_2 : std_logic := '0';
- signal sig_yel_2 : std_logic := '0';
- signal sig_gre_2 : std_logic := '0';
-
-begin
-
- intersection_ctrl : entity work.intersection_ctrl(intersection_ctrl_arq)
- generic map(clk_freq => CLK_FREQ/1e3) -- make sim times smaller (1000 times)
- port map(
- clk => sig_clk,
- rst => sig_rst,
-
- red_1 => sig_red_1,
- yel_1 => sig_yel_1,
- gre_1 => sig_gre_1,
- red_2 => sig_red_2,
- yel_2 => sig_yel_2,
- gre_2 => sig_gre_2);
-
- sig_clk <= not sig_clk after 500 ns; -- one rising edge every 1 us
-
-end architecture;
diff --git a/tps/1/src/rtc.vhd b/tps/1/src/rtc.vhd
@@ -1,42 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-entity rtc is
- generic(clk_freq: integer := 500e3); -- default 1 MHz clock frequency
- port(
- clk : in std_logic;
- rst : in std_logic;
-
- clk_ms : out std_logic);
-end;
-
-architecture rtc_arq of rtc is
-
- signal tick_cnt : unsigned(31 downto 0) := (others => '0');
- signal clk_aux : std_logic := '0';
-
-begin
-
- process(clk, rst)
- begin
-
- if rising_edge(clk) then
- if rst = '1' then
- tick_cnt <= (others => '0');
- clk_aux <= '0';
- else
- tick_cnt <= tick_cnt + 1;
-
- if tick_cnt = (clk_freq - 1)/2e3 then
- tick_cnt <= (others => '0');
- clk_aux <= not clk_aux;
- end if;
- end if;
- end if;
-
- end process;
-
- clk_ms <= clk_aux;
-
-end architecture;
diff --git a/tps/1/src/rtc_tb.vhd b/tps/1/src/rtc_tb.vhd
@@ -1,27 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-entity rtc_tb is
-end entity;
-
-architecture rtc_arq of rtc_tb is
-
- constant CLK_FREQ : integer := 1e6; -- 1 MHz clock frecuency
-
- signal sig_clk : std_logic := '1';
- signal sig_rst : std_logic := '0';
- signal sig_clk_ms : std_logic;
-
-begin
-
- rtc : entity work.rtc(rtc_arq)
- generic map(clk_freq => CLK_FREQ)
- port map(
- clk => sig_clk,
- rst => sig_rst,
- clk_ms => sig_clk_ms);
-
- sig_clk <= not sig_clk after 500 ns; -- 1 MHz clock frequency
-
-end architecture;
diff --git a/tps/1/src/rtl/cnt.vhd b/tps/1/src/rtl/cnt.vhd
@@ -0,0 +1,64 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.semaphore_pkg.all;
+
+entity cnt is
+ port(
+ clk : in std_logic;
+ rst : in std_logic;
+ ena : in std_logic;
+ state : in state_t;
+
+ state_flag : out std_logic);
+end;
+
+architecture cnt_arq of cnt is
+
+ constant YELLOW_S : unsigned(5 downto 0) := to_unsigned(3, 6);
+ constant RED_GREEN_S : unsigned(5 downto 0) := to_unsigned(30, 6);
+ signal tick_cnt : unsigned(5 downto 0);
+
+begin
+
+ process(clk, rst)
+ begin
+
+ if rst = '1' then
+
+ tick_cnt <= (others => '0');
+
+ elsif rising_edge(clk) then
+
+ if ena = '1' then
+ if state /= state_1r_2g and state /= state_1g_2r then
+ if tick_cnt = YELLOW_S - 1 then
+ tick_cnt <= (others => '0');
+
+ else
+ tick_cnt <= tick_cnt + 1;
+ end if;
+
+ else
+ if tick_cnt = RED_GREEN_S - 1 then
+ tick_cnt <= (others => '0');
+ else
+ tick_cnt <= tick_cnt + 1;
+ end if;
+ end if;
+
+ end if;
+
+ end if;
+
+ end process;
+
+ state_flag <= '1' when state /= state_1r_2g and
+ state /= state_1g_2r and
+ tick_cnt = YELLOW_S - 1 and ena = '1'
+ else
+ '1' when tick_cnt = RED_GREEN_S - 1 and ena = '1'
+ else '0';
+
+end architecture;
diff --git a/tps/1/src/rtl/intersection_ctrl.vhd b/tps/1/src/rtl/intersection_ctrl.vhd
@@ -0,0 +1,59 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use work.semaphore_pkg.all;
+
+entity intersection_ctrl is
+
+ generic(MAX_CNT : integer := 50e6);
+ port(
+ clk : in std_logic;
+ rst : in std_logic;
+
+ red_1 : out std_logic;
+ yel_1 : out std_logic;
+ gre_1 : out std_logic;
+ red_2 : out std_logic;
+ yel_2 : out std_logic;
+ gre_2 : out std_logic);
+
+end entity;
+
+architecture intersection_ctrl_arq of intersection_ctrl is
+
+ signal state : state_t;
+ signal seg_flag : std_logic;
+ signal state_flag : std_logic;
+
+begin
+
+ rtc : entity work.rtc(rtc_arq)
+ generic map(MAX_CNT => MAX_CNT)
+ port map(
+ clk => clk,
+ rst => rst,
+ seg_flag => seg_flag);
+
+ cnt : entity work.cnt(cnt_arq)
+ port map(
+ clk => clk,
+ rst => rst,
+ ena => seg_flag,
+ state => state,
+ state_flag => state_flag);
+
+ semaphore : entity work.semaphore(semaphore_arq)
+ port map(
+ clk => clk,
+ rst => rst,
+ state_flag => state_flag,
+
+ red_1 => red_1,
+ yel_1 => yel_1,
+ gre_1 => gre_1,
+ red_2 => red_2,
+ yel_2 => yel_2,
+ gre_2 => gre_2,
+
+ state => state);
+
+end architecture;
diff --git a/tps/1/src/rtl/rtc.vhd b/tps/1/src/rtl/rtc.vhd
@@ -0,0 +1,50 @@
+library ieee;
+use ieee.math_real.all;
+
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+entity rtc is
+ generic(MAX_CNT: integer := 50e6);
+ port(
+ clk : in std_logic;
+ rst : in std_logic;
+
+ seg_flag : out std_logic);
+end;
+
+architecture rtc_arq of rtc is
+
+ constant BITS : integer := integer(ceil(log2(real(MAX_CNT))));
+ signal tick_cnt : unsigned(BITS-1 downto 0);
+
+begin
+
+ process(clk, rst)
+ begin
+
+ if rst = '1' then
+
+ tick_cnt <= (others => '0');
+ seg_flag <= '0';
+
+ elsif rising_edge(clk) then
+
+ if tick_cnt = MAX_CNT - 1 then
+ tick_cnt <= (others => '0');
+ else
+ tick_cnt <= tick_cnt + 1;
+ end if;
+
+ if tick_cnt = MAX_CNT - 2 then
+ seg_flag <= '1';
+ else
+ seg_flag <= '0';
+ end if;
+
+ end if;
+
+ end process;
+
+end architecture;
diff --git a/tps/1/src/rtl/semaphore.vhd b/tps/1/src/rtl/semaphore.vhd
@@ -0,0 +1,88 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use work.semaphore_pkg.all;
+
+entity semaphore is
+
+ generic(clk_freq : integer := 1e6); -- default 1 MHz clock frequency
+ port(
+ clk : in std_logic;
+ rst : in std_logic;
+ state_flag : in std_logic;
+
+ red_1 : out std_logic;
+ yel_1 : out std_logic;
+ gre_1 : out std_logic;
+ red_2 : out std_logic;
+ yel_2 : out std_logic;
+ gre_2 : out std_logic;
+ state : out state_t);
+
+end entity;
+
+architecture semaphore_arq of semaphore is
+
+ -- R1 Y1 G1 R2 Y2 G2
+ signal light : std_logic_vector(5 downto 0);
+
+ signal state_aux : state_t;
+
+begin
+
+ process(rst, clk) is
+ begin
+
+ if rst = '1' then
+ state_aux <= state_1r_2g;
+ elsif rising_edge(clk) then
+
+ case state_aux is
+ when state_1r_2g =>
+ if state_flag = '1' then
+ state_aux <= state_1r_2y;
+ end if;
+ when state_1r_2y =>
+ if state_flag = '1' then
+ state_aux <= state_1ry_2r;
+ end if;
+ when state_1ry_2r =>
+ if state_flag = '1' then
+ state_aux <= state_1g_2r;
+ end if;
+ when state_1g_2r =>
+ if state_flag = '1' then
+ state_aux <= state_1y_2r;
+ end if;
+ when state_1y_2r =>
+ if state_flag = '1' then
+ state_aux <= state_1r_2ry;
+ end if;
+ when state_1r_2ry=>
+ if state_flag = '1' then
+ state_aux <= state_1r_2g;
+ end if;
+ end case;
+
+ end if;
+
+ end process;
+
+ state <= state_aux;
+
+ -- R1 Y1 G1 R2 Y2 G2
+ with state_aux select light <=
+ "100001" when state_1r_2g,
+ "100010" when state_1r_2y,
+ "010100" when state_1ry_2r,
+ "001100" when state_1g_2r,
+ "010010" when state_1y_2r,
+ "100010" when state_1r_2ry;
+
+ red_1 <= light(5);
+ yel_1 <= light(4);
+ gre_1 <= light(3);
+ red_2 <= light(2);
+ yel_2 <= light(1);
+ gre_2 <= light(0);
+
+end architecture;
diff --git a/tps/1/src/rtl/semaphore_pkg.vhd b/tps/1/src/rtl/semaphore_pkg.vhd
@@ -0,0 +1,11 @@
+package semaphore_pkg is
+
+type state_t is(
+ state_1r_2g,
+ state_1r_2y,
+ state_1ry_2r,
+ state_1g_2r,
+ state_1y_2r,
+ state_1r_2ry);
+
+end semaphore_pkg;
diff --git a/tps/1/src/tb/intersection_ctrl_tb.vhd b/tps/1/src/tb/intersection_ctrl_tb.vhd
@@ -0,0 +1,40 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity intersection_ctrl_tb is
+end entity;
+
+architecture intersection_ctrl_tb_arq of intersection_ctrl_tb is
+
+ constant MAX_CNT : integer := 5;
+
+ signal sig_clk : std_logic := '0';
+ signal sig_rst : std_logic := '0';
+
+ signal sig_red_1 : std_logic := '0';
+ signal sig_yel_1 : std_logic := '0';
+ signal sig_gre_1 : std_logic := '0';
+
+ signal sig_red_2 : std_logic := '0';
+ signal sig_yel_2 : std_logic := '0';
+ signal sig_gre_2 : std_logic := '0';
+
+begin
+
+ intersection_ctrl : entity work.intersection_ctrl(intersection_ctrl_arq)
+ generic map(MAX_CNT => MAX_CNT)
+ port map(
+ clk => sig_clk,
+ rst => sig_rst,
+
+ red_1 => sig_red_1,
+ yel_1 => sig_yel_1,
+ gre_1 => sig_gre_1,
+ red_2 => sig_red_2,
+ yel_2 => sig_yel_2,
+ gre_2 => sig_gre_2);
+
+ sig_clk <= not sig_clk after 5 ns;
+ sig_rst <= '1' after 1 ns, '0' after 2 ns;
+
+end architecture;
diff --git a/tps/1/src/tb/rtc_tb.vhd b/tps/1/src/tb/rtc_tb.vhd
@@ -0,0 +1,27 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity rtc_tb is
+end entity;
+
+architecture rtc_arq of rtc_tb is
+
+ constant CLK_FREQ : integer := 1e6; -- 1 MHz clock frecuency
+
+ signal sig_clk : std_logic := '1';
+ signal sig_rst : std_logic := '0';
+ signal sig_seg_flag : std_logic;
+
+begin
+
+ rtc : entity work.rtc(rtc_arq)
+ generic map(clk_freq => CLK_FREQ)
+ port map(
+ clk => sig_clk,
+ rst => sig_rst,
+ seg_flag => sig_seg_flag);
+
+ sig_clk <= not sig_clk after 500 ns; -- 1 MHz clock frequency
+
+end architecture;