CIC Filter design for multiple FM carrier demod

Started by Paul Solomon May 17, 2005
Paul Solomon wrote:
> Hi Jerry, > > > "Jerry Avins" <jya@ieee.org> wrote in message > news:-5WdnY8J-5UwvhffRVn-tQ@rcn.net... >> ... Why decimate at all? > > > I believe that if you were to try and notch a 200kHz part of spectrum out > when operating at 80MSPS, you need an ~ 1000 tap filter, and as I plan to > do multiple channels, that means multiple 1000 tap filters. > I dont think that is a good approach space wise!
It sounds pretty dumb the way I put it! There could be several reasons for decimating. I wanted to be clear about why, instead of maybe overlooking some part of the problem. ... Jerry -- Engineering is the art of making what you want from things you can get. &#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;&#2013266095;
On Wed, 18 May 2005 16:13:39 +1000, "Paul Solomon"
<psolomon@tpg.com.au> wrote:


Hi Paul,

>Hi Bhaskar, > >thanks for this info, it has helped alot, and that article nicely explained >the finer details of >CIC that I was confused about. > >I am trying to do the design in matlab and am currently stalled as I do not >have the fixed point toolbox >that the filter design toolbox wants to do CIC filters.. I think that I have >now made a correct FIR correction >filter but it would be nice to be able to cascade this with a CIC filter >inmatlab and see the cumulative response.
Humm, maybe you could try applying a wideband (flat spectrum) noise signal to your cascaded filters and then plot the DFT magnitudes of the filters' output sequence.
>So I think it will be a few days before I can report back sucsess, however I >think I am on the right track now >thanks to your assistance.
Yep, please let us know how things go. Good Luck. [-Rick-]
On Wed, 18 May 2005 16:19:32 +1000, "Paul Solomon"
<psolomon@tpg.com.au> wrote:

  (snipped)
>> >> Let us know how you make out. Maybe Rick will pass on some pointers. What >> FM demodulating scheme to you plan to use? There are a few. > >I am unsure on the method I will use for the demod, I have read multiple >approached >PLL, phase detector, differentiator, etc and I was planning on implementing >a few to compare >performance, and then I will just go with whatever works best.
Hi, ya' know, I've run across 3-4 (or is it 4-5) different schemes for FM demodulation. It sure would be terrific if someone could model all those schemes and come up with some sort of comaparison. But I'll bet a project like that would take all summer to complete! [-Rick-]
On Tue, 17 May 2005 17:23:41 -0400, "Steve Conahan"
<Steve.Conahan@mathworks.com> wrote:

  (snipped)
