You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.8 KiB

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity string_sender is
port (
i_clk :in std_logic;
i_send_clk :in std_logic;
i_sent :in std_logic;
i_reset_n :in std_logic;
o_send :out std_logic;
o_char :out std_logic_vector(7 downto 0)
);
end;
architecture string_sender_rtl of string_sender is
type z_sender_t is (
idle,
init_transmission,
wait_for_transmission_start,
sending
);
--Function to convert one char to std_logic_vector with 8 bit
function f_char_to_vector(
i_char : in character)
return std_logic_vector is
variable v_ret : std_logic_vector(7 downto 0);
begin
v_ret := std_logic_vector(
to_unsigned(natural(character'pos(i_char)),8)
);
return v_ret;
end function f_char_to_vector;
function reverse_any_vector (a: in std_logic_vector)
return std_logic_vector is
variable result: std_logic_vector(a'RANGE);
alias aa: std_logic_vector(a'REVERSE_RANGE) is a;
begin
for i in aa'RANGE loop
result(i) := aa(i);
end loop;
return result;
end; -- function reverse_any_vector
begin
string_sender_main_proc: process(i_clk)
constant c_msg : string(1 to 14) := "Hello World!" & LF & CR;
variable v_ind : integer range 0 to c_msg'length := 1;
variable v_old_clk : std_logic := '1';
variable z_sender : z_sender_t := idle;
begin
if rising_edge(i_clk) then
if i_reset_n = '0' then
v_ind := 1;
v_old_clk := i_send_clk;
z_sender := idle;
o_send <= '0';
o_char <= (others => '0');
else
case z_sender is
when idle =>
if i_send_clk /= v_old_clk then
v_old_clk := i_send_clk;
z_sender := init_transmission;
end if;
when init_transmission =>
if i_sent = '1' then
o_char <= reverse_any_vector(f_char_to_vector(c_msg(v_ind)));
o_send <= '1';
z_sender := wait_for_transmission_start;
end if;
when wait_for_transmission_start =>
if i_sent = '0' then
o_send <= '0';
z_sender := sending;
end if;
when sending =>
if (i_sent = '1') then
if v_ind = c_msg'length then
v_ind := 1;
-- String has been sent entirely
-- Go back to IDLE
z_sender := idle;
else
v_ind := v_ind + 1;
z_sender := init_transmission;
end if;
end if;
end case;
end if; -- reset
end if; -- clk
end process string_sender_main_proc;
end;