TA147

Ejecicios y trabajos prácticos de la materia Taller de Sistemas Digitales (TA147)
Index Commits Files Refs
commit 28638b6678ea5d28494b0178debf7927ca6dff46
parent d8c7f977087dfb32e0af2856c0eabe208bb7d705
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date:   Fri, 17 Apr 2026 16:03:44 -0300

Add `tps/1/*`

Diffstat:
Atps/1/src/Makefile | 24++++++++++++++++++++++++
Atps/1/src/intersection_ctrl.vhd | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atps/1/src/intersection_ctrl_tb.vhd | 40++++++++++++++++++++++++++++++++++++++++
Atps/1/src/rtc.vhd | 42++++++++++++++++++++++++++++++++++++++++++
Atps/1/src/rtc_tb.vhd | 27+++++++++++++++++++++++++++
5 files changed, 246 insertions(+), 0 deletions(-)
diff --git a/tps/1/src/Makefile b/tps/1/src/Makefile
@@ -0,0 +1,24 @@
+GHDL          = ghdl
+DEV_NAME      = intersection_ctrl
+TOP           = $(DEV_NAME)_tb
+TOP_SRC       = $(TOP).vhd
+SRCS          = rtc.vhd rtc_tb.vhd intersection_ctrl.vhd intersection_ctrl_tb.vhd 
+WAVEFORM_FILE = $(TOP).vcd
+
+all: run
+
+analyze:
+    $(GHDL) -a $(SRCS)
+    $(GHDL) -a $(TOP_SRC)
+
+elaborate: analyze
+    $(GHDL) -e $(TOP)
+
+run: elaborate
+    $(GHDL) -r $(TOP) --vcd=$(WAVEFORM_FILE) --stop-time=100ms
+
+clean:
+    rm -f *.o *.cf $(TOP) $(TOP).vcd
+
+view: all
+    nohup surfer $(WAVEFORM_FILE) >/dev/null 2>&1 &
diff --git a/tps/1/src/intersection_ctrl.vhd b/tps/1/src/intersection_ctrl.vhd
@@ -0,0 +1,113 @@
+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);
+
+    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(clk_ms, rst) 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 <= '1';
+                        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 <= '0';
+                        yel_1 <= '0';
+                        gre_1 <= '1';
+                        red_2 <= '1';
+                        yel_2 <= '0';
+                        gre_2 <= '0';
+
+                    end if;
+                when state_2 =>
+                    if ms_tick_cnt = GRE_TIME_MS then
+
+                        ms_tick_cnt <= (others => '0');
+                        state <= state_3;
+
+                        red_1 <= '0';
+                        yel_1 <= '1';
+                        gre_1 <= '0';
+                        red_2 <= '1';
+                        yel_2 <= '1';
+                        gre_2 <= '0';
+
+                    end if;
+                when state_3 =>
+                    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
@@ -0,0 +1,40 @@
+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
@@ -0,0 +1,42 @@
+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
@@ -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_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;