Maximilian Stiefel
4 years ago
6 changed files with 163 additions and 87 deletions
@ -1,14 +0,0 @@ |
|||
entity adder is |
|||
-- i0, i1 and the carry-in ci are inputs of the adder. |
|||
-- s is the sum output, co is the carry-out. |
|||
port (i0, i1 : in bit; ci : in bit; s : out bit; co : out bit); |
|||
end adder; |
|||
|
|||
architecture rtl of adder is |
|||
begin |
|||
-- This full-adder architecture contains two concurrent assignment. |
|||
-- Compute the sum. |
|||
s <= i0 xor i1 xor ci; |
|||
-- Compute the carry. |
|||
co <= (i0 and i1) or (i0 and ci) or (i1 and ci); |
|||
end rtl; |
@ -1,56 +0,0 @@ |
|||
-- A testbench has no ports. |
|||
entity adder_tb is |
|||
end adder_tb; |
|||
|
|||
architecture behav of adder_tb is |
|||
-- Declaration of the component that will be instantiated. |
|||
component adder |
|||
port (i0, i1 : in bit; ci : in bit; s : out bit; co : out bit); |
|||
end component; |
|||
-- Specifies which entity is bound with the component. |
|||
for adder_0: adder use entity work.adder; |
|||
signal i0, i1, ci, s, co : bit; |
|||
begin |
|||
-- Component instantiation. |
|||
adder_0: adder port map (i0 => i0, i1 => i1, ci => ci, |
|||
s => s, co => co); |
|||
|
|||
-- This process does the real job. |
|||
process |
|||
type pattern_type is record |
|||
-- The inputs of the adder. |
|||
i0, i1, ci : bit; |
|||
-- The expected outputs of the adder. |
|||
s, co : bit; |
|||
end record; |
|||
-- The patterns to apply. |
|||
type pattern_array is array (natural range <>) of pattern_type; |
|||
constant patterns : pattern_array := |
|||
(('0', '0', '0', '0', '0'), |
|||
('0', '0', '1', '1', '0'), |
|||
('0', '1', '0', '1', '0'), |
|||
('0', '1', '1', '0', '1'), |
|||
('1', '0', '0', '1', '0'), |
|||
('1', '0', '1', '0', '1'), |
|||
('1', '1', '0', '0', '1'), |
|||
('1', '1', '1', '1', '1')); |
|||
begin |
|||
-- Check each pattern. |
|||
for i in patterns'range loop |
|||
-- Set the inputs. |
|||
i0 <= patterns(i).i0; |
|||
i1 <= patterns(i).i1; |
|||
ci <= patterns(i).ci; |
|||
-- Wait for the results. |
|||
wait for 1 ns; |
|||
-- Check the outputs. |
|||
assert s = patterns(i).s |
|||
report "bad sum value" severity error; |
|||
assert co = patterns(i).co |
|||
report "bad carray out value" severity error; |
|||
end loop; |
|||
assert false report "end of test" severity note; |
|||
-- Wait forever; this will finish the simulation. |
|||
wait; |
|||
end process; |
|||
end behav; |
@ -1,17 +0,0 @@ |
|||
-- Hello world program. |
|||
use std.textio.all; -- Imports the standard textio package. |
|||
|
|||
-- Defines a design entity, without any ports. |
|||
entity hello_world is |
|||
end hello_world; |
|||
|
|||
architecture behaviour of hello_world is |
|||
begin |
|||
process |
|||
variable l : line; |
|||
begin |
|||
write (l, String'("Hello world!")); |
|||
writeline (output, l); |
|||
wait; |
|||
end process; |
|||
end behaviour; |
@ -0,0 +1,30 @@ |
|||
[*] |
|||
[*] GTKWave Analyzer v3.3.98 (w)1999-2019 BSI |
|||
[*] Mon Jul 6 17:13:37 2020 |
|||
[*] |
|||
[dumpfile] "/home/maximilian/vga_uart_grabber_vhdl/uart_tx.vcd" |
|||
[dumpfile_mtime] "Mon Jul 6 17:13:29 2020" |
|||
[dumpfile_size] 4538783 |
|||
[savefile] "/home/maximilian/vga_uart_grabber_vhdl/uart_tx.gtkw" |
|||
[timestart] 0 |
|||
[size] 1920 1051 |
|||
[pos] 3 0 |
|||
*-33.258671 3810000000000 -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] uart_tx_tb. |
|||
[sst_width] 212 |
|||
[signals_width] 182 |
|||
[sst_expanded] 1 |
|||
[sst_vpaned_height] 300 |
|||
@28 |
|||
uart_tx_tb.uart_tx_0.i_clk_baudrate |
|||
uart_tx_tb.uart_tx_0.i_reset_n |
|||
@22 |
|||
uart_tx_tb.uart_tx_0.i_tx_data_vec[7:0] |
|||
@28 |
|||
uart_tx_tb.uart_tx_0.i_tx_send |
|||
uart_tx_tb.uart_tx_0.o_tx_pin |
|||
uart_tx_tb.uart_tx_0.o_tx_sent |
|||
@23 |
|||
uart_tx_tb.uart_tx_0.s_tx_buf_vec[7:0] |
|||
[pattern_trace] 1 |
|||
[pattern_trace] 0 |
@ -0,0 +1,55 @@ |
|||
library ieee; |
|||
use ieee.std_logic_1164.all; |
|||
use ieee.numeric_std.all; |
|||
|
|||
entity uart_tx is |
|||
port( |
|||
i_clk_baudrate : in std_logic; |
|||
i_reset_n : in std_logic; |
|||
i_tx_send : in std_logic; |
|||
i_tx_data_vec : in std_logic_vector(7 downto 0); |
|||
o_tx_pin : out std_logic; |
|||
o_tx_sent : out std_logic |
|||
); |
|||
end; |
|||
|
|||
architecture uart_tx_rtl of uart_tx is |
|||
type z_uart_t is (idle, sending); |
|||
constant c_START_BIT : std_logic := '0'; |
|||
constant c_STOP_BIT : std_logic := '1'; |
|||
signal s_tx_buf_vec : std_logic_vector(7 downto 0) := x"00"; |
|||
begin |
|||
uart_tx_main_proc: process(i_clk_baudrate) |
|||
variable z_uart : z_uart_t := idle; |
|||
variable v_trans_cnt : integer range 0 to 10 := 0; |
|||
begin |
|||
if rising_edge(i_clk_baudrate) then |
|||
-- Syncrhonous reset only. |
|||
if (i_reset_n = '0') then |
|||
o_tx_pin <= '1'; |
|||
o_tx_sent <= '1'; |
|||
z_uart := idle; |
|||
else |
|||
case z_uart is |
|||
when idle => |
|||
if (i_tx_send = '1') then |
|||
s_tx_buf_vec <= i_tx_data_vec; |
|||
o_tx_sent <= '0'; |
|||
o_tx_pin <= c_START_BIT; |
|||
z_uart := sending; |
|||
end if; |
|||
when sending => |
|||
if (v_trans_cnt >= 8) then |
|||
v_trans_cnt := 0; |
|||
o_tx_sent <= '1'; |
|||
o_tx_pin <= c_STOP_BIT; |
|||
z_uart := idle; |
|||
else |
|||
o_tx_pin <= s_tx_buf_vec(7-v_trans_cnt); |
|||
v_trans_cnt := v_trans_cnt + 1; |
|||
end if; |
|||
end case; |
|||
end if; -- reset |
|||
end if; -- clk |
|||
end process uart_tx_main_proc; -- main |
|||
end; |
@ -0,0 +1,78 @@ |
|||
library ieee; |
|||
use ieee.std_logic_1164.all; |
|||
use ieee.numeric_std.all; |
|||
|
|||
-- Testbenches do not have ports. |
|||
entity uart_tx_tb is |
|||
end uart_tx_tb; |
|||
|
|||
architecture uart_tx_tb_rtl of uart_tx_tb is |
|||
-- 10 MHz clock |
|||
constant c_CLK_PERIOD : time := 100 ns; |
|||
--Declaration of component we will instantiate. |
|||
component uart_tx |
|||
port ( |
|||
i_clk_baudrate : in std_logic; |
|||
i_reset_n : in std_logic; |
|||
i_tx_send : in std_logic; |
|||
i_tx_data_vec : in std_logic_vector(7 downto 0); |
|||
o_tx_pin : out std_logic; |
|||
o_tx_sent : out std_logic |
|||
); |
|||
end component; |
|||
-- Which entity is bound with the component. |
|||
for uart_tx_0: uart_tx use entity work.uart_tx; |
|||
-- Signals for test stimuli. |
|||
signal tb_i_clk_baudrate : std_logic := '0'; |
|||
signal tb_i_reset_n : std_logic := '0'; |
|||
signal tb_i_tx_send : std_logic := '0'; |
|||
signal tb_i_tx_data_vec : std_logic_vector(7 downto 0) := x"00"; |
|||
signal tb_o_tx_pin : std_logic := '0'; |
|||
signal tb_o_tx_sent : std_logic := '0'; |
|||
signal tb_done : std_logic := '0'; |
|||
begin |
|||
-- Instatiating component. |
|||
uart_tx_0: uart_tx port map ( |
|||
i_clk_baudrate => tb_i_clk_baudrate, |
|||
i_reset_n => tb_i_reset_n, |
|||
i_tx_send => tb_i_tx_send, |
|||
i_tx_data_vec => tb_i_tx_data_vec, |
|||
o_tx_pin => tb_o_tx_pin, |
|||
o_tx_sent => tb_o_tx_sent |
|||
); |
|||
-- Generate clock. |
|||
p_clock : process is |
|||
begin |
|||
if (tb_done = '0') then |
|||
tb_i_clk_baudrate <= '0'; |
|||
wait for c_CLK_PERIOD/2; |
|||
tb_i_clk_baudrate <= '1'; |
|||
wait for c_CLK_PERIOD/2; |
|||
elsif tb_done = '1' then |
|||
wait; |
|||
end if; |
|||
end process p_clock; |
|||
-- Generate further testing stimuli in addition. |
|||
p_stimuli : process is |
|||
type vector_array_t is array (0 to 3) of std_logic_vector(7 downto 0); |
|||
constant nice_words : vector_array_t := (x"BE", x"EF", x"BA", x"BE"); |
|||
begin |
|||
-- Reset transmitter. |
|||
tb_i_reset_n <= '0'; |
|||
wait for c_CLK_PERIOD; |
|||
tb_i_reset_n <= '1'; |
|||
for sanny in nice_words'range loop |
|||
-- Feed with data and tell transmitter to send. |
|||
tb_i_tx_data_vec <= nice_words(sanny); |
|||
tb_i_tx_send <= '1'; |
|||
-- Wait until transmitted then finish simulation. |
|||
wait until tb_o_tx_sent = '1'; |
|||
tb_i_tx_send <= '0'; |
|||
wait for c_CLK_PERIOD*1.5; |
|||
end loop; |
|||
tb_done <= '1'; |
|||
assert false report "end of test" severity note; |
|||
wait; |
|||
-- Wait forever, which will finish the simulation. |
|||
end process p_stimuli; |
|||
end uart_tx_tb_rtl; |
Loading…
Reference in new issue