Browse Source

Introducing the string sender

master
Maximilian Stiefel 4 years ago
parent
commit
d62bfceea0
  1. 27
      string_sender.gtkw
  2. 77
      string_sender.vhdl
  3. 100
      string_sender_tb.vhdl

27
string_sender.gtkw

@ -0,0 +1,27 @@
[*]
[*] GTKWave Analyzer v3.3.98 (w)1999-2019 BSI
[*] Sat Jul 11 11:53:05 2020
[*]
[dumpfile] "/home/maximilian/vga_uart_grabber_vhdl/string_sender.vcd"
[dumpfile_mtime] "Sat Jul 11 11:50:19 2020"
[dumpfile_size] 410742
[savefile] "/home/maximilian/vga_uart_grabber_vhdl/string_sender.gtkw"
[timestart] 0
[size] 1366 703
[pos] -1 -1
*-30.103638 200000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] string_sender_tb.
[sst_width] 212
[signals_width] 299
[sst_expanded] 1
[sst_vpaned_height] 179
@28
string_sender_tb.tb_i_clk
string_sender_tb.tb_i_reset_n
string_sender_tb.tb_o_send
@22
string_sender_tb.tb_o_char[7:0]
@29
string_sender_tb.tb_i_sent
[pattern_trace] 1
[pattern_trace] 0

77
string_sender.vhdl

@ -0,0 +1,77 @@
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,
wait_for_transmission,
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;
begin
string_sender_main_proc: process(i_clk)
constant c_msg : string(1 to 13) := "Hello World!" & LF;
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;
if (i_sent = '1') then
o_char <= f_char_to_vector(c_msg(v_ind));
o_send <= '1';
if v_ind = c_msg'length then
v_ind := 1;
else
v_ind := v_ind + 1;
end if;
z_sender := wait_for_transmission;
end if;
end if;
when wait_for_transmission =>
if i_sent = '0' then
o_send <= '0';
z_sender := sending;
end if;
when sending =>
if (i_sent = '1') then
z_sender := idle;
end if;
end case;
end if; -- reset
end if; -- clk
end process string_sender_main_proc;
end;

100
string_sender_tb.vhdl

@ -0,0 +1,100 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity string_sender_tb is
end string_sender_tb;
architecture string_sender_tb_rtl of string_sender_tb is
-- 10 MHz clock
constant c_CLK_PERIOD : time := 100 ns;
signal tb_i_clk : std_logic := '0';
signal tb_i_send_clk : std_logic := '0';
signal tb_i_sent : std_logic := '1';
signal tb_i_reset_n : std_logic := '1';
signal tb_o_send : std_logic := '0';
signal tb_o_char : std_logic_vector(7 downto 0) := (others => '0');
signal tb_done : std_logic := '0';
begin
string_send_0: entity work.string_sender(string_sender_rtl)
port map (
i_clk => tb_i_clk,
i_send_clk => tb_i_send_clk,
i_sent => tb_i_sent,
i_reset_n => tb_i_reset_n,
o_send => tb_o_send,
o_char => tb_o_char
);
-- Generate clock.
p_clock : process is
begin
if (tb_done = '0') then
tb_i_clk <= '0';
wait for c_CLK_PERIOD/2;
tb_i_clk <= '1';
wait for c_CLK_PERIOD/2;
elsif tb_done = '1' then
wait;
end if;
end process p_clock;
-- Generate send clock.
p_sclock : process is
begin
if (tb_done = '0') then
tb_i_send_clk <= '0';
wait for 10*(c_CLK_PERIOD/2);
tb_i_send_clk <= '1';
wait for 10*(c_CLK_PERIOD/2);
elsif tb_done = '1' then
wait;
end if;
end process p_sclock;
-- Process for stimuli.
p_stimuli : process is
begin
tb_i_reset_n <= '0';
wait for 2*c_CLK_PERIOD;
tb_i_reset_n <= '1';
wait for 1 ms;
tb_done <= '1';
assert false report "end of test" severity note;
wait;
end process p_stimuli;
p_ssp: process(tb_i_clk)
type z_ssp_t is (
idle,
busy,
sending
);
variable v_cnt : integer range 0 to 20 := 0;
variable z_ssp : z_ssp_t := idle;
begin
if rising_edge(tb_i_clk) then
case z_ssp is
when idle =>
if tb_o_send = '1' then
v_cnt := 0;
tb_i_sent <= '1';
z_ssp := busy;
end if;
when busy =>
if v_cnt = 10 then
v_cnt := 0;
tb_i_sent <= '0';
z_ssp := sending;
else
v_cnt := v_cnt + 1;
end if;
when sending =>
if v_cnt = 20 then
v_cnt := 0;
tb_i_sent <= '1';
z_ssp := idle;
else
v_cnt := v_cnt + 1;
end if;
end case;
end if;
end process p_ssp;
end;
Loading…
Cancel
Save