blob: 49cb1fae6359b08b9dc183da48f0b085b49187ba (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 04/08/2020 11:41:37 AM
-- Design Name:
-- Module Name: axis_squarer - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity axis_squarer is
Port ( clk : in STD_LOGIC;
aresetn : in STD_LOGIC;
s_axis_tdata : in STD_LOGIC_VECTOR (31 downto 0);
s_axis_tlast : in STD_LOGIC;
s_axis_tvalid : in STD_LOGIC;
s_axis_tready : out STD_LOGIC;
m_axis_tdata : out STD_LOGIC_VECTOR (31 downto 0);
m_axis_tlast : out STD_LOGIC;
m_axis_tvalid : out STD_LOGIC;
m_axis_tready : in STD_LOGIC);
end axis_squarer;
architecture Behavioral of axis_squarer is
signal idle_counter: UNSIGNED(7 downto 0) := (others => '0');
signal counter_start_long: UNSIGNED(3 downto 0) := (others => '0');
type FSM_STATES is (IDLE, TX_RESULT, LONG_COMPUTATION);
signal fsm: FSM_STATES := IDLE;
begin
fsm_main: process(clk) is
begin
if rising_edge(clk) then
if aresetn = '0' then
fsm <= IDLE;
-- Reset stuff added below in response to fv
m_axis_tlast <= '0';
counter_start_long <= (others => '0');
else
case fsm is
when IDLE =>
-- Wait for input valid, then put data onto output bus
if s_axis_tvalid = '1' then
m_axis_tdata <= not s_axis_tdata;
if s_axis_tlast = '1' or counter_start_long = 2 then
m_axis_tlast <= '1';
else
m_axis_tlast <= '0';
end if;
fsm <= TX_RESULT;
end if;
when TX_RESULT =>
-- Wait for output ready
-- Do 8 fast returns before a single slow return
if m_axis_tready = '1' then
m_axis_tlast <= '0';
counter_start_long <= counter_start_long+1;
if counter_start_long = 2 then
fsm <= LONG_COMPUTATION;
counter_start_long <= (others => '0');
else
fsm <= IDLE;
end if;
end if;
when LONG_COMPUTATION =>
-- Wait for 16 cycles
-- In actuality a longer computation goes here but simplify by reducing it to a wait
idle_counter <= idle_counter + 1;
if idle_counter = 5 then
fsm <= IDLE;
end if;
end case;
end if;
end if;
end process;
fsm_axis_handshake_outputs: process(fsm,aresetn) is
begin
case fsm is
when IDLE =>
s_axis_tready <= aresetn; -- Ready when not reset
m_axis_tvalid <= '0';
when TX_RESULT =>
s_axis_tready <= '0';
m_axis_tvalid <= '1';
when LONG_COMPUTATION =>
s_axis_tready <= '0';
m_axis_tvalid <= '0';
end case;
end process;
end Behavioral;
|