Maximilian Stiefel
4 years ago
3 changed files with 204 additions and 0 deletions
@ -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 |
@ -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; |
@ -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…
Reference in new issue