Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Ivanov/Task01/CondVecSum.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity CondVecSum is port (
a, b : in std_logic_vector(23 downto 0);
k : in std_logic_vector(2 downto 0);
result : out std_logic_vector(23 downto 0)
);
end entity;

architecture rtl of CondVecSum is
begin
process(a, b, k) is
variable a_cur, b_cur, res_cur: unsigned(7 downto 0);
begin
for i in 0 to 2 loop
if k(i) = '1' then
a_cur := unsigned(a((i + 1) * 8 - 1 downto i * 8));
b_cur := unsigned(b((i + 1) * 8 - 1 downto i * 8));
res_cur := a_cur + b_cur;
else
res_cur := unsigned(b((i + 1) * 8 - 1 downto i * 8));
end if;
result((i + 1) * 8 - 1 downto i * 8) <= std_logic_vector(res_cur);
end loop;
end process;
end architecture;
25 changes: 25 additions & 0 deletions Ivanov/Task01/testbed.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity test is end entity;

architecture rtl of test is
signal a, b, result: std_logic_vector(23 downto 0);
signal k: std_logic_vector(2 downto 0);
begin
DUT : entity work.CondVecSum port map (
a => a, b => b, k => k, result => result
);
process is
variable a0, a1, a2: unsigned(7 downto 0);
variable b0, b1, b2: unsigned(7 downto 0);
begin
a0 := B"00000000"; a1 := B"11111111"; a2 := B"11111111";
b0 := B"00001111"; b1 := B"00001111"; b2 := B"00001111";
a <= std_logic_vector(a2) & std_logic_vector(a1) & std_logic_vector(a0);
b <= std_logic_vector(b2) & std_logic_vector(b1) & std_logic_vector(b0);
k <= "110";
wait for 1 ns;
end process;
end rtl;
30 changes: 30 additions & 0 deletions Ivanov/Task02/MultiplyAccumulate.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity MultiplyAccumulate is
port(
rst, clk, inp_valid: in std_logic;
inp_a, inp_b: in unsigned(7 downto 0);
outp_result: out unsigned(19 downto 0)
);
end entity;

architecture Behavioral of MultiplyAccumulate is
signal
acc: unsigned(19 downto 0);
begin
process(clk) is begin
if clk'event and clk = '1' then
if rst = '1' then
acc <= conv_unsigned(0, 20);
elsif inp_valid = '1' then
acc <= acc + inp_a * inp_b;
end if;
end if;
end process;

process (acc) is begin
outp_result <= acc;
end process;
end Behavioral;
42 changes: 42 additions & 0 deletions Ivanov/Task02/testbed.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity testbed is end entity;

architecture Behavioral of testbed is
signal rst, inp_valid: std_logic;
signal inp_a, inp_b: unsigned(7 downto 0);
signal clk: std_logic := '0';
constant half_period: time := 5 ns;
begin
DUT : entity work.MultiplyAccumulate port map(clk => clk, rst => rst, inp_a => inp_a, inp_b => inp_b, inp_valid => inp_valid);

process is begin
rst <= '1';
for i in 0 to 9 loop
wait until clk'event and clk = '1';
end loop;
rst <= '0';
wait;
end process;

process is begin
while true loop
clk <= not clk;
wait for half_period;
end loop;
end process;

process is begin
inp_a <= conv_unsigned(1, 8);
inp_b <= conv_unsigned(1, 8);
while true loop
wait until clk'event and clk = '1';
inp_valid <= '1';
wait until clk'event and clk = '1';
inp_valid <= '0';
inp_b <= inp_b + 1;
end loop;
end process;
end Behavioral;
62 changes: 62 additions & 0 deletions Ivanov/Task03/Generator.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.math_real.all;
use work.p.all;

entity Generator is
port(
clk, rst : in std_logic;
gen : out input_data;
valid : out std_logic;
ready : in std_logic
);
end Generator;

architecture rtl of Generator is

constant test_0 : input_data := (
a => conv_unsigned(0, 32), b => conv_unsigned(0, 32),
c => conv_unsigned(0, 32), x => conv_unsigned(0, 32)
);
constant test_1 : input_data := (
a => conv_unsigned(0, 32), b => conv_unsigned(0, 32),
c => conv_unsigned(1, 32), x => conv_unsigned(0, 32)
);
constant test_2 : input_data := (
a => conv_unsigned(0, 32), b => conv_unsigned(0, 32),
c => conv_unsigned(2, 32), x => conv_unsigned(0, 32)
);
constant test_3 : input_data := (
a => conv_unsigned(0, 32), b => conv_unsigned(0, 32),
c => conv_unsigned(3, 32), x => conv_unsigned(0, 32)
);

constant tests_amount : integer := 4;
type tests_type is array(0 to tests_amount - 1) of input_data;
constant tests : tests_type := (
test_0, test_1, test_2, test_3
);
begin

