summaryrefslogtreecommitdiffstats
path: root/PIC/uart.vhd
diff options
context:
space:
mode:
authorVaino Kauppila <vaino@vke.fi>2026-04-19 12:32:58 +0300
committerVaino Kauppila <vaino@vke.fi>2026-04-19 12:32:58 +0300
commiteb8643ddbef43547eb7bfe58789a3908926c7258 (patch)
treefadfba88a1c71b266b8c67df166a3a6ead6b30d1 /PIC/uart.vhd
parent129a1c975dbd0c042576010b1f6eb40d19fc5733 (diff)
downloadvhdl_pic-eb8643ddbef43547eb7bfe58789a3908926c7258.tar.gz
vhdl_pic-eb8643ddbef43547eb7bfe58789a3908926c7258.zip
refactor dir structure, add fib.c
Diffstat (limited to 'PIC/uart.vhd')
-rw-r--r--PIC/uart.vhd195
1 files changed, 0 insertions, 195 deletions
diff --git a/PIC/uart.vhd b/PIC/uart.vhd
deleted file mode 100644
index a0fad93..0000000
--- a/PIC/uart.vhd
+++ /dev/null
@@ -1,195 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
--- TX: fire and forget (8E1)
--- RX: FIFO-backed (8E1), consumer reads via rd_en/rx_data/rx_empty
-
-entity uart is
- generic (
- CLK_FREQ : positive := 50_000_000;
- BAUD_RATE : positive := 115_200;
- CLKS_PER_BIT : positive := CLK_FREQ / BAUD_RATE
- );
- port (
- clk : in std_logic;
- -- TX
- tx_should_send : in std_logic;
- byte_in : in std_logic_vector(7 downto 0);
- tx_done : out std_logic;
- baud_tick : out std_logic;
- uart_tx : out std_logic;
- -- RX
- uart_rx : in std_logic;
- rd_en : in std_logic;
- rx_data : out std_logic_vector(7 downto 0);
- rx_empty : out std_logic;
- rx_full : out std_logic
- );
-end entity uart;
-
-architecture rtl of uart is
-
- signal baud_counter : std_logic_vector(15 downto 0)
- := (others => '0');
- signal baud_tick_i : std_logic := '0';
-
- signal tx_out : std_logic := '1';
- signal current_byte : std_logic_vector(7 downto 0) := (others => '0');
- signal tx_byte_latch : std_logic_vector(7 downto 0) := (others => '0');
-
- -- RX input synchronizer (2FF, idle state is '1')
- signal uart_rx_meta : std_logic := '1';
- signal uart_rx_sync : std_logic := '1';
-
- -- RX FIFO wiring
- signal fifo_wr_en : std_logic := '0';
- signal fifo_din : std_logic_vector(7 downto 0)
- := (others => '0');
- signal fifo_full : std_logic := '0';
-
-begin
-
- uart_tx <= tx_out;
- baud_tick <= baud_tick_i;
-
- rx_fifo : entity work.fifo
- generic map (DEPTH => 64, ADDR_BITS => 6, WIDTH => 8)
- port map (
- clk => clk,
- wr_en => fifo_wr_en,
- rd_en => rd_en,
- din => fifo_din,
- dout => rx_data,
- full => fifo_full,
- empty => rx_empty
- );
-
- rx_full <= fifo_full;
-
- uart_rx_synchronizer : process(clk)
- begin
- if rising_edge(clk) then
- uart_rx_meta <= uart_rx;
- uart_rx_sync <= uart_rx_meta;
- end if;
- end process uart_rx_synchronizer;
-
- uart_baud_timer : process(clk)
- begin
- if rising_edge(clk) then
- if unsigned(baud_counter) = CLKS_PER_BIT - 1 then
- baud_counter <= (others => '0');
- baud_tick_i <= '1';
- else
- baud_counter <= std_logic_vector(unsigned(baud_counter) + 1);
- baud_tick_i <= '0';
- end if;
- end if;
- end process uart_baud_timer;
-
- uart_transmit_byte : process(clk)
- type t_state is (idle, start, data, parity, stop);
- variable state : t_state := idle;
- variable bit_index : unsigned(2 downto 0);
- variable parity_value : std_logic;
- begin
- if rising_edge(clk) then
- tx_done <= '0';
- if baud_tick_i = '1' then
- case state is
- when idle =>
- if tx_should_send = '1' then
- tx_out <= '0'; -- start bit immediately
- tx_byte_latch <= byte_in; -- latch byte now
- parity_value := '0';
- bit_index := (others => '0');
- state := data;
- end if;
- when start =>
- null; -- unused, kept for completeness
- when data =>
- tx_out <= tx_byte_latch(to_integer(bit_index));
- parity_value := parity_value xor tx_byte_latch(to_integer(bit_index));
- if bit_index = 7 then
- state := parity;
- else
- state := data;
- end if;
- bit_index := bit_index + 1;
- when parity =>
- tx_out <= parity_value;
- state := stop;
- when stop =>
- tx_out <= '1';
- tx_done <= '1';
- state := idle;
- end case;
- end if;
- end if;
- end process uart_transmit_byte;
-
- uart_receive_byte : process(clk)
- type rx_state_t is (idle, start, data, parity, stop);
- variable state : rx_state_t := idle;
- variable bit_index : unsigned(2 downto 0);
- variable rx_byte : std_logic_vector(7 downto 0);
- variable parity_val : std_logic;
- variable rx_counter : unsigned(15 downto 0);
- begin
- if rising_edge(clk) then
- fifo_wr_en <= '0';
- case state is
- when idle =>
- if uart_rx_sync = '0' then
- rx_counter := to_unsigned(CLKS_PER_BIT / 2, 16);
- state := start;
- end if;
- when start =>
- if rx_counter = 0 then
- if uart_rx_sync = '0' then
- rx_counter := to_unsigned(CLKS_PER_BIT - 1, 16);
- bit_index := (others => '0');
- parity_val := '0';
- state := data;
- else
- state := idle;
- end if;
- else
- rx_counter := rx_counter - 1;
- end if;
- when data =>
- if rx_counter = 0 then
- rx_byte(to_integer(bit_index)) := uart_rx_sync;
- parity_val := parity_val xor uart_rx_sync;
- rx_counter := to_unsigned(CLKS_PER_BIT - 1, 16);
- if bit_index = 7 then
- state := parity;
- else
- bit_index := bit_index + 1;
- end if;
- else
- rx_counter := rx_counter - 1;
- end if;
- when parity =>
- if rx_counter = 0 then
- rx_counter := to_unsigned(CLKS_PER_BIT - 1, 16);
- state := stop;
- else
- rx_counter := rx_counter - 1;
- end if;
- when stop =>
- if rx_counter = 0 then
- if uart_rx_sync = '1' and fifo_full = '0' then
- fifo_din <= rx_byte;
- fifo_wr_en <= '1';
- end if;
- state := idle;
- else
- rx_counter := rx_counter - 1;
- end if;
- end case;
- end if;
- end process uart_receive_byte;
-
-end architecture rtl;