Skip to content

Commit f39466b

Browse files
committed
Initial commit of tutorial
1 parent d9cf079 commit f39466b

File tree

79 files changed

+8512
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+8512
-0
lines changed

tutorial/common/src/incrementer.vhd

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
library ieee;
2+
use ieee.std_logic_1164.all;
3+
use ieee.numeric_std_unsigned.all;
4+
5+
use work.incrementer_pkg.all;
6+
7+
entity incrementer is
8+
generic(
9+
delay : positive := 1);
10+
port(
11+
clk : in std_logic;
12+
13+
input_tdata : in std_logic_vector;
14+
input_tvalid : in std_logic;
15+
input_tready : out std_logic;
16+
input_tlast : in std_logic := '1';
17+
18+
output_tdata : out std_logic_vector;
19+
output_tvalid : out std_logic := '0';
20+
output_tready : in std_logic := '1';
21+
output_tlast : out std_logic := '0';
22+
23+
ctrl_arready : out std_logic := '0';
24+
ctrl_arvalid : in std_logic := '0';
25+
ctrl_araddr : in std_logic_vector(7 downto 0) := x"00";
26+
27+
ctrl_rready : in std_logic := '0';
28+
ctrl_rvalid : out std_logic := '0';
29+
ctrl_rdata : out std_logic_vector(31 downto 0) := (others => '0');
30+
ctrl_rresp : out std_logic_vector(1 downto 0) := "00";
31+
32+
ctrl_awready : out std_logic := '0';
33+
ctrl_awvalid : in std_logic := '0';
34+
ctrl_awaddr : in std_logic_vector(7 downto 0) := x"00";
35+
36+
ctrl_wready : out std_logic := '0';
37+
ctrl_wvalid : in std_logic := '0';
38+
ctrl_wdata : in std_logic_vector(31 downto 0) := (others => '0');
39+
ctrl_wstrb : in std_logic_vector(3 downto 0) := x"0";
40+
41+
ctrl_bvalid : out std_logic := '0';
42+
ctrl_bready : in std_logic := '0';
43+
ctrl_bresp : out std_logic_vector(1 downto 0) := "00");
44+
begin
45+
assert input_tdata'length = output_tdata'length;
46+
end;
47+
48+
architecture a of incrementer is
49+
type state_t is (idle,
50+
writing,
51+
write_response,
52+
reading);
53+
54+
signal increment : std_logic_vector(input_tdata'length - 1 downto 0) := (0 => '1', others => '0');
55+
signal state : state_t := idle;
56+
signal addr : std_logic_vector(ctrl_araddr'range);
57+
begin
58+
main : process is
59+
type delay_line_t is array (natural range <>) of std_logic_vector(input_tdata'length + 1 downto 0);
60+
variable delay_line : delay_line_t(1 to delay + 1) := (others => (others => '0'));
61+
begin
62+
wait until rising_edge(clk);
63+
if not output_tvalid or output_tready then
64+
delay_line(1) := input_tlast & (input_tvalid and input_tready) & input_tdata;
65+
delay_line(2 to delay) := delay_line(1 to delay - 1);
66+
end if;
67+
output_tlast <= delay_line(delay)(input_tdata'length + 1);
68+
output_tvalid <= delay_line(delay)(input_tdata'length);
69+
output_tdata <= delay_line(delay)(input_tdata'length - 1 downto 0) + increment;
70+
end process main;
71+
72+
input_tready <= not output_tvalid or output_tready;
73+
74+
ctrl : process is
75+
constant axi_response_ok : std_logic_vector(1 downto 0) := "00";
76+
constant axi_response_decerr : std_logic_vector(1 downto 0) := "11";
77+
78+
-- Compare addresses of 32-bit words discarding byte address
79+
function cmp_word_address(byte_addr : std_logic_vector;
80+
word_addr : natural) return boolean is
81+
begin
82+
return to_integer(byte_addr(byte_addr'left downto 2)) = word_addr/4;
83+
end;
84+
85+
begin
86+
wait until rising_edge(clk);
87+
88+
ctrl_arready <= '0';
89+
ctrl_awready <= '0';
90+
ctrl_wready <= '0';
91+
ctrl_rvalid <= '0';
92+
ctrl_rdata <= (others => '0');
93+
94+
case state is
95+
when idle =>
96+
97+
if ctrl_arvalid then
98+
ctrl_arready <= '1';
99+
addr <= ctrl_araddr;
100+
state <= reading;
101+
102+
elsif ctrl_awvalid then
103+
ctrl_awready <= '1';
104+
addr <= ctrl_awaddr;
105+
state <= writing;
106+
end if;
107+
108+
when writing =>
109+
if ctrl_wvalid then
110+
ctrl_wready <= '1';
111+
112+
ctrl_bvalid <= '1';
113+
ctrl_bresp <= axi_response_ok;
114+
115+
state <= write_response;
116+
117+
-- Ignore byte write enable
118+
if cmp_word_address(addr, increment_reg_addr) then
119+
increment <= ctrl_wdata(increment'length - 1 downto 0);
120+
end if;
121+
end if;
122+
123+
when write_response =>
124+
if ctrl_bready then
125+
ctrl_bvalid <= '0';
126+
state <= idle;
127+
end if;
128+
129+
when reading =>
130+
if not ctrl_rvalid then
131+
ctrl_rvalid <= '1';
132+
ctrl_rresp <= axi_response_ok;
133+
134+
if cmp_word_address(addr, increment_reg_addr) then
135+
ctrl_rdata(increment'range) <= increment;
136+
else
137+
ctrl_rresp <= axi_response_decerr;
138+
end if;
139+
140+
elsif ctrl_rready then
141+
state <= idle;
142+
end if;
143+
end case;
144+
145+
end process ctrl;
146+
end;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package incrementer_pkg is
2+
constant increment_reg_addr : natural := 0;
3+
end package incrementer_pkg;

0 commit comments

Comments
 (0)