-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathudp_byte_sum.vhd
110 lines (101 loc) · 2.86 KB
/
udp_byte_sum.vhd
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
-- Calculates 16 bit 1's compliment or 2's compliment sum a byte at a time
-- For 2's compliment first byte is the high byte
--
-- Dave Sankey, June 2012
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity udp_byte_sum is
port (
mac_clk: in std_logic;
do_sum: in std_logic;
clr_sum: in std_logic;
mac_rx_data: in std_logic_vector(7 downto 0);
mac_rx_valid: in std_logic;
int_data: in std_logic_vector(7 downto 0);
int_valid: in std_logic;
cksum: in std_logic;
run_byte_sum: in std_logic;
outbyte: out std_logic_vector(7 downto 0)
);
end udp_byte_sum;
architecture rtl of udp_byte_sum is
signal carry_bit: std_logic;
signal hi_byte, lo_byte: unsigned(8 downto 0);
begin
outbyte <= std_logic_vector(hi_byte(7 downto 0));
lo_byte_calc: process (mac_clk)
variable hi_byte_int, lo_byte_int : unsigned(8 downto 0);
variable int_data_buf: std_logic_vector(7 downto 0);
variable clr_sum_buf, int_valid_buf: std_logic;
begin
if rising_edge(mac_clk) then
if do_sum = '1' and clr_sum = '1' then
clr_sum_buf := '1';
end if;
if do_sum = '1' and int_valid = '1' then
int_data_buf := int_data;
int_valid_buf := '1';
end if;
if mac_rx_valid = '1' or run_byte_sum = '1' then
if clr_sum_buf = '1' then
hi_byte_int := (Others => '0');
clr_sum_buf := '0';
else
hi_byte_int := hi_byte;
end if;
if do_sum = '1' then
if int_valid_buf = '1' then
lo_byte_int := unsigned('0' & int_data_buf);
int_valid_buf := '0';
else
lo_byte_int := unsigned('0' & mac_rx_data);
end if;
else
lo_byte_int := (Others => '0');
end if;
end if;
lo_byte <= hi_byte_int + lo_byte_int
-- pragma translate_off
after 4 ns
-- pragma translate_on
;
end if;
end process;
hi_byte_calc: process (mac_clk)
variable carry_bit_int, hi_lo, clr_sum_buf : std_logic;
variable hi_byte_int : unsigned(8 downto 0);
begin
if rising_edge(mac_clk) then
if do_sum = '1' and clr_sum = '1' then
clr_sum_buf := '1';
end if;
if mac_rx_valid = '1' or run_byte_sum = '1' then
if clr_sum_buf = '1' then
hi_byte_int := (Others => '0');
carry_bit_int := '0';
hi_lo := '1';
clr_sum_buf := '0';
else
if carry_bit = '1' and hi_lo = '1' then
hi_byte_int := unsigned('0' & lo_byte(7 downto 0)) + 1;
else
hi_byte_int := unsigned('0' & lo_byte(7 downto 0));
end if;
carry_bit_int := lo_byte(8);
hi_lo := cksum or not hi_lo;
end if;
end if;
carry_bit <= carry_bit_int
-- pragma translate_off
after 4 ns
-- pragma translate_on
;
hi_byte <= hi_byte_int
-- pragma translate_off
after 4 ns
-- pragma translate_on
;
end if;
end process;
end rtl;