> >Hi Paul, > >There is a demo that is in the Filter Design Toolbox for MATLAB (Release 14, >Service Pack 2) that may help you. The demo file is named >ddcfilterchaindemo.m (see complete code below). It illustrates how to >design a similar DDC system for GSM. It looks like a very similar example >for what you are interested in doing (at least it could get you started). > >Also there is a similar "GSM Digital Downconverter" Simulink demo that ships >with the Signal Processing Blockset product. > >Cheers, >Steve Conahan >Signal Processing and Communications Development >The MathWorks, Inc. > >P.S. Here is the complete M code for the demo: >
(MATLAB code snipped) Hello Steve, I was tickled that you posted that code. However, trying to run it failed because I don't have a "called" routine titled "mfilt.cicdecim". Any chance you could provide that "mfilt.cicdecim" code? Thanks, [-Rick-] I'm just being greedy. :-)
"Paul Solomon" <psolomon@tpg.com.au> wrote in message
news:428add1a@dnews.tpgi.com.au...
> Hi Bhaskar, > > thanks for this info, it has helped alot, and that article nicely
explained
> the finer details of > CIC that I was confused about. > > I am trying to do the design in matlab and am currently stalled as I do
not
> have the fixed point toolbox > that the filter design toolbox wants to do CIC filters.. I think that I
have
> now made a correct FIR correction > filter but it would be nice to be able to cascade this with a CIC filter > inmatlab and see the cumulative response.
While a CIC filter is typically modeled (and implemented) in fixed point, I don't think you absolutely need the fixed point toolbox to do what you want. Either you can implement the fixed precision manually in your matlab code or go ahead and use double precision arithmetic to model it for now. What is of importance here is that you model the frequency response of the CIC correctly (since that is what you are trying to study)..esp to see if your FIR correction is doing it's job. The frequency response of the CIC is quite well defined (see references). So you should be able to stick that your current simulation and see what happens. (Yes, I know that it would certainly be a lot more convenient to take a canned solution from Mathworks and get this to happen but I can guarantee that you'll learn more this way and save a bunch of cash) Cheers Bhaskar Note - A CIC implementation takes advantage of fixed precision arithmetic to work right - so I suggest you *model* your CIC rather than implement it in matlab for your simulation.
> So I think it will be a few days before I can report back sucsess, however
I
> think I am on the right track now > thanks to your assistance. > > regards, > > Paul Solomon > > > "Bhaskar Thiagarajan" <bhaskart@deja.com> wrote in message > news:428a1b87$0$79456$14726298@news.sunsite.dk... > > "Tim Wescott" <tim@seemywebsite.com> wrote in message > > news:118jvijkhj28t22@corp.supernews.com... > >> Paul Solomon wrote: > >> > >> > Hi All, > >> > > >> > I am working on a project in which we are attempting to demod
multiple
> >> > (analog) FM radio stations in a FPGA. > >> > I have been trying to work out how to design the CIC / FIR filter
pair
> > in > >> > the DDC section of this design. > >> > >> This paragraph has put me into abbreviation overload. FM, FPGA and FIR > >> all make sense to me -- what do CIC and DDC mean in this context? > > > > CIC - Cascaded Integrated Comb > > DDC - Digital Down Converter > > > > > >> > I have a input sampling rate of 80MSPS, which undersamples a clean > > spectrum > >> > of 88 - 108MHz i.e. the FM band. > >> > this should give me the FM band at 8 - 28MHz with an alias at 52 - > > 72MHz. > >> > > >> > I then take this input and mix with a NCO generated carrier at say > > 20.5MHz > >> > to try to pull out one of the stations. > >> > The output of the mixer needs to then be filtered to approx 200kHz > > bandwidth > >> > and decimated to maybe 800kSPS? > >> > >> Is it quadrature demodulation? If so 200kHz is strictly correct only
if
> >> you mean -100kHz to 100kHz. You could go out more than that if you > >> wanted to, but why? > >> > > >> > this is the part I am unsure of how to do.. I believe that I will
need
> >> > a > > CIC > >> > followed by a FIR however > >> > I am not sure the relevant paramaters of the CIC and how to set them, > >> > i.e. (decimation Rate) R = 128, but (stages)N = ?? and (differential > > delay)M > >> > = ??. > >> > >> Apparantly a CIC is some sort of a polyphase filter with decimation?
If
> >> so, why do you need a FIR filter at all? In fact if you were clever
you
> >> should be able to follow the quadrature demodulation with a single-step > >> lowpass/decimation filter to get a nicely conditioned baseband signal > >> that you would then have to work on to extract the FM signal. > > > > A CIC is a box-car filter that (just google for lotsa references and
very
> > detailed explanations - Rick just had one of his artciles on this very > > topic > > in EE times I think) doesn't use any multipliers, supports large > > decimation > > ratios, works well in fixed point arithmentic. So these are excellent > > candiates for 'coarse' decimation blocks that need to be implemented in > > FPGAs. Since they are box-car to begin with, their frequency response is > > pretty bad - so they are typically followed by a FIR filter that does
any
> > 'fine' decimation that may be needed as well as correct for the
amplitude
> > droop in the pass-band caused by the CICs. > > > > Given Paul's system requirements, I would think that a single FIR > > (non-CIC) > > to get him from 80 Msps to 800ksps in one step wouldn't be easy. So he
is
> > correct in considering CICs in his design. > > > > Here is Rick's article for reference - Paul would be wise to read it > > before > > moving forward. > > http://www.embedded.com/showArticle.jhtml?articleID=160400592 > > > > Paul - it seems you are shooting for a decimation of about 100. I'd > > suggest > > a CIC decimation of say 64 and the rest can be handled by your final
FIR.
> > Rick's article discusses the trade-offs related to stages and
differential
> > delay choices for these filters. If you still aren't sure of what you > > need, > > ask again (with some background on what you don't get). > > > > Since the CIC filters' frequency response is known exactly, you can then > > create an 'inverse' of this response in the frequency domain and then > > perform an IFFT to get filter coeffs for your FIR filter that can
correct
> > for the CIC. > > Note that you probably want a combination FIR - one that will correct
the
> > CIC as well as provide filtering to remove images and good stop band > > attenuation for the spectrum of interest. So you'd need to combine the 2 > > responses together to get your filter coeffs. > > > > Cheers > > Bhaskar > > > >> > > >> > I have read Hogenauer and still feel none the wiser.. > >> > > >> > also once the filter parameters are decided, how do you design the > > following > >> > FIR filter to straighten up the passband?? > >> > > >> > Anyhow, Hopefully someone out there will be able to help. > >> > > >> > Cheers, > >> > > >> > Paul Solomon > >> > > >> > > >> > >> > >> -- > >> ------------------------------------------- > >> Tim Wescott > >> Wescott Design Services > >> http://www.wescottdesign.com > > > > > >
"Rick Lyons" <R.Lyons@_BOGUS_ieee.org> wrote in message 
news:428b4b55.1377594562@news.sf.sbcglobal.net...
> On Tue, 17 May 2005 17:23:41 -0400, "Steve Conahan" > <Steve.Conahan@mathworks.com> wrote: > > (snipped) >> >>Hi Paul, >> >>There is a demo that is in the Filter Design Toolbox for MATLAB (Release >>14, >>Service Pack 2) that may help you. The demo file is named >>ddcfilterchaindemo.m (see complete code below). It illustrates how to >>design a similar DDC system for GSM. It looks like a very similar example >>for what you are interested in doing (at least it could get you started). >> >>Also there is a similar "GSM Digital Downconverter" Simulink demo that >>ships >>with the Signal Processing Blockset product. >> >>Cheers, >>Steve Conahan >>Signal Processing and Communications Development >>The MathWorks, Inc. >> >>P.S. Here is the complete M code for the demo: >> > > (MATLAB code snipped) > > Hello Steve, > > I was tickled that you posted that code. > > However, trying to run it failed because > I don't have a "called" routine titled > "mfilt.cicdecim". > > Any chance you could provide that > "mfilt.cicdecim" code? > > Thanks, > [-Rick-] > I'm just being greedy. :-) >
Hi Rick, Our Filter Design Toolbox MFILT multirate filter object code is not open source. ;-) However, as a friendly gesture, I have included below some close/equivalent/similar MATLAB fixed-point M code that can be used to do CIC decimation filtering. This code may explain some of the lower-level fixed-point arithmetic that you are interested in simulating. (Note that the code below uses fixed-point arithmetic in MATLAB, and hence requires the Fixed-Point Toolbox but it does not use Filter Design Toolbox MFILT objects). Cheers, Steve function y = hcicdecimalgo(x,n,m,r,offset,inbits,infraclen,obits,bps,varargin) %HCICDECIMALGO Cascaded Integrator-Comb Decimator M-file. % Y = HCICDECIMALGO(X,N,M,R,OFFSET,INBITS,INFRACLEN,OBITS,BPS) filters the % data in X with N-section cascaded integrator-comb decimation filter with % M differential delays and a rate-change factor of R. X can be a % row/column vector or a matrix. % % Inputs: % N is the number of sections % M is the differential delay of the comb part % R is the decimation factor % OFFSET is the phase offset factor for downsampling % INBITS is the Word Length of the input signal. % INFRACLEN is the Fractional Length of the input signal % OBITS is the wordlength of the output signal % BPS can be a scalar or vector (of length 2*N). BPS defines the word length % section used during either the accumulation of the data in the integrator % sections or the subtraction of the data performed by the comb sections % (using 'wrap' arithmetic). If BPS is a scalar, that value is applied % to each filter stage. % % Optional arguments: % Y = HCICDECIMALGO(...,'zerolat') filters the data in X % with N-stage cascaded integrator-comb decimation filter with M % differential delays and a rate-change factor of R with NO LATENCY at % the output % % Note: This function is used to emulate the functionality of the % CIC-Decimator in the Signal Processing Blockset % Vectorize bps if it is a scalar if(isscalar(bps)) bps = repmat(bps,[1 2*n]); end % Include the output bits bps(end+1) = obits; % Compute the bits to remove per section b2rm = [abs(diff(bps)) abs(bps(end)-obits)]; % Compute the fraction lengths that will be propagated through the filter. for i = 1:(2*n)+ 1 if(i==1) fraclen(i) = infraclen; else fraclen(i) = fraclen(i-1) - b2rm(i-1); end end % Create a vector of FIMATH objects (2*n) and initialize the states for each stage for i = 1:2*n fm(i) = fimath('SumMode','SpecifyPrecision','SumWordLength',bps(i),'SumFractionLength',fraclen(i),... 'RoundMode','floor','OverflowMode','wrap','CastBeforeSum',1); z{i,1} = fi(0,'fimath',fm(i)); end fm_integ = fm(1:n); % assign the fimath operators(for addition) to the % integrator section fm_comb = fm(n+1:end); % assign the fimath operators(for subtraction) % to the comb section z_integ = z(1:n,:); % assign initial delays to each integrator stage z_comb = z(n+1:end,:); % assign initial delays to each comb stage % Default is to exhibit latency latency = true; if((nargin > 9) && strcmpi(varargin{1},'zerolat')) latency = false; end % Convert input to FI % % NOTE: % In order to match the results of the CIC Block, we use a test model with % the DSP Constant block. The RoundMode of the DSP Constant Block is % 'round' and the OverFlowMode is 'Saturate.' xfi = fi(x,true,inbits,infraclen,'RoundMode','round','OverflowMode','saturate'); % Preallocate for the output of the integrator portion of the filter using % the attributes of section N (last section in the integrator side) [nx,nchans] = size(x); yint_out = fi(zeros(ceil(nx/r),nchans),'WordLength',bps(n),... 'FractionLength',fraclen(n),'fimath',fm_integ(n)); [yrows,ycols] = size(yint_out); % Multichannel loop for l = 1:nchans, % Intergrate and Decimate Portion if latency, [yint(:,l), zfint(:,l)] = cic_integratendecim(r,m,n,xfi(:,l),bps,b2rm,fm_integ,z_integ,yint_out(:,l),offset); else [yint(:,l), zfint(:,l)] = cic_integratendecim_zlat(r,m,n,xfi(:,l),bps,b2rm,fm_integ,z_integ,yint_out(:,l),offset); end % Comb Portion y_comb(:,l) = comb(yint(:,l),yrows,m,n,fm_comb,bps,fraclen,b2rm); end % Cast output to correct size fm_out = fimath('SumMode','SpecifyPrecision','SumWordLength',obits,'SumFractionLength',fraclen(end),... 'RoundMode','floor','OverflowMode','wrap','CastBeforeSum',1); y = fi(y_comb,'WordLength',obits,'FractionLength',fraclen(end),... 'fimath',fm_out); % ------------------------------------------------------------------------- % CIC_INTEGRATENDECIM: Integrate and decimate portion of a CIC decimator % ------------------------------------------------------------------------- function [yout,zf] = cic_integratendecim(R,M,N,x,BPS,b2rm,fm_integ,z,yout,offset) % Initialize variables n = 1; modj = 0; for j = 1:length(x), % % Decimation portion % if modj == offset, % Select an output sample yout(n) = z{N}; n = n+1; end modj = mod(modj+1,R); % % Integrator section % for k = N:-1:2, % Use the FIMATH add method when adding two FIs w/ diff. FIMATHs fm = fm_integ(k); z{k} = fm.add(z{k-1},z{k}); end fm = fm_integ(1); z{1} = fm.add(x(j),z{1}); end zf = z; % ------------------------------------------------------------------------- % CIC_INTEGRATENDECIM_ZLAT: Integrate and decim portion of a ZLAT CIC decim % ------------------------------------------------------------------------- function [yout,zf] = cic_integratendecim_zlat(R,M,N,x,BPS,b2rm,fm_integ,z,yout,offset) % Initialize variables n = 1; modj = 0; for j = 1:length(x), % % Integrator section % % for k = N:-1:2, % Use the FIMATH add method when adding two FIs w/ diff. FIMATHs % fm = fm_integ(k); % z{k} = fm.add(z{k-1},z{k}); % end % fm = fm_integ(1); % z{1} = fm.add(x(j),z{1}); % Use the FIMATH add method when adding two FIs w/ diff. FIMATHs fm = fm_integ(1); z{1} = fm.add(x(j),z{1}); for k = 2:N, fm = fm_integ(k); z{k} = fm.add(z{k-1},z{k}); end % % Decimation portion % if modj == offset, % Select an output sample yout(n) = z{N}; n = n+1; end modj = mod(modj+1,R); end zf = z; %-------------------------------------------------------------------------- % COMB: Comb portion of a CIC decimation filter. %-------------------------------------------------------------------------- function y_comb = comb(yint,ny,M,N,fm_comb,bps,fraclen,b2rm) zcomb = cell(1,N); bps_comb = bps(N+1:end-1); fraclen_comb = fraclen(N+1:end-1); for k = 1:N zcomb{k} = fi(zeros(M,1),true,bps_comb(k),fraclen_comb(k),... 'fimath',fm_comb(k)); end % In order to retain the attributes of the states (for the comb side), % we'll need to loop over each section of the filter (N) and compute the % output and state. y_comb = yint; for sec = 1:N,% Number of sections [y_comb,zfcomb] = modcomb(y_comb,ny,M,N,zcomb{sec},fm_comb(sec),b2rm(N+sec)); end %-------------------------------------------------------------------------- % MODCOMB: One comb section in a CIC decimation filter. %-------------------------------------------------------------------------- function [y_comb,zcomb] = modcomb(yint,ny,M,N,zcomb,fm_comb,b2rm) for j = 0:ny-1, % Length of signal acc = yint(j+1); % Using the FIMATH method y_comb(j+1,1) = sub(fm_comb,acc,zcomb(end)); % Can't use the following because the FIMATHs for both operands must % be equal. % y_comb(j+1,1) = bitshift(acc-zcomb(end),-b2rm); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Shift the contents of the states (should be Circular buffer) for dd = M:-1:2, zcomb(dd) = zcomb(dd-1); end zcomb(1) = acc; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% end % [EOF]
Hi Guys,

