-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathpsi_common_par_ser.vhd
227 lines (204 loc) · 6.96 KB
/
psi_common_par_ser.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
------------------------------------------------------------------------------
-- Copyright (c) 2021 by Paul Scherrer Institute, Switzerland
-- All rights reserved.
-- Authors: Benoit Stef
------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- Description
------------------------------------------------------------------------------
-- This component implements a parallel to serialized data with a load input
-- and generics number to define the length of vector input.
-- Data bit 0 is sent last. when msb_g if set true; if false bit 0 sent first
-- An error bit is active when a valid occured while the serializer didn't
-- finish its task. A frame output flag arises at last serialized bit
------------------------------------------------------------------------------
-- Libraries
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.psi_common_math_pkg.all;
-- @formatter:off
entity psi_common_par_ser is
generic(rst_pol_g : std_logic := '1'; -- reset polarity
msb_g : boolean := true; -- msb first in the frame
ratio_g : natural range 1 to 4096 := 2; -- output valid speed related to clock
width_g : natural := 16); -- vector in width
port( clk_i : in std_logic; -- clock system
rst_i : in std_logic; -- reset system
dat_i : in std_logic_vector(width_g - 1 downto 0); -- data in parallel
vld_i : in std_logic; -- valid/strobe/load in
dat_o : out std_logic; -- data out serialized
err_o : out std_logic; -- error out when input valid too fast
frm_o : out std_logic; -- frame out
ld_o : out std_logic; -- start of frame out
vld_o : out std_logic); -- valid/strobe
end entity;
-- @formatter:on
architecture RTL of psi_common_par_ser is
type two_process_t is record
cnt : unsigned(log2ceil(width_g) - 1 downto 0);
dat : std_logic_vector(width_g - 1 downto 0);
idat : std_logic_vector(width_g - 1 downto 0);
frm : std_logic;
vld : std_logic;
err : std_logic;
ld : std_logic;
-- active process of serializing when ratio > 1
active : std_logic;
-- increase setting with lower data rate
count : unsigned(log2ceil(ratio_g) - 1 downto 0);
tick : std_logic;
end record;
signal r, r_next : two_process_t;
begin
proc_comb : process(r, vld_i, dat_i)
variable v : two_process_t;
begin
-- *** r => v ***
v := r;
--*** ratio counter sync with vld_i for slower throughput ***
if ratio_g > 1 then
if vld_i = '1' then
if ratio_g = 2 then
v.count := (others=>'0');
v.tick := '1';
else
v.count := r.count+1;
v.tick := '0';
end if;
v.idat := dat_i;
else
if r.active = '1' then
if r.count = ratio_g - 1 then
v.count := (others => '0');
else
v.count := r.count + 1;
end if;
--*** mng vld output ***
if ratio_g = 2 then
if r.count = ratio_g - 1 then
v.tick := '1';
else
v.tick := '0';
end if;
else
if r.count = ratio_g - 2 then
v.tick := '1';
else
v.tick := '0';
end if;
end if;
end if;
end if;
--*** load output handling ***
if ratio_g = 2 then
if r.active ='1' and r.cnt=0 and r.count = 0 then
v.ld := '1';
else
v.ld := '0';
end if;
else
if r.active ='1' and r.cnt=0 and r.count = to_unsigned(ratio_g-1,r.count'length) then
v.ld := '1';
else
v.ld := '0';
end if;
end if;
--*** serializer active ***
if vld_i = '1' then
v.active := '1';
elsif r.cnt = width_g - 1 and r.tick = '1' and vld_i='0' then
v.active := '0';
end if;
--*** serialize statement ***
if r.cnt <= width_g - 1 then
v.vld := r.tick;
--*** cnt statements upon tick ***
if r.tick = '1' and r.active = '1' then
v.cnt := r.cnt + 1;
v.dat := r.idat;
--*** shifter left MSB or right LSB ***
if msb_g then
v.idat := r.idat(width_g - 2 downto 0) & '0';
else
v.idat := '0' & r.idat(width_g - 1 downto 1);
end if;
end if;
-- *** end of frame output ***
if r.cnt = width_g - 1 and r.tick = '1' then
v.frm := '1';
else
v.frm := '0';
end if;
end if;
--*** error when serialize process isn't complete ***
if vld_i = '1' and r.cnt /= 0 then
v.err := '1';
else
v.err := '0';
end if;
--*** full speed througput ***
else
if vld_i = '1' then
v.cnt := (others=>'0');
v.vld := '1';
v.ld := '1';
v.frm := '0';
v.dat := dat_i;
else
v.ld := '0';
if r.cnt < width_g-1 then
v.cnt := r.cnt+1;
--*** shifter left MSB or right LSB ***
if msb_g then
v.dat := r.dat(width_g - 2 downto 0) & '0';
else
v.dat := '0' & r.dat(width_g - 1 downto 1);
end if;
--*** end of frame handling ***
if r.cnt = width_g-2 then
v.frm := '1';
else
v.frm := '0';
end if;
else
v.cnt := r.cnt;
v.vld := '0';
v.frm := '0';
end if;
end if;
--*** error when serialize process isn't complete ***
if vld_i = '1' and r.cnt /= width_g - 1 then
v.err := '1';
else
v.err := '0';
end if;
end if;
--*** v => r next ***
r_next <= v;
end process;
--*** output map ***
dat_o <= r.dat(width_g - 1) when msb_g else r.dat(0);
vld_o <= r.vld;
err_o <= r.err;
ld_o <= r.ld;
frm_o <= r.frm;
proc_seq : process(clk_i)
begin
if rising_edge(clk_i) then
r <= r_next;
if rst_i = rst_pol_g then
r.active <= '0';
r.tick <= '0';
r.vld <= '0';
r.err <= '0';
r.frm <= '0';
r.cnt <= (others => '0');
r.count <= (others => '0');
r.dat <= (others => '0');
r.ld <= '0';
end if;
end if;
end process;
end architecture;