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