Ok, I managed to get the simulation done that I was happy with in Matlab and 
designed a conpensating
FIR filter and it all looks good in matlab.. I have not started moving this 
stuff to verilog for the FPGA
and I have had a bit of trouble (probably as my verilog is rusty more than 
anything else)

I wil post my verilog code here in case there are and verilog guru's 
watching that may see what is wrong
instantly otherwise I will just keep plugging at it tonnorow. I have a 
feelig that it may be a signed integer issue
i.e. something to do with casting from a 32 bit to a 54 bit not filling in 
the trailing ones in the case of the negative input.

Anyhow, when I run this on the hardware I just get an awful lot of noise in 
the spectrum instead of a nice signal
which is what I have before filtering.

The CIC filter I am trying to implement here is a 4 stage M = 1, filter with 
a decimation rate of 64.

A 21 tap FIR filter seems to nicely clean up the passband if I put it 
afterwards.

I do have one big question weighing in my mind though, and that is how do 
you deal with the bit widths that
are constantly growing. i.e., I only have 12 bit ADC input, however after 
the multiply with the NCO I am up to 30 bits
then after the CIC I grow to 54 bits.. And after FIR it gets worse etc...
At the moment I have just taken the 14 MSB's to feed to my DAC (which is how 
I am testing the output to see if it is ok)
However, I am not sure that this is the best method of doing this..

Any Ideas on how to keep the bit widths down to a manageable size?

Regards

Paul Solomon

module cic_filter(clk, in, clk_out, out);

input clk;

input [29:0] in;

output clk_out;

output [31:0] out;

reg state; // 0 = hold, 1 = sample

reg [5:0] count;


reg [31:0] x;


reg [53:0] int1;

reg [53:0] int2;

reg [53:0] int3;

reg [53:0] int4;

reg [53:0] int_out;

reg [53:0] comb1;

reg [53:0] comb2;

reg [53:0] comb3;

reg [53:0] comb4;

reg [53:0] combd1;

reg [53:0] combd2;

reg [53:0] combd3;

reg [53:0] combd4;

reg clk2;


always @(negedge clk) begin

if (~state) begin

if (count < 63) begin

state <= 1'b0;

end else begin

state <= 1'b1;

end

end else begin

state <= 1'b0;

end

end


always @(posedge clk) begin

x <= in;

int1 <= int1 + x;

int2 <= int2 + int1;

int3 <= int3 + int2;

int4 <= int4 + int3;

if (state) begin

count <= 6'b0;

