From 5c175df671221f9111670caf47166ba231ff44be Mon Sep 17 00:00:00 2001 From: IvanovDA <34244808+IvanovDA@users.noreply.github.com> Date: Fri, 7 Dec 2018 11:11:59 +0300 Subject: [PATCH] Add files via upload --- Ivanov/Task01/CondVecSum.vhd | 28 +++++++++++ Ivanov/Task01/testbed.vhd | 25 ++++++++++ Ivanov/Task02/MultiplyAccumulate.vhd | 30 ++++++++++++ Ivanov/Task02/testbed.vhd | 42 ++++++++++++++++ Ivanov/Task03/Generator.vhd | 62 +++++++++++++++++++++++ Ivanov/Task03/Quadratic.vhd | 73 ++++++++++++++++++++++++++++ Ivanov/Task03/Validator.vhd | 51 +++++++++++++++++++ Ivanov/Task03/clock.xdc | 1 + Ivanov/Task03/testbed.vhd | 59 ++++++++++++++++++++++ 9 files changed, 371 insertions(+) create mode 100644 Ivanov/Task01/CondVecSum.vhd create mode 100644 Ivanov/Task01/testbed.vhd create mode 100644 Ivanov/Task02/MultiplyAccumulate.vhd create mode 100644 Ivanov/Task02/testbed.vhd create mode 100644 Ivanov/Task03/Generator.vhd create mode 100644 Ivanov/Task03/Quadratic.vhd create mode 100644 Ivanov/Task03/Validator.vhd create mode 100644 Ivanov/Task03/clock.xdc create mode 100644 Ivanov/Task03/testbed.vhd diff --git a/Ivanov/Task01/CondVecSum.vhd b/Ivanov/Task01/CondVecSum.vhd new file mode 100644 index 0000000..c605ec4 --- /dev/null +++ b/Ivanov/Task01/CondVecSum.vhd @@ -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; \ No newline at end of file diff --git a/Ivanov/Task01/testbed.vhd b/Ivanov/Task01/testbed.vhd new file mode 100644 index 0000000..2589d0c --- /dev/null +++ b/Ivanov/Task01/testbed.vhd @@ -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; \ No newline at end of file diff --git a/Ivanov/Task02/MultiplyAccumulate.vhd b/Ivanov/Task02/MultiplyAccumulate.vhd new file mode 100644 index 0000000..5c66e12 --- /dev/null +++ b/Ivanov/Task02/MultiplyAccumulate.vhd @@ -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; diff --git a/Ivanov/Task02/testbed.vhd b/Ivanov/Task02/testbed.vhd new file mode 100644 index 0000000..128fac1 --- /dev/null +++ b/Ivanov/Task02/testbed.vhd @@ -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; diff --git a/Ivanov/Task03/Generator.vhd b/Ivanov/Task03/Generator.vhd new file mode 100644 index 0000000..9bc9bec --- /dev/null +++ b/Ivanov/Task03/Generator.vhd @@ -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; diff --git a/Ivanov/Task03/Quadratic.vhd b/Ivanov/Task03/Quadratic.vhd new file mode 100644 index 0000000..78a110e --- /dev/null +++ b/Ivanov/Task03/Quadratic.vhd @@ -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; \ No newline at end of file diff --git a/Ivanov/Task03/Validator.vhd b/Ivanov/Task03/Validator.vhd new file mode 100644 index 0000000..ff29580 --- /dev/null +++ b/Ivanov/Task03/Validator.vhd @@ -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; diff --git a/Ivanov/Task03/clock.xdc b/Ivanov/Task03/clock.xdc new file mode 100644 index 0000000..0fd9050 --- /dev/null +++ b/Ivanov/Task03/clock.xdc @@ -0,0 +1 @@ +create_clock -name clk -period 4 [get_ports clk ] \ No newline at end of file diff --git a/Ivanov/Task03/testbed.vhd b/Ivanov/Task03/testbed.vhd new file mode 100644 index 0000000..dc263bb --- /dev/null +++ b/Ivanov/Task03/testbed.vhd @@ -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;