@@ -58,6 +58,17 @@ def elaborate(self, platform):
5858 # Arms
5959 m .submodules .fir = fir = FIRFilter (fir_taps , shape = self .data_shape , always_ready = always_ready ,
6060 num_channels = 1 , add_tap = len (fir_taps )// 2 + 1 )
61+ fir_out_odd = Signal ()
62+ with m .If (fir .output .valid & fir .output .ready ):
63+ m .d .sync += fir_out_odd .eq (~ fir_out_odd )
64+
65+ odd = Signal ()
66+ with m .If (self .input .valid & self .input .ready ):
67+ m .d .sync += odd .eq (~ odd )
68+
69+ # Only switch modes at even samples.
70+ switch_stb = Signal ()
71+ m .d .comb += switch_stb .eq ((~ odd ) ^ (self .input .valid & self .input .ready ))
6172
6273 with m .FSM ():
6374
@@ -70,72 +81,54 @@ def elaborate(self, platform):
7081 if not self .input .signature .always_ready :
7182 m .d .comb += self .input .ready .eq (1 )
7283
73- with m .If (self .enable ):
84+ with m .If (self .enable & switch_stb ):
7485 m .next = "DECIMATE"
7586
7687 with m .State ("DECIMATE" ):
7788
78- # Input switching.
79- odd = Signal ()
80- input_idx = Signal ()
81- even_valid = Signal ()
89+ # I and Q channels are muxed in time, demuxed later in the output stage.
8290 even_buffer = Signal .like (self .input .p )
83- q_inputs = Signal .like (self .input .p )
91+ odd_buffer = Signal .like (self .input .p )
92+ q_valid = Signal ()
8493
8594 if not self .input .signature .always_ready :
86- m .d .comb += self .input .ready .eq (( ~ odd & ~ even_valid ) | fir .input .ready )
95+ m .d .comb += self .input .ready .eq (fir .input .ready )
8796
88- # Even samples are buffered and used as a secondary
89- # carry addition for the FIR filter.
90- # I and Q channels are muxed in time, demuxed later in the output stage.
91- with m .If (self .input .valid & self .input .ready ):
92- m .d .sync += odd .eq (~ odd )
93- with m .If (~ odd ):
94- with m .If (~ even_valid | fir .input .ready ):
95- m .d .sync += even_valid .eq (self .input .valid )
96- with m .If (self .input .valid ):
97- m .d .sync += even_buffer .eq (self .input .p )
98-
99- # Process two I samples and two Q samples in sequence.
100- with m .If (fir .input .ready & fir .input .valid ):
101- m .d .sync += input_idx .eq (input_idx ^ 1 )
102-
103- with m .If (input_idx == 0 ):
97+ with m .If (self .input .ready & self .input .valid ):
98+ with m .If (~ odd ):
99+ m .d .sync += even_buffer .eq (self .input .p )
100+ with m .Else ():
101+ m .d .sync += odd_buffer .eq (self .input .p )
102+ m .d .sync += q_valid .eq (1 )
103+
104+ with m .If (odd ):
104105 m .d .comb += [
105106 fir .add_input .eq (even_buffer [0 ]),
106107 fir .input .p .eq (self .input .p [0 ]),
107- fir .input .valid .eq (self .input .valid & even_valid ),
108+ fir .input .valid .eq (self .input .valid ),
108109 ]
109- with m .If (fir .input .ready & fir .input .valid ):
110- m .d .sync += [
111- q_inputs [0 ].eq (even_buffer [1 ]),
112- q_inputs [1 ].eq (self .input .p [1 ]),
113- ]
114110 with m .Else ():
115111 m .d .comb += [
116- fir .add_input .eq (q_inputs [ 0 ]),
117- fir .input .p .eq (q_inputs [1 ]),
118- fir .input .valid .eq (1 ),
112+ fir .add_input .eq (even_buffer [ 1 ]),
113+ fir .input .p .eq (odd_buffer [1 ]),
114+ fir .input .valid .eq (q_valid ),
119115 ]
116+ with m .If (fir .input .ready ):
117+ m .d .sync += q_valid .eq (0 )
120118
121119 # Output sum and demux.
122- output_idx = Signal ()
123-
124120 with m .If (~ self .output .valid | self .output .ready ):
125121 if not fir .output .signature .always_ready :
126122 m .d .comb += fir .output .ready .eq (1 )
127- m .d .sync += self .output .valid .eq (fir .output .valid & output_idx )
123+ m .d .sync += self .output .valid .eq (fir .output .valid & fir_out_odd )
128124 with m .If (fir .output .valid ):
129125 m .d .sync += self .output .p [0 ].eq (self .output .p [1 ])
130126 m .d .sync += self .output .p [1 ].eq (fir .output .p [0 ] * fixed .Const (0.5 ))
131- m .d .sync += output_idx .eq (output_idx ^ 1 )
132127
133- # Mode switch logic.
134- with m .If (~ self .enable ):
135- m .d .sync += input_idx .eq (0 )
136- m .d .sync += output_idx .eq (0 )
137- m .d .sync += odd .eq (0 )
138- m .d .sync += even_valid .eq (0 )
128+ # Mode switch logic
129+ with m .If (~ self .enable & switch_stb ):
130+ m .d .sync += even_buffer .eq (0 )
131+ m .d .sync += odd_buffer .eq (0 )
139132 m .next = "BYPASS"
140133
141134 if self ._domain != "sync" :
0 commit comments