Line 4... |
Line 4... |
|
|
--! Use CPU Definitions package
|
--! Use CPU Definitions package
|
use work.pkgDefinitions.all;
|
use work.pkgDefinitions.all;
|
|
|
entity uart_control is
|
entity uart_control is
|
Port ( rst : in STD_LOGIC;
|
Port ( rst : in STD_LOGIC; -- Global reset
|
clk : in STD_LOGIC;
|
clk : in STD_LOGIC; -- Global clock
|
WE : in STD_LOGIC;
|
WE : in STD_LOGIC; -- Write enable
|
reg_addr : in STD_LOGIC_VECTOR (1 downto 0);
|
reg_addr : in STD_LOGIC_VECTOR (1 downto 0); -- Register address
|
DAT_I : in STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
start : in std_logic; -- Start (Strobe)
|
DAT_O : out STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0);
|
done : out std_logic; -- Done (ACK)
|
tx_busy : in STD_LOGIC;
|
DAT_I : in STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0); -- Data Input (Wishbone)
|
rx_ready : in STD_LOGIC);
|
DAT_O : out STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0); -- Data output (Wishbone)
|
|
baud_wait : out STD_LOGIC_VECTOR ((nBitsLarge-1) downto 0); -- Signal to control the baud rate frequency
|
|
data_byte_tx : out std_logic_vector((nBits-1) downto 0); -- 1 Byte to be send to serial_transmitter
|
|
data_byte_rx : in std_logic_vector((nBits-1) downto 0); -- 1 Byte to be received by serial_receiver
|
|
tx_data_sent : in STD_LOGIC; -- Signal comming from serial_transmitter
|
|
rx_data_ready : in STD_LOGIC); -- Signal comming from serial_receiver
|
end uart_control;
|
end uart_control;
|
|
|
architecture Behavioral of uart_control is
|
architecture Behavioral of uart_control is
|
signal config_clk : std_logic_vector((nBitsLarge-1) downto 0);
|
signal config_clk : std_logic_vector((nBitsLarge-1) downto 0);
|
signal config_baud : std_logic_vector((nBitsLarge-1) downto 0);
|
signal config_baud : std_logic_vector((nBitsLarge-1) downto 0);
|
signal byte_out : std_logic_vector((nBitsLarge-1) downto 0);
|
signal byte_to_receive : std_logic_vector((nBitsLarge-1) downto 0);
|
signal byte_in : std_logic_vector((nBitsLarge-1) downto 0);
|
signal byte_to_transmitt : std_logic_vector((nBitsLarge-1) downto 0);
|
signal controlStates : uartControl;
|
signal controlStates : uartControl;
|
|
|
signal sigDivRst : std_logic;
|
signal sigDivRst : std_logic;
|
signal sigDivDone : std_logic;
|
signal sigDivDone : std_logic;
|
signal sigDivQuotient : std_logic_vector((nBitsLarge-1) downto 0);
|
signal sigDivQuotient : std_logic_vector((nBitsLarge-1) downto 0);
|
Line 51... |
Line 56... |
numerator => sigDivNumerator,
|
numerator => sigDivNumerator,
|
divident => sigDivDividend,
|
divident => sigDivDividend,
|
done => sigDivDone
|
done => sigDivDone
|
);
|
);
|
|
|
-- Process that populate/read the uart control registers
|
-- Process that read uart control registers
|
|
process (rst, clk, reg_addr,WE)
|
|
begin
|
|
if rising_edge(clk) then
|
|
if (WE = '0') and (start = '1') then
|
|
case reg_addr is
|
|
when "00" =>
|
|
DAT_O <= config_clk;
|
|
when "01" =>
|
|
DAT_O <= config_baud;
|
|
when "10" =>
|
|
-- Byte that will be transmitted
|
|
DAT_O <= "0000000000000000000000000" & byte_to_transmitt;
|
|
when "11" =>
|
|
-- Byte that will be received
|
|
DAT_O <= "0000000000000000000000000" & byte_to_receive;
|
|
when others =>
|
|
null;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- Process that populate the uart control registers
|
process (rst, clk, reg_addr,WE)
|
process (rst, clk, reg_addr,WE)
|
begin
|
begin
|
if rst = '1' then
|
if rst = '1' then
|
config_clk <= (others => '0');
|
config_clk <= (others => '0');
|
config_baud <= (others => '0');
|
config_baud <= (others => '0');
|
byte_out <= (others => '0');
|
byte_to_transmitt <= (others => '0');
|
byte_in <= (others => '0');
|
byte_to_receive <= (others => '0');
|
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
if WE = '1' then
|
if (WE = '1') and (start = '1') then
|
case reg_addr is
|
case reg_addr is
|
when "00" =>
|
when "00" =>
|
config_clk <= DAT_I;
|
config_clk <= DAT_I;
|
when "01" =>
|
when "01" =>
|
config_baud <= DAT_I;
|
config_baud <= DAT_I;
|
when "10" =>
|
when "10" =>
|
byte_out <= DAT_I((nBits-1) downto 0);
|
-- Byte that will be transmitted
|
|
byte_to_transmitt <= DAT_I((nBits-1) downto 0);
|
when others =>
|
when others =>
|
null;
|
null;
|
end case;
|
end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
Line 79... |
Line 108... |
|
|
-- Process to handle the next state logic
|
-- Process to handle the next state logic
|
process (rst, clk, reg_addr, WE)
|
process (rst, clk, reg_addr, WE)
|
variable baud_configured : std_logic;
|
variable baud_configured : std_logic;
|
variable clk_configured : std_logic;
|
variable clk_configured : std_logic;
|
|
variable div_result_baud_wait : std_logic_vector ((nBitsLarge-1) downto 0);
|
begin
|
begin
|
if rst = '1' then
|
if rst = '1' then
|
controlStates <= idle;
|
controlStates <= idle;
|
baud_configured <= '0';
|
baud_configured <= '0';
|
clk_configured <= '0';
|
clk_configured <= '0';
|
|
div_result_baud_wait <= (others => '0');
|
|
done <= '0';
|
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
case controlStates is
|
case controlStates is
|
when idle =>
|
when idle =>
|
|
done <= '0';
|
-- Go to config state
|
-- Go to config state
|
if (reg_addr = "00") and (WE = '1') then
|
if (reg_addr = "00") and (WE = '1') then
|
controlStates <= config_state_clk;
|
controlStates <= config_state_clk;
|
clk_configured <= '1';
|
clk_configured <= '1';
|
elsif (reg_addr = "01") and (WE = '1') then
|
elsif (reg_addr = "01") and (WE = '1') then
|
Line 102... |
Line 135... |
sigDivRst <= '1';
|
sigDivRst <= '1';
|
sigDivNumerator <= config_clk;
|
sigDivNumerator <= config_clk;
|
if baud_configured = '0' then
|
if baud_configured = '0' then
|
-- Baud not configured yet so wait for it...
|
-- Baud not configured yet so wait for it...
|
controlStates <= idle;
|
controlStates <= idle;
|
|
done <= '1';
|
else
|
else
|
-- If already configured wait for division completion...
|
-- If already configured wait for division completion...
|
controlStates <= start_division;
|
controlStates <= start_division;
|
end if;
|
end if;
|
|
|
Line 113... |
Line 147... |
sigDivRst <= '1';
|
sigDivRst <= '1';
|
sigDivDividend <= config_baud;
|
sigDivDividend <= config_baud;
|
if clk_configured = '0' then
|
if clk_configured = '0' then
|
-- Clock not configured yet so wait for it...
|
-- Clock not configured yet so wait for it...
|
controlStates <= idle;
|
controlStates <= idle;
|
|
done <= '1';
|
else
|
else
|
-- If already configured wait for division completion...
|
-- If already configured wait for division completion...
|
controlStates <= start_division;
|
controlStates <= start_division;
|
end if;
|
end if;
|
|
|
Line 126... |
Line 161... |
|
|
when wait_division =>
|
when wait_division =>
|
if sigDivDone = '0' then
|
if sigDivDone = '0' then
|
controlStates <= wait_division;
|
controlStates <= wait_division;
|
else
|
else
|
-- Division done, configure the Baud generator
|
-- Division done, get the result to put on the wait_cycles signal of the baud generator
|
|
div_result_baud_wait := sigDivQuotient;
|
|
controlStates <= config_state_baud_generator;
|
|
end if;
|
|
|
|
when config_state_baud_generator =>
|
|
-- Configure the wait_cycle for the desired baud rate...
|
|
baud_wait <= div_result_baud_wait;
|
|
controlStates <= rx_tx_state;
|
|
done <= '1';
|
|
|
|
-- Control the serial_receiver or serial_transmitter block
|
|
when rx_tx_state =>
|
|
controlStates <= rx_tx_state;
|
|
if (WE = '1') and (start = '1') then
|
|
if reg_addr = "10" then
|
|
controlStates <= tx_state_wait;
|
|
done <= '0';
|
|
end if;
|
|
end if;
|
|
|
|
if (WE = '0') and (start = '1') then
|
|
if reg_addr = "11" then
|
|
controlStates <= rx_state_wait;
|
|
done <= '0';
|
|
end if;
|
|
end if;
|
|
|
|
|
|
-- Send data and wait to transmit
|
|
when tx_state_wait =>
|
|
data_byte_tx <= byte_to_transmitt;
|
|
if tx_data_sent = '0' then
|
|
controlStates <= tx_state_wait;
|
|
else
|
|
controlStates <= rx_tx_state;
|
|
done <= '1';
|
end if;
|
end if;
|
|
|
|
-- Receive data and wait to receive
|
|
when rx_state_wait =>
|
|
if rx_data_ready = '1' then
|
|
byte_to_receive <= data_byte_rx;
|
|
done <= '1';
|
|
controlStates <= rx_tx_state;
|
|
else
|
|
controlStates <= rx_state_wait;
|
|
end if;
|
end case;
|
end case;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
end Behavioral;
|
end Behavioral;
|