You are on page 1of 7

Kharkov National University of Radioelectronics

Centre for Education in English

Course: “System-on-chip”

Laboratory Work
Report #4

Student: Teacher:
Gr. КІУКІі-16-3 Prof. Eugenia Litvinova
Name

Kharkov 2020
Task of the Lab#4:
Using cloud service http://www.edaplayground.com create the following
projects.
You can login this service using Facebook or Google account.

Example 1. Bidirectional shift register.


Use the following test data:
data <= "00000111"
data <= "00010111"

-- Testbench automatically generated online -- Design shift_register.vhd


-- at https://vhdl.lapinoo.net
-- Generation date : 27.9.2020 21:52:10 UTC -- Functionality:
-- load data and shift it data to left and right
library ieee; -- parallel to serial conversion (i.e. first load,
use ieee.std_logic_1164.all; then shift)
-- serial to parallel conversion (i.e. first shift,
entity tb_shift_register is then read)
end tb_shift_register;
-- inputs:
architecture tb of tb_shift_register is -- ctrl : to load-data and shift operations (right
and left shift)
component shift_register -- data : it is the data to be shifted
generic ( -- q_reg : store the outputs
n : natural
); library ieee;
use ieee.std_logic_1164.all;
port (clk : in std_logic;
reset : in std_logic; entity shift_register is
ctrl : in std_logic_vector (1 downto 0); generic (N :integer :=8);
data : in std_logic_vector (n-1 downto port(
0); clk, reset : in std_logic;
q_reg : out std_logic_vector (n-1 ctrl : in std_logic_vector(1 downto
downto 0)); 0);
end component; data : in std_logic_vector(N-1
downto 0);
constant n : integer := 8; q_reg : out std_logic_vector(N-1
downto 0)
);
signal clk : std_logic; end shift_register;
signal reset : std_logic;
signal ctrl : std_logic_vector (1 downto 0);
signal data : std_logic_vector (n-1 downto 0); architecture arch of shift_register is
signal q_reg : std_logic_vector (n-1 downto signal s_reg, s_next : std_logic_vector(N-1
0); downto 0);
begin
process(clk, reset)
constant TbPeriod : time := 100 ns; -- EDIT begin
Put right period here if(reset='1') then
signal TbClock : std_logic := '0'; s_reg <= (others=>'0'); -- clear the
signal TbSimEnded : std_logic := '0'; content
elsif (clk'event and clk='1') then
begin s_reg <= s_next; -- otherwise save the
next state
dut : shift_register end if;
generic map ( end process;
n => n
) process (ctrl, s_reg)
begin
port map (clk => clk, case ctrl is
reset => reset, when "00" =>
ctrl => ctrl, s_next <= s_reg; -- no operation (to
data => data, read data for serial to parallel)
q_reg => q_reg); when "01" =>
s_next <= data(N-1) & s_reg(N-1
-- Clock generation downto 1); -- right shift
TbClock <= not TbClock after TbPeriod/2 when "10" =>
when TbSimEnded /= '1' else '0'; s_next <= s_reg(N-2 downto 0) &
data(0); -- left shift
when others =>
-- EDIT: Check that clk is really your main s_next <= data; -- load data (for
clock signal parallel to serial)
clk <= TbClock; end case;
end process;
stimuli : process
begin q_reg <= s_reg;
-- EDIT Adapt initialization as needed end arch;
ctrl <= (others => '0');
data <= (others => '0');

-- Reset generation
-- EDIT: Check that reset is really your
reset signal
reset <= '1';
wait for 10 ns;
reset <= '0';
wait for 10 ns;

-- EDIT Add stimuli here


ctrl <="00";
data <= "11010101";
wait for 10 * TbPeriod;

ctrl <="01";
data <= "10010101";
wait for 10 * TbPeriod;

ctrl <="10";
data <= "10001111";
wait for 10 * TbPeriod;

ctrl <="11";
data <= "10101111";
wait for 10 * TbPeriod;

-- Stop the clock and hence terminate the


simulation
TbSimEnded <= '1';
wait;
end process;

end tb;

Add Results and waveform.


Example 2. Register-based FIFO
Use the following test data:

Reading and writing the numbers: “00000011” and "00001111".

---------------------------------------------------------------- -- File Downloaded from


-- File Downloaded from http://www.nandland.com
http://www.nandland.com --
---------------------------------------------------------------- -- Description: Creates a Synchronous FIFO
made out of registers.
library ieee; -- Generic: g_WIDTH sets the width of
use ieee.std_logic_1164.all; the FIFO created.
use ieee.numeric_std.all; -- Generic: g_DEPTH sets the depth of
the FIFO created.
entity module_fifo_regs_no_flags_tb is --
end module_fifo_regs_no_flags_tb; -- Total FIFO register usage will be
width * depth
architecture behave of -- Note that this fifo should not be used
module_fifo_regs_no_flags_tb is to cross clock domains.
-- (Read and write clocks NEED TO BE
constant c_DEPTH : integer := 4; the same clock domain)
constant c_WIDTH : integer := 8; --
-- FIFO Full Flag will assert as soon as
signal r_RESET : std_logic := '0'; last word is written.
signal r_CLOCK : std_logic := '0'; -- FIFO Empty Flag will assert as soon
signal r_WR_EN : std_logic := '0'; as last word is read.
signal r_WR_DATA : --
std_logic_vector(c_WIDTH-1 downto 0) := -- FIFO is 100% synthesizable. It uses
"00000011"; assert statements which do
-- X"A5" is initial value -- not synthesize, but will cause your
signal w_FULL : std_logic; simulation to crash if you
signal r_RD_EN : std_logic := '0'; -- are doing something you shouldn't be
signal w_RD_DATA : doing (reading from an
std_logic_vector(c_WIDTH-1 downto 0); -- empty FIFO or writing to a full FIFO).
signal w_EMPTY : std_logic; --
-- No Flags = No Almost Full
component module_fifo_regs_no_flags is (AF)/Almost Empty (AE) Flags
generic ( -- There is a separate module that has
g_WIDTH : natural := 8; programmable AF/AE flags.
g_DEPTH : integer := 32 ----------------------------------------------------------------
); ---------------
port (
i_rst_sync : in std_logic; library ieee;
i_clk : in std_logic; use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- FIFO Write Interface
i_wr_en : in std_logic; entity module_fifo_regs_no_flags is
i_wr_data : in std_logic_vector(g_WIDTH-1 generic ( -- parameters of array
downto 0); g_WIDTH : natural := 8;
o_full : out std_logic; g_DEPTH : integer := 32
);
-- FIFO Read Interface port (
i_rd_en : in std_logic; i_rst_sync : in std_logic;
o_rd_data : out std_logic_vector(g_WIDTH- i_clk : in std_logic;
1 downto 0);
o_empty : out std_logic -- FIFO Write Interface
); i_wr_en : in std_logic;
end component module_fifo_regs_no_flags; i_wr_data : in std_logic_vector(g_WIDTH-1
downto 0);
begin o_full : out std_logic;

MODULE_FIFO_REGS_NO_FLAGS_INST : -- FIFO Read Interface


module_fifo_regs_no_flags i_rd_en : in std_logic;
generic map ( o_rd_data : out std_logic_vector(g_WIDTH-1
g_WIDTH => c_WIDTH, downto 0);
g_DEPTH => c_DEPTH o_empty : out std_logic
) );
port map ( end module_fifo_regs_no_flags;
i_rst_sync => r_RESET,
i_clk => r_CLOCK, architecture rtl of module_fifo_regs_no_flags is
i_wr_en => r_WR_EN,
i_wr_data => r_WR_DATA, type t_FIFO_DATA is array (0 to g_DEPTH-1)
o_full => w_FULL, of std_logic_vector(g_WIDTH-1 downto 0);
i_rd_en => r_RD_EN, signal r_FIFO_DATA : t_FIFO_DATA :=
o_rd_data => w_RD_DATA, (others => (others => '0'));
o_empty => w_EMPTY
); signal r_WR_INDEX : integer range 0 to
g_DEPTH-1 := 0;
r_CLOCK <= not r_CLOCK after 5 ns; signal r_RD_INDEX : integer range 0 to
g_DEPTH-1 := 0;
p_TEST : process is
begin -- # Words in FIFO, has extra range to allow for
wait until r_CLOCK = '1'; assert conditions
r_WR_EN <= '1'; signal r_FIFO_COUNT : integer range -1 to
wait until r_CLOCK = '1'; g_DEPTH+1 := 0;
wait until r_CLOCK = '1';
wait until r_CLOCK = '1'; signal w_FULL : std_logic;
wait until r_CLOCK = '1'; signal w_EMPTY : std_logic;
r_WR_EN <= '0';
r_RD_EN <= '1'; begin
wait until r_CLOCK = '1';
wait until r_CLOCK = '1'; p_CONTROL : process (i_clk) is
wait until r_CLOCK = '1'; begin
wait until r_CLOCK = '1'; if rising_edge(i_clk) then
r_RD_EN <= '0'; if i_rst_sync = '1' then
r_WR_EN <= '1'; r_FIFO_COUNT <= 0;
wait until r_CLOCK = '1'; r_WR_INDEX <= 0;
r_WR_DATA <= "00001111"; r_RD_INDEX <= 0;
wait until r_CLOCK = '1'; else
r_RD_EN <= '1';
wait until r_CLOCK = '1'; -- Keeps track of the total number of words
wait until r_CLOCK = '1'; in the FIFO
wait until r_CLOCK = '1'; if (i_wr_en = '1' and i_rd_en = '0') then
wait until r_CLOCK = '1'; r_FIFO_COUNT <= r_FIFO_COUNT + 1;
wait until r_CLOCK = '1'; elsif (i_wr_en = '0' and i_rd_en = '1') then
wait until r_CLOCK = '1'; r_FIFO_COUNT <= r_FIFO_COUNT - 1;
wait until r_CLOCK = '1'; end if;
wait until r_CLOCK = '1';
r_WR_EN <= '0'; -- Keeps track of the write index (and
wait until r_CLOCK = '1'; controls roll-over)
wait until r_CLOCK = '1'; if (i_wr_en = '1' and w_FULL = '0') then
wait until r_CLOCK = '1'; if r_WR_INDEX = g_DEPTH-1 then
wait until r_CLOCK = '1'; r_WR_INDEX <= 0;
else
end process; r_WR_INDEX <= r_WR_INDEX + 1;
end if;
end behave; end if;

-- Keeps track of the read index (and


controls roll-over)
if (i_rd_en = '1' and w_EMPTY = '0') then
if r_RD_INDEX = g_DEPTH-1 then
r_RD_INDEX <= 0;
else
r_RD_INDEX <= r_RD_INDEX + 1;
end if;
end if;

-- Registers the input data when there is a


write
if i_wr_en = '1' then
r_FIFO_DATA(r_WR_INDEX) <=
i_wr_data;
end if;

end if; -- sync reset


end if; -- rising_edge(i_clk)
end process p_CONTROL;

o_rd_data <= r_FIFO_DATA(r_RD_INDEX);

w_FULL <= '1' when r_FIFO_COUNT =


g_DEPTH else '0';
w_EMPTY <= '1' when r_FIFO_COUNT = 0
else '0';

o_full <= w_FULL;


o_empty <= w_EMPTY;

-- ASSERTION LOGIC - Not synthesized


-- synthesis translate_off

p_ASSERT : process (i_clk) is


begin
if rising_edge(i_clk) then
if i_wr_en = '1' and w_FULL = '1' then
report "ASSERT FAILURE -
MODULE_REGISTER_FIFO: FIFO IS FULL
AND BEING WRITTEN " severity failure;
end if;

if i_rd_en = '1' and w_EMPTY = '1' then


report "ASSERT FAILURE -
MODULE_REGISTER_FIFO: FIFO IS EMPTY
AND BEING READ " severity failure;
end if;
end if;
end process p_ASSERT;

-- synthesis translate_on
end rtl;

Add Results and waveform.

You might also like