int_out <= int4;

end else begin

count <= count + 1;

end


if ((count > 16) && (count < 32)) begin

clk2 <= 1'b1;

end else begin

clk2 <= 1'b0;

end

end

always @(posedge clk2) begin

combd1 <= int_out;

comb1 <= int_out - combd1;

combd2 <= comb1;

comb2 <= comb1 - combd2;

combd3 <= comb2;

comb3 <= comb2 - combd3;

combd4 <= comb3;

comb4 <= comb3 - combd4;

end

assign clk_out = clk2;

assign out = comb4[53:22];

endmodule


"Bhaskar Thiagarajan" <bhaskart@deja.com> wrote in message 
news:428b7038$0$79458$14726298@news.sunsite.dk...
> "Paul Solomon" <psolomon@tpg.com.au> wrote in message > news:428add1a@dnews.tpgi.com.au... >> Hi Bhaskar, >> >> thanks for this info, it has helped alot, and that article nicely > explained >> the finer details of >> CIC that I was confused about. >> >> I am trying to do the design in matlab and am currently stalled as I do > not >> have the fixed point toolbox >> that the filter design toolbox wants to do CIC filters.. I think that I > have >> now made a correct FIR correction >> filter but it would be nice to be able to cascade this with a CIC filter >> inmatlab and see the cumulative response. > > While a CIC filter is typically modeled (and implemented) in fixed point, > I > don't think you absolutely need the fixed point toolbox to do what you > want. > Either you can implement the fixed precision manually in your matlab code > or > go ahead and use double precision arithmetic to model it for now. What is > of > importance here is that you model the frequency response of the CIC > correctly (since that is what you are trying to study)..esp to see if your > FIR correction is doing it's job. The frequency response of the CIC is > quite > well defined (see references). So you should be able to stick that your > current simulation and see what happens. (Yes, I know that it would > certainly be a lot more convenient to take a canned solution from > Mathworks > and get this to happen but I can guarantee that you'll learn more this way > and save a bunch of cash) > > Cheers > Bhaskar > > Note - A CIC implementation takes advantage of fixed precision arithmetic > to > work right - so I suggest you *model* your CIC rather than implement it in > matlab for your simulation. > > >> So I think it will be a few days before I can report back sucsess, >> however > I >> think I am on the right track now >> thanks to your assistance. >> >> regards, >> >> Paul Solomon >> >> >> "Bhaskar Thiagarajan" <bhaskart@deja.com> wrote in message >> news:428a1b87$0$79456$14726298@news.sunsite.dk... >> > "Tim Wescott" <tim@seemywebsite.com> wrote in message >> > news:118jvijkhj28t22@corp.supernews.com... >> >> Paul Solomon wrote: >> >> >> >> > Hi All, >> >> > >> >> > I am working on a project in which we are attempting to demod > multiple >> >> > (analog) FM radio stations in a FPGA. >> >> > I have been trying to work out how to design the CIC / FIR filter > pair >> > in >> >> > the DDC section of this design. >> >> >> >> This paragraph has put me into abbreviation overload. FM, FPGA and >> >> FIR >> >> all make sense to me -- what do CIC and DDC mean in this context? >> > >> > CIC - Cascaded Integrated Comb >> > DDC - Digital Down Converter >> > >> > >> >> > I have a input sampling rate of 80MSPS, which undersamples a clean >> > spectrum >> >> > of 88 - 108MHz i.e. the FM band. >> >> > this should give me the FM band at 8 - 28MHz with an alias at 52 - >> > 72MHz. >> >> > >> >> > I then take this input and mix with a NCO generated carrier at say >> > 20.5MHz >> >> > to try to pull out one of the stations. >> >> > The output of the mixer needs to then be filtered to approx 200kHz >> > bandwidth >> >> > and decimated to maybe 800kSPS? >> >> >> >> Is it quadrature demodulation? If so 200kHz is strictly correct only > if >> >> you mean -100kHz to 100kHz. You could go out more than that if you >> >> wanted to, but why? >> >> > >> >> > this is the part I am unsure of how to do.. I believe that I will > need >> >> > a >> > CIC >> >> > followed by a FIR however >> >> > I am not sure the relevant paramaters of the CIC and how to set >> >> > them, >> >> > i.e. (decimation Rate) R = 128, but (stages)N = ?? and (differential >> > delay)M >> >> > = ??. >> >> >> >> Apparantly a CIC is some sort of a polyphase filter with decimation? > If >> >> so, why do you need a FIR filter at all? In fact if you were clever > you >> >> should be able to follow the quadrature demodulation with a >> >> single-step >> >> lowpass/decimation filter to get a nicely conditioned baseband signal >> >> that you would then have to work on to extract the FM signal. >> > >> > A CIC is a box-car filter that (just google for lotsa references and > very >> > detailed explanations - Rick just had one of his artciles on this very >> > topic >> > in EE times I think) doesn't use any multipliers, supports large >> > decimation >> > ratios, works well in fixed point arithmentic. So these are excellent >> > candiates for 'coarse' decimation blocks that need to be implemented in >> > FPGAs. Since they are box-car to begin with, their frequency response >> > is >> > pretty bad - so they are typically followed by a FIR filter that does > any >> > 'fine' decimation that may be needed as well as correct for the > amplitude >> > droop in the pass-band caused by the CICs. >> > >> > Given Paul's system requirements, I would think that a single FIR >> > (non-CIC) >> > to get him from 80 Msps to 800ksps in one step wouldn't be easy. So he > is >> > correct in considering CICs in his design. >> > >> > Here is Rick's article for reference - Paul would be wise to read it >> > before >> > moving forward. >> > http://www.embedded.com/showArticle.jhtml?articleID=160400592 >> > >> > Paul - it seems you are shooting for a decimation of about 100. I'd >> > suggest >> > a CIC decimation of say 64 and the rest can be handled by your final > FIR. >> > Rick's article discusses the trade-offs related to stages and > differential >> > delay choices for these filters. If you still aren't sure of what you >> > need, >> > ask again (with some background on what you don't get). >> > >> > Since the CIC filters' frequency response is known exactly, you can >> > then >> > create an 'inverse' of this response in the frequency domain and then >> > perform an IFFT to get filter coeffs for your FIR filter that can > correct >> > for the CIC. >> > Note that you probably want a combination FIR - one that will correct > the >> > CIC as well as provide filtering to remove images and good stop band >> > attenuation for the spectrum of interest. So you'd need to combine the >> > 2 >> > responses together to get your filter coeffs. >> > >> > Cheers >> > Bhaskar >> > >> >> > >> >> > I have read Hogenauer and still feel none the wiser.. >> >> > >> >> > also once the filter parameters are decided, how do you design the >> > following >> >> > FIR filter to straighten up the passband?? >> >> > >> >> > Anyhow, Hopefully someone out there will be able to help. >> >> > >> >> > Cheers, >> >> > >> >> > Paul Solomon >> >> > >> >> > >> >> >> >> >> >> -- >> >> ------------------------------------------- >> >> Tim Wescott >> >> Wescott Design Services >> >> http://www.wescottdesign.com >> > >> > >> >> > >
Please bottom post.

Paul Solomon wrote:

> Hi Guys, > > Ok, I managed to get the simulation done that I was happy with in Matlab and > designed a conpensating > FIR filter and it all looks good in matlab.. I have not started moving this > stuff to verilog for the FPGA > and I have had a bit of trouble (probably as my verilog is rusty more than > anything else) > > I wil post my verilog code here in case there are and verilog guru's > watching that may see what is wrong > instantly otherwise I will just keep plugging at it tonnorow. I have a > feelig that it may be a signed integer issue > i.e. something to do with casting from a 32 bit to a 54 bit not filling in > the trailing ones in the case of the negative input. > > Anyhow, when I run this on the hardware I just get an awful lot of noise in > the spectrum instead of a nice signal > which is what I have before filtering. > > The CIC filter I am trying to implement here is a 4 stage M = 1, filter with > a decimation rate of 64. > > A 21 tap FIR filter seems to nicely clean up the passband if I put it > afterwards. > > I do have one big question weighing in my mind though, and that is how do > you deal with the bit widths that > are constantly growing. i.e., I only have 12 bit ADC input, however after > the multiply with the NCO I am up to 30 bits > then after the CIC I grow to 54 bits.. And after FIR it gets worse etc... > At the moment I have just taken the 14 MSB's to feed to my DAC (which is how > I am testing the output to see if it is ok) > However, I am not sure that this is the best method of doing this.. > > Any Ideas on how to keep the bit widths down to a manageable size? > > Regards > > Paul Solomon > > module cic_filter(clk, in, clk_out, out); > > input clk; > > input [29:0] in; > > output clk_out; > > output [31:0] out; > > reg state; // 0 = hold, 1 = sample > > reg [5:0] count; > > > reg [31:0] x; > > > reg [53:0] int1; > > reg [53:0] int2; > > reg [53:0] int3; > > reg [53:0] int4; > > reg [53:0] int_out; > > reg [53:0] comb1; > > reg [53:0] comb2; > > reg [53:0] comb3; > > reg [53:0] comb4; > > reg [53:0] combd1; > > reg [53:0] combd2; > > reg [53:0] combd3; > > reg [53:0] combd4; > > reg clk2; > > > always @(negedge clk) begin > > if (~state) begin > > if (count < 63) begin > > state <= 1'b0; > > end else begin > > state <= 1'b1; > > end > > end else begin > > state <= 1'b0; > > end > > end > > > always @(posedge clk) begin > > x <= in; > > int1 <= int1 + x; > > int2 <= int2 + int1; > > int3 <= int3 + int2; > > int4 <= int4 + int3; > > if (state) begin > > count <= 6'b0; > > int_out <= int4; > > end else begin > > count <= count + 1; > > end > > > if ((count > 16) && (count < 32)) begin > > clk2 <= 1'b1; > > end else begin > > clk2 <= 1'b0; > > end > > end > > always @(posedge clk2) begin > > combd1 <= int_out; > > comb1 <= int_out - combd1; > > combd2 <= comb1; > > comb2 <= comb1 - combd2; > > combd3 <= comb2; > > comb3 <= comb2 - combd3; > > combd4 <= comb3; > > comb4 <= comb3 - combd4; > > end > > assign clk_out = clk2; > > assign out = comb4[53:22]; > > endmodule >
Bit Widths: To keep bit widths to a manageable size you need to asses the number of "good" bits and keep those, while throwing away the dross. The number of bits can be a flexible quantity, depending on what you're trying to do. To really do it up right you draw up a block diagram of your system with noise injected anywhere you are planning to quantize. Then you find the transfer function from each quantization point to the output, and you find your sensitivity to noise vs. frequency at the output and ask "if the quantization noise were at the worst possible frequency it could be, would my output noise be higher than I could stand?". If the answer is yes, then you're quantizing too much. Various rules of thumb descend from this. If you're just keeping 14 bits, and you're doing it all with FIR filters, and you're not hacking bits off the top then you can probably just carry 16-20 bit intermediate values and be OK. This figure can vary however; I could certainly concieve of a control system with a 12-bit input that would require a 32-bit integrator and last-bit-dithering on the output to maintain DC accuracy. Verilog code: I don't see anything glaring, so I'll comment on your style instead. All the proffesional Verilog people I know would beat me up for clocking with clk2: they would want me to just gate the assignments instead. You _do_ have spaces and tabs availible, please indent for readability! If it were my code or I were adopting it I'd simulate it with a stimulus that exactly matches one that I could run through the Matlab simulation, and I'd compare the signals clock-by-clock with the Matlab results. This will, at least, tell you where your verilog code starts to diverge from your Matlab code. ------------------------------------------- Tim Wescott Wescott Design Services http://www.wescottdesign.com
"Paul Solomon" <psolomon@tpg.com.au> wrote in message
news:428c9536@dnews.tpgi.com.au...
> Hi Guys, > > Ok, I managed to get the simulation done that I was happy with in Matlab
and
> designed a conpensating > FIR filter and it all looks good in matlab.. I have not started moving
this
> stuff to verilog for the FPGA > and I have had a bit of trouble (probably as my verilog is rusty more than > anything else) > > I wil post my verilog code here in case there are and verilog guru's > watching that may see what is wrong
Cross-posting to comp.arch.fpga might get you more responses/help. Our resident expert on this (Ray) is off writing a book and acting busy in general...perhaps there are others.
> instantly otherwise I will just keep plugging at it tonnorow. I have a > feelig that it may be a signed integer issue > i.e. something to do with casting from a 32 bit to a 54 bit not filling in > the trailing ones in the case of the negative input. > > Anyhow, when I run this on the hardware I just get an awful lot of noise
in
> the spectrum instead of a nice signal > which is what I have before filtering.
Have you tried simplifying your design (say fewer filters with fewer stages for debugging) and tapping off your signal at various points to see where things go bad?
> The CIC filter I am trying to implement here is a 4 stage M = 1, filter
with
> a decimation rate of 64. > > A 21 tap FIR filter seems to nicely clean up the passband if I put it > afterwards. > > I do have one big question weighing in my mind though, and that is how do > you deal with the bit widths that > are constantly growing. i.e., I only have 12 bit ADC input, however after > the multiply with the NCO I am up to 30 bits
Why? While it is nice to maintain all the precision if you can, the SNR of your input signal is only going to be so much. Filtering and decimation is going to lower your noise floor but I don't see 30 bits needed (that's approx 180dB of dynamic range!)
> then after the CIC I grow to 54 bits.. And after FIR it gets worse etc...
The CIC accumulator needs to be large for it to work right but the output can be rounded to your output precision.
> At the moment I have just taken the 14 MSB's to feed to my DAC (which is
how
> I am testing the output to see if it is ok) > However, I am not sure that this is the best method of doing this..
> Any Ideas on how to keep the bit widths down to a manageable size? > > Regards > > Paul Solomon > > module cic_filter(clk, in, clk_out, out); > > input clk; > > input [29:0] in; > > output clk_out; > > output [31:0] out; > > reg state; // 0 = hold, 1 = sample > > reg [5:0] count; > > > reg [31:0] x; > > > reg [53:0] int1; > > reg [53:0] int2; > > reg [53:0] int3; > > reg [53:0] int4; > > reg [53:0] int_out; > > reg [53:0] comb1; > > reg [53:0] comb2; > > reg [53:0] comb3; > > reg [53:0] comb4; > > reg [53:0] combd1; > > reg [53:0] combd2; > > reg [53:0] combd3; > > reg [53:0] combd4; > > reg clk2; > > > always @(negedge clk) begin > > if (~state) begin > > if (count < 63) begin > > state <= 1'b0; > > end else begin > > state <= 1'b1; > > end > > end else begin > > state <= 1'b0; > > end > > end > > > always @(posedge clk) begin > > x <= in; > > int1 <= int1 + x; > > int2 <= int2 + int1; > > int3 <= int3 + int2; > > int4 <= int4 + int3; > > if (state) begin > > count <= 6'b0; > > int_out <= int4; > > end else begin > > count <= count + 1; > > end > > > if ((count > 16) && (count < 32)) begin > > clk2 <= 1'b1; > > end else begin > > clk2 <= 1'b0; > > end > > end > > always @(posedge clk2) begin > > combd1 <= int_out; > > comb1 <= int_out - combd1; > > combd2 <= comb1; > > comb2 <= comb1 - combd2; > > combd3 <= comb2; > > comb3 <= comb2 - combd3; > > combd4 <= comb3; > > comb4 <= comb3 - combd4; > > end > > assign clk_out = clk2; > > assign out = comb4[53:22]; > > endmodule > > > "Bhaskar Thiagarajan" <bhaskart@deja.com> wrote in message > news:428b7038$0$79458$14726298@news.sunsite.dk... > > "Paul Solomon" <psolomon@tpg.com.au> wrote in message > > news:428add1a@dnews.tpgi.com.au... > >> Hi Bhaskar, > >> > >> thanks for this info, it has helped alot, and that article nicely > > explained > >> the finer details of > >> CIC that I was confused about. > >> > >> I am trying to do the design in matlab and am currently stalled as I do > > not > >> have the fixed point toolbox > >> that the filter design toolbox wants to do CIC filters.. I think that I > > have > >> now made a correct FIR correction > >> filter but it would be nice to be able to cascade this with a CIC
filter
> >> inmatlab and see the cumulative response. > > > > While a CIC filter is typically modeled (and implemented) in fixed
point,
> > I > > don't think you absolutely need the fixed point toolbox to do what you > > want. > > Either you can implement the fixed precision manually in your matlab
code
> > or > > go ahead and use double precision arithmetic to model it for now. What
is
> > of > > importance here is that you model the frequency response of the CIC > > correctly (since that is what you are trying to study)..esp to see if
your
> > FIR correction is doing it's job. The frequency response of the CIC is > > quite > > well defined (see references). So you should be able to stick that your > > current simulation and see what happens. (Yes, I know that it would > > certainly be a lot more convenient to take a canned solution from > > Mathworks > > and get this to happen but I can guarantee that you'll learn more this
way
> > and save a bunch of cash) > > > > Cheers > > Bhaskar > > > > Note - A CIC implementation takes advantage of fixed precision
arithmetic
> > to > > work right - so I suggest you *model* your CIC rather than implement it
in
> > matlab for your simulation. > > > > > >> So I think it will be a few days before I can report back sucsess, > >> however > > I > >> think I am on the right track now > >> thanks to your assistance. > >> > >> regards, > >> > >> Paul Solomon > >> > >> > >> "Bhaskar Thiagarajan" <bhaskart@deja.com> wrote in message > >> news:428a1b87$0$79456$14726298@news.sunsite.dk... > >> > "Tim Wescott" <tim@seemywebsite.com> wrote in message > >> > news:118jvijkhj28t22@corp.supernews.com... > >> >> Paul Solomon wrote: > >> >> > >> >> > Hi All, > >> >> > > >> >> > I am working on a project in which we are attempting to demod > > multiple > >> >> > (analog) FM radio stations in a FPGA. > >> >> > I have been trying to work out how to design the CIC / FIR filter > > pair > >> > in > >> >> > the DDC section of this design. > >> >> > >> >> This paragraph has put me into abbreviation overload. FM, FPGA and > >> >> FIR > >> >> all make sense to me -- what do CIC and DDC mean in this context? > >> > > >> > CIC - Cascaded Integrated Comb > >> > DDC - Digital Down Converter > >> > > >> > > >> >> > I have a input sampling rate of 80MSPS, which undersamples a clean > >> > spectrum > >> >> > of 88 - 108MHz i.e. the FM band. > >> >> > this should give me the FM band at 8 - 28MHz with an alias at 52 - > >> > 72MHz. > >> >> > > >> >> > I then take this input and mix with a NCO generated carrier at say > >> > 20.5MHz > >> >> > to try to pull out one of the stations. > >> >> > The output of the mixer needs to then be filtered to approx 200kHz > >> > bandwidth > >> >> > and decimated to maybe 800kSPS? > >> >> > >> >> Is it quadrature demodulation? If so 200kHz is strictly correct
only
> > if > >> >> you mean -100kHz to 100kHz. You could go out more than that if you > >> >> wanted to, but why? > >> >> > > >> >> > this is the part I am unsure of how to do.. I believe that I will > > need > >> >> > a > >> > CIC > >> >> > followed by a FIR however > >> >> > I am not sure the relevant paramaters of the CIC and how to set > >> >> > them, > >> >> > i.e. (decimation Rate) R = 128, but (stages)N = ?? and
(differential
> >> > delay)M > >> >> > = ??. > >> >> > >> >> Apparantly a CIC is some sort of a polyphase filter with decimation? > > If > >> >> so, why do you need a FIR filter at all? In fact if you were clever > > you > >> >> should be able to follow the quadrature demodulation with a > >> >> single-step > >> >> lowpass/decimation filter to get a nicely conditioned baseband
signal
> >> >> that you would then have to work on to extract the FM signal. > >> > > >> > A CIC is a box-car filter that (just google for lotsa references and > > very > >> > detailed explanations - Rick just had one of his artciles on this
very
> >> > topic > >> > in EE times I think) doesn't use any multipliers, supports large > >> > decimation > >> > ratios, works well in fixed point arithmentic. So these are excellent > >> > candiates for 'coarse' decimation blocks that need to be implemented
in
> >> > FPGAs. Since they are box-car to begin with, their frequency response > >> > is > >> > pretty bad - so they are typically followed by a FIR filter that does > > any > >> > 'fine' decimation that may be needed as well as correct for the > > amplitude > >> > droop in the pass-band caused by the CICs. > >> > > >> > Given Paul's system requirements, I would think that a single FIR > >> > (non-CIC) > >> > to get him from 80 Msps to 800ksps in one step wouldn't be easy. So
he
> > is > >> > correct in considering CICs in his design. > >> > > >> > Here is Rick's article for reference - Paul would be wise to read it > >> > before > >> > moving forward. > >> > http://www.embedded.com/showArticle.jhtml?articleID=160400592 > >> > > >> > Paul - it seems you are shooting for a decimation of about 100. I'd > >> > suggest > >> > a CIC decimation of say 64 and the rest can be handled by your final > > FIR. > >> > Rick's article discusses the trade-offs related to stages and > > differential > >> > delay choices for these filters. If you still aren't sure of what you > >> > need, > >> > ask again (with some background on what you don't get). > >> > > >> > Since the CIC filters' frequency response is known exactly, you can > >> > then > >> > create an 'inverse' of this response in the frequency domain and then > >> > perform an IFFT to get filter coeffs for your FIR filter that can > > correct > >> > for the CIC. > >> > Note that you probably want a combination FIR - one that will correct > > the > >> > CIC as well as provide filtering to remove images and good stop band > >> > attenuation for the spectrum of interest. So you'd need to combine
the
> >> > 2 > >> > responses together to get your filter coeffs. > >> > > >> > Cheers > >> > Bhaskar > >> > > >> >> > > >> >> > I have read Hogenauer and still feel none the wiser.. > >> >> > > >> >> > also once the filter parameters are decided, how do you design the > >> > following > >> >> > FIR filter to straighten up the passband?? > >> >> > > >> >> > Anyhow, Hopefully someone out there will be able to help. > >> >> > > >> >> > Cheers, > >> >> > > >> >> > Paul Solomon > >> >> > > >> >> > > >> >> > >> >> > >> >> -- > >> >> ------------------------------------------- > >> >> Tim Wescott > >> >> Wescott Design Services > >> >> http://www.wescottdesign.com > >> > > >> > > >> > >> > > > > > >
"Paul Solomon" <psolomon@tpg.com.au> writes:

> Hi Guys, > > Ok, I managed to get the simulation done that I was happy with in Matlab and > designed a conpensating > FIR filter and it all looks good in matlab.. I have not started moving this > stuff to verilog for the FPGA > and I have had a bit of trouble (probably as my verilog is rusty more than > anything else) > ... > The CIC filter I am trying to implement here is a 4 stage M = 1, filter with > a decimation rate of 64.
Hi Paul, If you get a trial of Filter Design Toolbox and Filter Design HDL Coder, you could just do the following in MATLAB: Hx = mfilt.cicdecim(64,1,4) Hx.inputWordLength = 30; Hx.inputFracLength = 0; Hx.outputWordLength = 32; generatehdl(Hx,'targetlanguage','verilog'); Notes: Adding input and output registers is the default for generatehdl, but these registers are optional. CIC bit widths were chosen automatically and are shown in the comments in the Verilog file below; the binary points are notational and do not change the algorithm until the quantizer at the output of the filter where based on your 32-bit output, one bit is truncated (it can optionally be rounded in various ways). The single clock mode shown below is the default, but a two-clock interface can be generated as well. You can add your inverse sinc FIR filter and cascade it with the CIC and generate Verilog for both. You can also automatically generate a Verilog testbench to verify that the generated Verilog filter is working correcly. I hope this helps! Here is the Verilog: // ------------------------------------------------------------- // // Module: Hx // // Generated by MATLAB(R) 7.1 and the Filter Design HDL Coder 1.3. // // Generated on: 2005-05-20 13:34:06 // // ------------------------------------------------------------- // ------------------------------------------------------------- // HDL Code Generation Options: // // TargetLanguage: Verilog // Name: Hx // CastBeforeSum: On // // Filter Settings: // // Discrete-Time FIR Multirate Filter (real) // ----------------------------------------- // Filter Structure : Cascaded Integrator-Comb Decimator // Decimation Factor : 64 // Differential Delay : 1 // Number of Sections : 4 // Stable : Yes // Linear Phase : Yes (Type 1) // // Input : s30,0 // Output : s32,-21 // Filter Internals : Minimum Word Lengths // Integrator Section 1 : s53,0 // Integrator Section 2 : s48,-5 // Integrator Section 3 : s43,-10 // Integrator Section 4 : s38,-15 // Comb Section 1 : s36,-17 // Comb Section 2 : s35,-18 // Comb Section 3 : s34,-19 // Comb Section 4 : s33,-20 // ------------------------------------------------------------- `timescale 1 ns / 1 ns module Hx ( clk, clk_enable, reset, filter_in, filter_out, ce_out ); input clk; input clk_enable; input reset; input signed [29:0] filter_in; //sfix30 output signed [31:0] filter_out; //sfix32_E21 output ce_out; //////////////////////////////////////////////////////////////// //Module Architecture: Hx //////////////////////////////////////////////////////////////// // Local Functions // Type Definitions // Constants // Signals reg [5:0] cur_count; // ufix6 wire current_count; // boolean reg ce_out_reg; // boolean // reg signed [29:0] input_register; // sfix30 // -- Section 1 Signals wire signed [29:0] section_in1; // sfix30 wire signed [52:0] section_cast1; // sfix53 wire signed [52:0] sum1; // sfix53 reg signed [52:0] section_out1; // sfix53 wire signed [52:0] add_cast; // sfix53 wire signed [52:0] add_cast_1; // sfix53 wire signed [53:0] add_temp; // sfix54 // -- Section 2 Signals wire signed [52:0] section_in2; // sfix53 wire signed [47:0] section_cast2; // sfix48_E5 wire signed [47:0] sum2; // sfix48_E5 reg signed [47:0] section_out2; // sfix48_E5 wire signed [47:0] add_cast_2; // sfix48_E5 wire signed [47:0] add_cast_3; // sfix48_E5 wire signed [48:0] add_temp_1; // sfix49_E5 // -- Section 3 Signals wire signed [47:0] section_in3; // sfix48_E5 wire signed [42:0] section_cast3; // sfix43_E10 wire signed [42:0] sum3; // sfix43_E10 reg signed [42:0] section_out3; // sfix43_E10 wire signed [42:0] add_cast_4; // sfix43_E10 wire signed [42:0] add_cast_5; // sfix43_E10 wire signed [43:0] add_temp_2; // sfix44_E10 // -- Section 4 Signals wire signed [42:0] section_in4; // sfix43_E10 wire signed [37:0] section_cast4; // sfix38_E15 wire signed [37:0] sum4; // sfix38_E15 reg signed [37:0] section_out4; // sfix38_E15 wire signed [37:0] add_cast_6; // sfix38_E15 wire signed [37:0] add_cast_7; // sfix38_E15 wire signed [38:0] add_temp_3; // sfix39_E15 // -- Section 5 Signals wire signed [37:0] section_in5; // sfix38_E15 wire signed [35:0] section_cast5; // sfix36_E17 reg signed [35:0] diff1; // sfix36_E17 wire signed [35:0] section_out5; // sfix36_E17 wire signed [35:0] sub_cast; // sfix36_E17 wire signed [35:0] sub_cast_1; // sfix36_E17 wire signed [36:0] sub_temp; // sfix37_E17 // -- Section 6 Signals wire signed [35:0] section_in6; // sfix36_E17 wire signed [34:0] section_cast6; // sfix35_E18 reg signed [34:0] diff2; // sfix35_E18 wire signed [34:0] section_out6; // sfix35_E18 wire signed [34:0] sub_cast_2; // sfix35_E18 wire signed [34:0] sub_cast_3; // sfix35_E18 wire signed [35:0] sub_temp_1; // sfix36_E18 // -- Section 7 Signals wire signed [34:0] section_in7; // sfix35_E18 wire signed [33:0] section_cast7; // sfix34_E19 reg signed [33:0] diff3; // sfix34_E19 wire signed [33:0] section_out7; // sfix34_E19 wire signed [33:0] sub_cast_4; // sfix34_E19 wire signed [33:0] sub_cast_5; // sfix34_E19 wire signed [34:0] sub_temp_2; // sfix35_E19 // -- Section 8 Signals wire signed [33:0] section_in8; // sfix34_E19 wire signed [32:0] section_cast8; // sfix33_E20 reg signed [32:0] diff4; // sfix33_E20 wire signed [32:0] section_out8; // sfix33_E20 wire signed [32:0] sub_cast_6; // sfix33_E20 wire signed [32:0] sub_cast_7; // sfix33_E20 wire signed [33:0] sub_temp_3; // sfix34_E20 wire signed [31:0] output_typeconvert; // sfix32_E21 // reg signed [31:0] output_register; // sfix32_E21 // Block Statements // ------------------ CE Output Generation ------------------ always @ (posedge clk or posedge reset) begin: ce_output if (reset == 1'b1) begin cur_count <= 0; end else begin if (clk_enable == 1'b1) begin if (cur_count == 63) begin cur_count <= 0; end else begin cur_count <= cur_count + 1; end end end end // ce_output assign current_count = (cur_count == 1 && clk_enable == 1'b1)? 1 : 0; // ------------------ CE Output Register ------------------ always @ (posedge clk or posedge reset) begin: ce_output_register if (reset == 1'b1) begin ce_out_reg <= 1'b0; end else begin ce_out_reg <= current_count; end end // ce_output_register // ------------------ Input Register ------------------ always @ (posedge clk or posedge reset) begin: input_reg_process if (reset == 1'b1) begin input_register <= 0; end else begin if (clk_enable == 1'b1) begin input_register <= filter_in; end end end // input_reg_process // ------------------ Section # 1 : Integrator ------------------ assign section_in1 = input_register; assign section_cast1 = $signed({{23{section_in1[29]}}, section_in1}); assign add_cast = section_cast1; assign add_cast_1 = section_out1; assign add_temp = add_cast + add_cast_1; assign sum1 = add_temp[52:0]; always @ (posedge clk or posedge reset) begin: integrator_delay_section1 if (reset == 1'b1) begin section_out1 <= 0; end else begin if (clk_enable == 1'b1) begin section_out1 <= sum1; end end end // integrator_delay_section1 // ------------------ Section # 2 : Integrator ------------------ assign section_in2 = section_out1; assign section_cast2 = section_in2[52:5]; assign add_cast_2 = section_cast2; assign add_cast_3 = section_out2; assign add_temp_1 = add_cast_2 + add_cast_3; assign sum2 = add_temp_1[47:0]; always @ (posedge clk or posedge reset) begin: integrator_delay_section2 if (reset == 1'b1) begin section_out2 <= 0; end else begin if (clk_enable == 1'b1) begin section_out2 <= sum2; end end end // integrator_delay_section2 // ------------------ Section # 3 : Integrator ------------------ assign section_in3 = section_out2; assign section_cast3 = section_in3[47:5]; assign add_cast_4 = section_cast3; assign add_cast_5 = section_out3; assign add_temp_2 = add_cast_4 + add_cast_5; assign sum3 = add_temp_2[42:0]; always @ (posedge clk or posedge reset) begin: integrator_delay_section3 if (reset == 1'b1) begin section_out3 <= 0; end else begin if (clk_enable == 1'b1) begin section_out3 <= sum3; end end end // integrator_delay_section3 // ------------------ Section # 4 : Integrator ------------------ assign section_in4 = section_out3; assign section_cast4 = section_in4[42:5]; assign add_cast_6 = section_cast4; assign add_cast_7 = section_out4; assign add_temp_3 = add_cast_6 + add_cast_7; assign sum4 = add_temp_3[37:0]; always @ (posedge clk or posedge reset) begin: integrator_delay_section4 if (reset == 1'b1) begin section_out4 <= 0; end else begin if (clk_enable == 1'b1) begin section_out4 <= sum4; end end end // integrator_delay_section4 // ------------------ Section # 5 : Comb ------------------ assign section_in5 = section_out4; assign section_cast5 = section_in5[37:2]; assign sub_cast = section_cast5; assign sub_cast_1 = diff1; assign sub_temp = sub_cast - sub_cast_1; assign section_out5 = sub_temp[35:0]; always @ (posedge clk or posedge reset) begin: comb_delay_section5 if (reset == 1'b1) begin diff1 <= 0; end else begin if (current_count == 1'b1) begin diff1 <= section_cast5; end end end // comb_delay_section5 // ------------------ Section # 6 : Comb ------------------ assign section_in6 = section_out5; assign section_cast6 = section_in6[35:1]; assign sub_cast_2 = section_cast6; assign sub_cast_3 = diff2; assign sub_temp_1 = sub_cast_2 - sub_cast_3; assign section_out6 = sub_temp_1[34:0]; always @ (posedge clk or posedge reset) begin: comb_delay_section6 if (reset == 1'b1) begin diff2 <= 0; end else begin if (current_count == 1'b1) begin diff2 <= section_cast6; end end end // comb_delay_section6 // ------------------ Section # 7 : Comb ------------------ assign section_in7 = section_out6; assign section_cast7 = section_in7[34:1]; assign sub_cast_4 = section_cast7; assign sub_cast_5 = diff3; assign sub_temp_2 = sub_cast_4 - sub_cast_5; assign section_out7 = sub_temp_2[33:0]; always @ (posedge clk or posedge reset) begin: comb_delay_section7 if (reset == 1'b1) begin diff3 <= 0; end else begin if (current_count == 1'b1) begin diff3 <= section_cast7; end end end // comb_delay_section7 // ------------------ Section # 8 : Comb ------------------ assign section_in8 = section_out7; assign section_cast8 = section_in8[33:1]; assign sub_cast_6 = section_cast8; assign sub_cast_7 = diff4; assign sub_temp_3 = sub_cast_6 - sub_cast_7; assign section_out8 = sub_temp_3[32:0]; always @ (posedge clk or posedge reset) begin: comb_delay_section8 if (reset == 1'b1) begin diff4 <= 0; end else begin if (current_count == 1'b1) begin diff4 <= section_cast8; end end end // comb_delay_section8 assign output_typeconvert = section_out8[32:1]; // ------------------ Output Register ------------------ always @ (posedge clk or posedge reset) begin: output_reg_process if (reset == 1'b1) begin output_register <= 0; end else begin if (current_count == 1'b1) begin output_register <= output_typeconvert; end end end // output_reg_process // Assignment Statements assign ce_out = ce_out_reg; assign filter_out = output_register; endmodule // Hx