Line 108... |
Line 108... |
constant lo_abb_c : natural := index_size_f(uart_id_size_c); -- low address boundary bit
|
constant lo_abb_c : natural := index_size_f(uart_id_size_c); -- low address boundary bit
|
|
|
-- simulation output configuration --
|
-- simulation output configuration --
|
constant sim_screen_output_en_c : boolean := true; -- output lowest byte as char to simulator console when enabled
|
constant sim_screen_output_en_c : boolean := true; -- output lowest byte as char to simulator console when enabled
|
constant sim_text_output_en_c : boolean := true; -- output lowest byte as char to text file when enabled
|
constant sim_text_output_en_c : boolean := true; -- output lowest byte as char to text file when enabled
|
constant sim_data_output_en_c : boolean := true; -- dump 32-word to file when enabled
|
constant sim_data_output_en_c : boolean := true; -- dump 32-bit TX word to file when enabled
|
constant sim_uart_text_file_c : string := cond_sel_string_f(UART_PRIMARY, "neorv32.uart0.sim_mode.text.out", "neorv32.uart1.sim_mode.text.out");
|
constant sim_uart_text_file_c : string := cond_sel_string_f(UART_PRIMARY, "neorv32.uart0.sim_mode.text.out", "neorv32.uart1.sim_mode.text.out");
|
constant sim_uart_data_file_c : string := cond_sel_string_f(UART_PRIMARY, "neorv32.uart0.sim_mode.data.out", "neorv32.uart1.sim_mode.data.out");
|
constant sim_uart_data_file_c : string := cond_sel_string_f(UART_PRIMARY, "neorv32.uart0.sim_mode.data.out", "neorv32.uart1.sim_mode.data.out");
|
|
|
-- control register --
|
-- control register --
|
signal ctrl : std_ulogic_vector(31 downto 0);
|
signal ctrl : std_ulogic_vector(31 downto 0);
|
Line 168... |
Line 168... |
|
|
-- clock generator --
|
-- clock generator --
|
signal uart_clk : std_ulogic;
|
signal uart_clk : std_ulogic;
|
|
|
-- numbers of bits in transmission frame --
|
-- numbers of bits in transmission frame --
|
signal num_bits : std_ulogic_vector(03 downto 0);
|
signal num_bits : std_ulogic_vector(3 downto 0);
|
|
|
-- hardware flow-control IO buffer --
|
-- hardware flow-control IO buffer --
|
signal uart_cts_ff : std_ulogic_vector(1 downto 0);
|
signal uart_cts_ff : std_ulogic_vector(1 downto 0);
|
signal uart_rts : std_ulogic;
|
signal uart_rts : std_ulogic;
|
|
|
Line 396... |
Line 396... |
end if;
|
end if;
|
|
|
when S_TX_TRANSMIT => -- transmit data
|
when S_TX_TRANSMIT => -- transmit data
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
if (uart_clk = '1') then
|
if (uart_clk = '1') then
|
if (tx_engine.baud_cnt = x"000") then
|
if (or_reduce_f(tx_engine.baud_cnt) = '0') then -- bit done?
|
tx_engine.baud_cnt <= ctrl(ctrl_baud11_c downto ctrl_baud00_c);
|
tx_engine.baud_cnt <= ctrl(ctrl_baud11_c downto ctrl_baud00_c);
|
tx_engine.bitcnt <= std_ulogic_vector(unsigned(tx_engine.bitcnt) - 1);
|
tx_engine.bitcnt <= std_ulogic_vector(unsigned(tx_engine.bitcnt) - 1);
|
tx_engine.sreg <= '1' & tx_engine.sreg(tx_engine.sreg'left downto 1);
|
tx_engine.sreg <= '1' & tx_engine.sreg(tx_engine.sreg'left downto 1);
|
else
|
else
|
tx_engine.baud_cnt <= std_ulogic_vector(unsigned(tx_engine.baud_cnt) - 1);
|
tx_engine.baud_cnt <= std_ulogic_vector(unsigned(tx_engine.baud_cnt) - 1);
|
end if;
|
end if;
|
end if;
|
end if;
|
uart_txd_o <= tx_engine.sreg(0);
|
uart_txd_o <= tx_engine.sreg(0);
|
if (tx_engine.bitcnt = "0000") then -- all bits send?
|
if (or_reduce_f(tx_engine.bitcnt) = '0') then -- all bits send?
|
tx_engine.state <= S_TX_IDLE;
|
tx_engine.state <= S_TX_IDLE;
|
end if;
|
end if;
|
|
|
when S_TX_SIM => -- simulation mode output
|
when S_TX_SIM => -- simulation mode output
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
Line 432... |
Line 432... |
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
uart_rx_engine: process(clk_i)
|
uart_rx_engine: process(clk_i)
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
-- input synchronizer --
|
-- input synchronizer --
|
rx_engine.sync <= uart_rxd_i & rx_engine.sync(4 downto 1);
|
rx_engine.sync <= uart_rxd_i & rx_engine.sync(rx_engine.sync'left downto 1);
|
|
|
-- FSM --
|
-- FSM --
|
if (ctrl(ctrl_en_c) = '0') then -- disabled
|
if (ctrl(ctrl_en_c) = '0') then -- disabled
|
rx_engine.overr <= '0';
|
rx_engine.overr <= '0';
|
rx_engine.state <= S_RX_IDLE;
|
rx_engine.state <= S_RX_IDLE;
|
Line 445... |
Line 445... |
|
|
when S_RX_IDLE => -- idle; prepare receive
|
when S_RX_IDLE => -- idle; prepare receive
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
rx_engine.baud_cnt <= '0' & ctrl(ctrl_baud11_c downto ctrl_baud01_c); -- half baud delay at the beginning to sample in the middle of each bit
|
rx_engine.baud_cnt <= '0' & ctrl(ctrl_baud11_c downto ctrl_baud01_c); -- half baud delay at the beginning to sample in the middle of each bit
|
rx_engine.bitcnt <= num_bits;
|
rx_engine.bitcnt <= num_bits;
|
if (rx_engine.sync(2 downto 0) = "001") then -- start bit? (falling edge)
|
if (rx_engine.sync(3 downto 0) = "0011") then -- start bit? (falling edge)
|
rx_engine.state <= S_RX_RECEIVE;
|
rx_engine.state <= S_RX_RECEIVE;
|
end if;
|
end if;
|
|
|
when S_RX_RECEIVE => -- receive data
|
when S_RX_RECEIVE => -- receive data
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
if (uart_clk = '1') then
|
if (uart_clk = '1') then
|
if (rx_engine.baud_cnt = x"000") then
|
if (or_reduce_f(rx_engine.baud_cnt) = '0') then -- bit done
|
rx_engine.baud_cnt <= ctrl(ctrl_baud11_c downto ctrl_baud00_c);
|
rx_engine.baud_cnt <= ctrl(ctrl_baud11_c downto ctrl_baud00_c);
|
rx_engine.bitcnt <= std_ulogic_vector(unsigned(rx_engine.bitcnt) - 1);
|
rx_engine.bitcnt <= std_ulogic_vector(unsigned(rx_engine.bitcnt) - 1);
|
rx_engine.sreg <= rx_engine.sync(0) & rx_engine.sreg(rx_engine.sreg'left downto 1);
|
rx_engine.sreg <= rx_engine.sync(2) & rx_engine.sreg(rx_engine.sreg'left downto 1);
|
else
|
else
|
rx_engine.baud_cnt <= std_ulogic_vector(unsigned(rx_engine.baud_cnt) - 1);
|
rx_engine.baud_cnt <= std_ulogic_vector(unsigned(rx_engine.baud_cnt) - 1);
|
end if;
|
end if;
|
end if;
|
end if;
|
if (rx_engine.bitcnt = "0000") then -- all bits received?
|
if (or_reduce_f(rx_engine.bitcnt) = '0') then -- all bits received?
|
rx_engine.state <= S_RX_IDLE;
|
rx_engine.state <= S_RX_IDLE;
|
end if;
|
end if;
|
|
|
when others => -- undefined
|
when others => -- undefined
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|