TA147

Ejecicios y trabajos prácticos de la materia Taller de Sistemas Digitales (TA147)
Index Commits Files Refs
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:
Dtps/1/src/intersection_ctrl.vhd | 128-------------------------------------------------------------------------------
Dtps/1/src/intersection_ctrl_tb.vhd | 40----------------------------------------
Dtps/1/src/rtc.vhd | 42------------------------------------------
Dtps/1/src/rtc_tb.vhd | 27---------------------------
Atps/1/src/rtl/cnt.vhd | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atps/1/src/rtl/intersection_ctrl.vhd | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atps/1/src/rtl/rtc.vhd | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Atps/1/src/rtl/semaphore.vhd | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atps/1/src/rtl/semaphore_pkg.vhd | 11+++++++++++
Atps/1/src/tb/intersection_ctrl_tb.vhd | 40++++++++++++++++++++++++++++++++++++++++
Atps/1/src/tb/rtc_tb.vhd | 27+++++++++++++++++++++++++++
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;