-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcnp_vector.vhd
152 lines (145 loc) · 3.8 KB
/
cnp_vector.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
-- vector check node processor
--
-- Copyright 2019 Ahmet Inan <[email protected]>
library ieee;
use ieee.std_logic_1164.all;
use work.ldpc_scalar.all;
use work.ldpc_vector.all;
entity cnp_vector is
port (
clock : in std_logic;
start : in boolean;
count : in count_scalar;
ready : out boolean := true;
valid : out boolean := false;
iseq : in sequence_scalar;
oseq : out sequence_scalar;
ivsft : in vsft_vector;
ovsft : out vsft_vector;
icsft : in csft_vector;
ocsft : out csft_vector;
iwdf : in boolean;
owdf : out boolean;
iloc : in vector_location;
oloc : out vector_location;
ioff : in vector_offset;
ooff : out vector_offset;
ishi : in vector_shift;
oshi : out vector_shift
);
end cnp_vector;
architecture rtl of cnp_vector is
signal imin, dmin, omin : two_min_vector;
signal ipty, dpty, opty : sign_vector;
subtype num_scalar is natural range 0 to degree_max;
signal num : num_scalar := num_scalar'high;
signal icmag : cmag_vector;
signal this_count, prev_count : count_scalar;
signal seq, dseq : sequence_scalar;
signal this_start, prev_start : boolean := false;
signal okay : boolean := true;
signal dvalid : boolean := false;
signal shorter : boolean;
signal finalize : boolean;
signal buf_wren : boolean := false;
signal buf_addr : natural range 0 to degree_max-1;
signal buf_ivsft : vsft_vector;
signal buf_ovsft : vsft_vector;
signal buf_icsft : csft_vector;
signal buf_ocsft : csft_vector;
signal buf_icmag : cmag_vector;
signal buf_ocmag : cmag_vector;
signal buf_iwdf : boolean;
signal buf_owdf : boolean;
signal buf_iloc : vector_location;
signal buf_oloc : vector_location;
signal buf_ioff : vector_offset;
signal buf_ooff : vector_offset;
signal buf_ishi : vector_shift;
signal buf_oshi : vector_shift;
begin
buf_inst : entity work.buf_vector
port map (clock,
buf_wren, buf_addr,
buf_ivsft, buf_ovsft,
buf_icsft, buf_ocsft,
buf_icmag, buf_ocmag,
buf_iwdf, buf_owdf,
buf_iloc, buf_oloc,
buf_ioff, buf_ooff,
buf_ishi, buf_oshi);
icmag <= min_sum(vmag_of_vsft(ivsft));
ovsft <= buf_ovsft;
ocsft <= self_corr(buf_ocsft, sign_and_cmag_to_csft(opty xor sign_of_vsft(buf_ovsft), select_other(buf_ocmag, omin)));
owdf <= buf_owdf;
oloc <= buf_oloc;
ooff <= buf_ooff;
oshi <= buf_oshi;
finalize <= false when not this_start else num = prev_count when shorter else num = this_count;
process (clock)
begin
if rising_edge(clock) then
valid <= dvalid;
oseq <= dseq;
omin <= dmin;
opty <= dpty;
if start or finalize then
num <= 0;
dvalid <= false;
buf_wren <= false;
prev_start <= this_start;
this_start <= start;
prev_count <= this_count;
dseq <= seq;
seq <= iseq;
if start then
this_count <= count;
shorter <= count < this_count;
else
this_count <= count_scalar'low;
shorter <= true;
ready <= false;
end if;
dmin <= imin;
dpty <= ipty;
imin <= (others => (cmag_scalar'high, cmag_scalar'high));
ipty <= (others => false);
elsif num /= num_scalar'high then
num <= num + 1;
if shorter then
if num = prev_count-2 then
ready <= true;
elsif num = this_count-2 then
ready <= false;
end if;
if num = prev_count-1 then
okay <= true;
elsif num = this_count-1 then
okay <= false;
end if;
end if;
if okay then
imin <= two_min(icmag, imin);
ipty <= ipty xor sign_of_vsft(ivsft);
end if;
if num = 0 then
dvalid <= prev_start;
elsif num = prev_count then
dvalid <= false;
end if;
buf_wren <= true;
buf_addr <= num;
buf_ivsft <= ivsft;
buf_icsft <= icsft;
buf_icmag <= icmag;
buf_iwdf <= iwdf;
buf_iloc <= iloc;
buf_ioff <= ioff;
buf_ishi <= ishi;
else
dvalid <= false;
buf_wren <= false;
end if;
end if;
end process;
end rtl;