process(clk)
variable current_test : integer := 0;
begin
if rising_edge(clk) then
if rst = '1' then
valid <= '0';
current_test := 0;
else
if ready = '1' then
valid <= '1';
gen <= tests(current_test);
current_test := current_test + 1;
if current_test = tests_amount then
current_test := 0;
end if;
end if;
end if;
end if;
end process;

end rtl;
73 changes: 73 additions & 0 deletions Ivanov/Task03/Quadratic.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

package p is
constant intsize : integer := 32;
subtype int is unsigned(intsize - 1 downto 0);
subtype int_tmp is unsigned(intsize * 2 - 1 downto 0);
subtype int_res is unsigned(intsize * 3 - 1 downto 0);
type input_data is record
a, b, c, x: int;
end record;
type input_data_arr is array(0 to 3) of input_data;
type valid_data_arr is array(0 to 3) of std_logic;
end;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use work.p.all;

entity Quadratic is
port(
clk, rst, valid_gen, ready_val : in std_logic;
inp : in input_data;
x : out input_data;
y : out int_res;
valid, ready : out std_logic
);
end Quadratic;

architecture rtl of Quadratic is
signal x_stored : input_data_arr := (others => (others => conv_unsigned(0, 32)));
signal y_stored_0 : int_tmp := conv_unsigned(0, intsize * 2);
signal y_stored_1 : int_tmp := conv_unsigned(0, intsize * 2);
signal y_stored_2 : int_res := conv_unsigned(0, intsize * 3);
signal v_stored : valid_data_arr := (others => '0');
begin
ready <= ready_val;

process(clk) is
begin
if rising_edge(clk) then
if rst = '1' then
x_stored <= (others => (others => conv_unsigned(0, 32)));
y_stored_0 <= conv_unsigned(0, intsize * 2);
y_stored_1 <= conv_unsigned(0, intsize * 2);
y_stored_2 <= conv_unsigned(0, intsize * 3);
v_stored <= (others => '0');
else
if ready_val = '1' then
for i in 1 to 3 loop
x_stored(i) <= x_stored(i - 1);
end loop;
for i in 1 to 3 loop
v_stored(i) <= v_stored(i - 1);
end loop;
x_stored(0) <= inp;
v_stored(0) <= valid_gen;

y_stored_0 <= x_stored(0).a * x_stored(0).x;
y_stored_1 <= y_stored_0 + x_stored(1).b;
y_stored_2 <= y_stored_1 * x_stored(2).x;
x <= x_stored(3);
y <= y_stored_2 + x_stored(3).c;
valid <= v_stored(3);
else
valid <= '0';
end if;
end if;
end if;
end process;
end rtl;
51 changes: 51 additions & 0 deletions Ivanov/Task03/Validator.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use work.p.all;

entity Validator is
port(
clk, rst : in std_logic;
x : in input_data;
y : in int_res;
valid : in std_logic;
ready : out std_logic;
error : out std_logic
);
end Validator;

architecture rtl of Validator is
constant stalling_frequency : integer := 7;
signal stalling_delta : integer := 0;
begin

process(clk)
variable y_true : int_res;
begin
if rst = '1' then
error <= '0';
ready <= '0';
else
if rising_edge(clk) then
if valid = '1' then
y_true := x.a * x.x * x.x + x.b * x.x + x.c;
if (y_true /= y) then
error <= '1';
else
error <= '0';
end if;
assert (y_true = y);
--assert(y = conv_unsigned(0, intsize * 3));
end if;
stalling_delta <= stalling_delta + 1;
if stalling_delta = stalling_frequency then
stalling_delta <= 0;
ready <= '0';
else
ready <= '1';
end if;
end if;
end if;
end process;

end rtl;
1 change: 1 addition & 0 deletions Ivanov/Task03/clock.xdc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
create_clock -name clk -period 4 [get_ports clk ]
59 changes: 59 additions & 0 deletions Ivanov/Task03/testbed.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use work.p.all;

entity testbed is
port(
error : out std_logic
);
end testbed;

architecture behavioral of testbed is
signal clk : std_logic := '0';
signal rst : std_logic;
signal in_ready, in_valid : std_logic;
signal in_gen : input_data;
signal out_ready, out_valid : std_logic;
signal out_gen : input_data;
signal out_res : int_res;

constant half_period : time := 2ns;
begin

GEN : entity work.Generator port map (
clk => clk, rst => rst, ready => in_ready, gen => in_gen, valid => in_valid
);

DUT : entity work.Quadratic port map (
clk => clk, rst => rst,
valid_gen => in_valid, ready => in_ready,
valid => out_valid, ready_val => out_ready,
inp => in_gen,
x => out_gen, y => out_res
);

VAL : entity work.Validator port map (
clk => clk, rst => rst,
x => out_gen,
y => out_res,
valid => out_valid,
ready => out_ready,
error => error
);

process is begin
clk <= not clk;
wait for half_period;
end process;

process is begin
rst <= '1';
for i in 0 to 9 loop
wait until rising_edge(clk);
end loop;
rst <= '0';
wait;
end process;

end behavioral;